Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/refactor state #17

Merged
merged 2 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
265 changes: 143 additions & 122 deletions dist/kasper.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/kasper.min.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions live/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
}

class MyTodoApp extends KasperApp {
posts = this.$state([]);
user = this.$state(null);
post = this.$state(null);
posts = $state([]);
user = $state(null);
post = $state(null);

$onInit = async () => {
const posts = await fetchPosts();
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
"author": "eugenioenko",
"license": "MIT",
"devDependencies": {
"@types/node": "^20.10.3",
"@types/node": "^20.12.7",
"jasmine": "^5.1.0",
"terser-webpack-plugin": "^5.3.9",
"ts-loader": "^9.5.1",
"tslint": "^6.1.3",
"typescript": "^5.3.2",
"webpack": "^5.89.0",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4"
}
}
26 changes: 26 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ExpressionParser } from "./expression-parser";
import { Interpreter } from "./interpreter";
import { execute, transpile, Kasper, KasperApp, kasperState } from "./kasper";
import { Scanner } from "./scanner";
import { TemplateParser } from "./template-parser";
import { Transpiler } from "./transpiler";
import { Viewer } from "./viewer";

if (typeof window !== "undefined") {
((window as any) || {}).kasper = {
execute,
transpile,
};
(window as any)["Kasper"] = Kasper;
(window as any)["KasperApp"] = KasperApp;
(window as any)["$state"] = kasperState;
} else if (typeof exports !== "undefined") {
exports.kasper = {
ExpressionParser,
Interpreter,
Scanner,
TemplateParser,
Transpiler,
Viewer,
};
}
106 changes: 60 additions & 46 deletions src/kasper.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { TemplateParser } from "./template-parser";
import { ExpressionParser } from "./expression-parser";
import { Interpreter } from "./interpreter";
import { Transpiler } from "./transpiler";
import { Viewer } from "./viewer";
import { Scanner } from "./scanner";
import { State } from "./state";

function execute(source: string): string {
export function execute(source: string): string {
const parser = new TemplateParser();
const nodes = parser.parse(source);
if (parser.errors.length) {
Expand All @@ -16,7 +11,7 @@ function execute(source: string): string {
return result;
}

function transpile(
export function transpile(
source: string,
entity?: { [key: string]: any },
container?: HTMLElement
Expand All @@ -28,7 +23,7 @@ function transpile(
return result;
}

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

export class KasperApp {
$state = (initial: any) => new State(initial, this);
$changes = 1;
$dirty = false;
$doRender = () => {
if (typeof this.$onChanges === "function") {
this.$onChanges();
$onInit = () => {};
$onRender = () => {};
$onChanges = () => {};
}

export class KasperRenderer {
entity?: KasperApp = undefined;
changes = 1;
dirty = false;

render = () => {
this.changes += 1;
if (!this.entity) {
// do not render if entity is not set
return;
}
if (typeof this.entity?.$onChanges === "function") {
this.entity.$onChanges();
}
if (this.$changes > 0 && !this.$dirty) {
this.$dirty = true;
if (this.changes > 0 && !this.dirty) {
this.dirty = true;
queueMicrotask(() => {
render(this);
// console.log(this.$changes);
if (typeof this.$onRender === "function") {
this.$onRender();
render(this.entity);
// console.log(this.changes);
if (typeof this.entity?.$onRender === "function") {
this.entity.$onRender();
}
this.$dirty = false;
this.$changes = 0;
this.dirty = false;
this.changes = 0;
});
}
};
$onInit = () => {};
$onRender = () => {};
$onChanges = () => {};
}

function Kasper(initializer: any) {
const entity = new initializer();
entity.$doRender();
if (typeof entity.$onInit === "function") {
entity.$onInit();
let renderer = new KasperRenderer();

export class KasperState {
_value: any;

constructor(initial: any) {
this._value = initial;
}

get value(): any {
return this._value;
}

set(value: any) {
this._value = value;
renderer.render();
}

toString() {
return this._value.toString();
}
}

if (typeof window !== "undefined") {
((window as any) || {}).kasper = {
execute,
transpile,
};
(window as any)["Kasper"] = Kasper;
(window as any)["KasperApp"] = KasperApp;
} else if (typeof exports !== "undefined") {
exports.kasper = {
ExpressionParser,
Interpreter,
Scanner,
TemplateParser,
Transpiler,
Viewer,
};
export function kasperState(initial: any): KasperState {
return new KasperState(initial);
}

export function Kasper(Component: any) {
const entity = new Component();
renderer.entity = entity;
renderer.render();
if (typeof entity.$onInit === "function") {
entity.$onInit();
}
}
26 changes: 0 additions & 26 deletions src/state.ts

This file was deleted.

2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require("path");

module.exports = {
entry: "./src/kasper.ts",
entry: "./src/index.ts",
devtool: "inline-source-map",
mode: "development",
watch: true,
Expand Down
5 changes: 4 additions & 1 deletion webpack.prod.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const path = require("path");

module.exports = {
entry: "./src/kasper.ts",
entry: "./src/index.ts",
mode: "production",
watch: false,
module: {
Expand All @@ -21,4 +21,7 @@ module.exports = {
path: path.resolve(__dirname, "dist"),
// libraryTarget: "window",
},
optimization: {
minimize: true,
},
};
Loading
Loading