Skip to content

Commit cc98f6a

Browse files
authored
Feat/refactor state (#17)
* chore: cleanup build * feat: refactor this.$state into $state function
1 parent ecfff9e commit cc98f6a

10 files changed

+367
-305
lines changed

dist/kasper.js

+143-122
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/kasper.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

live/demo.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@
8181
}
8282

8383
class MyTodoApp extends KasperApp {
84-
posts = this.$state([]);
85-
user = this.$state(null);
86-
post = this.$state(null);
84+
posts = $state([]);
85+
user = $state(null);
86+
post = $state(null);
8787

8888
$onInit = async () => {
8989
const posts = await fetchPosts();

package.json

+3-4
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@
1919
"author": "eugenioenko",
2020
"license": "MIT",
2121
"devDependencies": {
22-
"@types/node": "^20.10.3",
22+
"@types/node": "^20.12.7",
2323
"jasmine": "^5.1.0",
24-
"terser-webpack-plugin": "^5.3.9",
2524
"ts-loader": "^9.5.1",
2625
"tslint": "^6.1.3",
27-
"typescript": "^5.3.2",
28-
"webpack": "^5.89.0",
26+
"typescript": "^5.4.5",
27+
"webpack": "^5.91.0",
2928
"webpack-cli": "^5.1.4"
3029
}
3130
}

src/index.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { ExpressionParser } from "./expression-parser";
2+
import { Interpreter } from "./interpreter";
3+
import { execute, transpile, Kasper, KasperApp, kasperState } from "./kasper";
4+
import { Scanner } from "./scanner";
5+
import { TemplateParser } from "./template-parser";
6+
import { Transpiler } from "./transpiler";
7+
import { Viewer } from "./viewer";
8+
9+
if (typeof window !== "undefined") {
10+
((window as any) || {}).kasper = {
11+
execute,
12+
transpile,
13+
};
14+
(window as any)["Kasper"] = Kasper;
15+
(window as any)["KasperApp"] = KasperApp;
16+
(window as any)["$state"] = kasperState;
17+
} else if (typeof exports !== "undefined") {
18+
exports.kasper = {
19+
ExpressionParser,
20+
Interpreter,
21+
Scanner,
22+
TemplateParser,
23+
Transpiler,
24+
Viewer,
25+
};
26+
}

src/kasper.ts

+60-46
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import { TemplateParser } from "./template-parser";
2-
import { ExpressionParser } from "./expression-parser";
3-
import { Interpreter } from "./interpreter";
42
import { Transpiler } from "./transpiler";
5-
import { Viewer } from "./viewer";
6-
import { Scanner } from "./scanner";
7-
import { State } from "./state";
83

9-
function execute(source: string): string {
4+
export function execute(source: string): string {
105
const parser = new TemplateParser();
116
const nodes = parser.parse(source);
127
if (parser.errors.length) {
@@ -16,7 +11,7 @@ function execute(source: string): string {
1611
return result;
1712
}
1813

19-
function transpile(
14+
export function transpile(
2015
source: string,
2116
entity?: { [key: string]: any },
2217
container?: HTMLElement
@@ -28,7 +23,7 @@ function transpile(
2823
return result;
2924
}
3025

31-
function render(entity: any): void {
26+
export function render(entity: any): void {
3227
if (typeof window === "undefined") {
3328
console.error("kasper requires a browser environment to render templates.");
3429
return;
@@ -48,53 +43,72 @@ function render(entity: any): void {
4843
}
4944

5045
export class KasperApp {
51-
$state = (initial: any) => new State(initial, this);
52-
$changes = 1;
53-
$dirty = false;
54-
$doRender = () => {
55-
if (typeof this.$onChanges === "function") {
56-
this.$onChanges();
46+
$onInit = () => {};
47+
$onRender = () => {};
48+
$onChanges = () => {};
49+
}
50+
51+
export class KasperRenderer {
52+
entity?: KasperApp = undefined;
53+
changes = 1;
54+
dirty = false;
55+
56+
render = () => {
57+
this.changes += 1;
58+
if (!this.entity) {
59+
// do not render if entity is not set
60+
return;
61+
}
62+
if (typeof this.entity?.$onChanges === "function") {
63+
this.entity.$onChanges();
5764
}
58-
if (this.$changes > 0 && !this.$dirty) {
59-
this.$dirty = true;
65+
if (this.changes > 0 && !this.dirty) {
66+
this.dirty = true;
6067
queueMicrotask(() => {
61-
render(this);
62-
// console.log(this.$changes);
63-
if (typeof this.$onRender === "function") {
64-
this.$onRender();
68+
render(this.entity);
69+
// console.log(this.changes);
70+
if (typeof this.entity?.$onRender === "function") {
71+
this.entity.$onRender();
6572
}
66-
this.$dirty = false;
67-
this.$changes = 0;
73+
this.dirty = false;
74+
this.changes = 0;
6875
});
6976
}
7077
};
71-
$onInit = () => {};
72-
$onRender = () => {};
73-
$onChanges = () => {};
7478
}
7579

76-
function Kasper(initializer: any) {
77-
const entity = new initializer();
78-
entity.$doRender();
79-
if (typeof entity.$onInit === "function") {
80-
entity.$onInit();
80+
let renderer = new KasperRenderer();
81+
82+
export class KasperState {
83+
_value: any;
84+
85+
constructor(initial: any) {
86+
this._value = initial;
87+
}
88+
89+
get value(): any {
90+
return this._value;
91+
}
92+
93+
set(value: any) {
94+
this._value = value;
95+
renderer.render();
96+
}
97+
98+
toString() {
99+
return this._value.toString();
81100
}
82101
}
83102

84-
if (typeof window !== "undefined") {
85-
((window as any) || {}).kasper = {
86-
execute,
87-
transpile,
88-
};
89-
(window as any)["Kasper"] = Kasper;
90-
(window as any)["KasperApp"] = KasperApp;
91-
} else if (typeof exports !== "undefined") {
92-
exports.kasper = {
93-
ExpressionParser,
94-
Interpreter,
95-
Scanner,
96-
TemplateParser,
97-
Transpiler,
98-
Viewer,
99-
};
103+
export function kasperState(initial: any): KasperState {
104+
return new KasperState(initial);
105+
}
106+
107+
export function Kasper(Component: any) {
108+
const entity = new Component();
109+
renderer.entity = entity;
110+
renderer.render();
111+
if (typeof entity.$onInit === "function") {
112+
entity.$onInit();
113+
}
100114
}

src/state.ts

-26
This file was deleted.

webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require("path");
22

33
module.exports = {
4-
entry: "./src/kasper.ts",
4+
entry: "./src/index.ts",
55
devtool: "inline-source-map",
66
mode: "development",
77
watch: true,

webpack.prod.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require("path");
22

33
module.exports = {
4-
entry: "./src/kasper.ts",
4+
entry: "./src/index.ts",
55
mode: "production",
66
watch: false,
77
module: {
@@ -21,4 +21,7 @@ module.exports = {
2121
path: path.resolve(__dirname, "dist"),
2222
// libraryTarget: "window",
2323
},
24+
optimization: {
25+
minimize: true,
26+
},
2427
};

0 commit comments

Comments
 (0)