@praxisjs/runtime 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # @praxisjs/runtime
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - aaf7dab: Initial beta release
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [aaf7dab]
12
+ - @praxisjs/core@0.1.0
13
+ - @praxisjs/decorators@0.1.0
14
+ - @praxisjs/jsx@0.1.0
15
+ - @praxisjs/shared@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present Mateus Martins
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export { render } from "./renderer";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { render } from "./renderer";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { VNode } from "@praxisjs/shared";
2
+ export declare function render(vnode: VNode, container: HTMLElement): () => void;
3
+ //# sourceMappingURL=renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,KAAK,EAGN,MAAM,kBAAkB,CAAC;AAkc1B,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,cAY1D"}
@@ -0,0 +1,380 @@
1
+ import { effect, createFunctionalContext, setFunctionalContext, } from "@praxisjs/core";
2
+ import { initSlots } from "@praxisjs/decorators";
3
+ const EVENT_MAP = {
4
+ onClick: "click",
5
+ onDblClick: "dblclick",
6
+ onChange: "change",
7
+ onInput: "input",
8
+ onSubmit: "submit",
9
+ onReset: "reset",
10
+ onKeyDown: "keydown",
11
+ onKeyUp: "keyup",
12
+ onKeyPress: "keypress",
13
+ onFocus: "focus",
14
+ onBlur: "blur",
15
+ onMouseDown: "mousedown",
16
+ onMouseUp: "mouseup",
17
+ onMouseEnter: "mouseenter",
18
+ onMouseLeave: "mouseleave",
19
+ onMouseMove: "mousemove",
20
+ onContextMenu: "contextmenu",
21
+ onScroll: "scroll",
22
+ onWheel: "wheel",
23
+ onDragStart: "dragstart",
24
+ onDragEnd: "dragend",
25
+ onDragOver: "dragover",
26
+ onDrop: "drop",
27
+ onTouchStart: "touchstart",
28
+ onTouchEnd: "touchend",
29
+ onTouchMove: "touchmove",
30
+ onAnimationEnd: "animationend",
31
+ onTransitionEnd: "transitionend",
32
+ };
33
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
34
+ const SVG_TAGS = new Set([
35
+ "svg",
36
+ "path",
37
+ "circle",
38
+ "rect",
39
+ "line",
40
+ "polyline",
41
+ "polygon",
42
+ "ellipse",
43
+ "text",
44
+ "g",
45
+ "defs",
46
+ "use",
47
+ "symbol",
48
+ "marker",
49
+ "clipPath",
50
+ "mask",
51
+ "pattern",
52
+ "image",
53
+ "linearGradient",
54
+ "radialGradient",
55
+ "stop",
56
+ "filter",
57
+ "feGaussianBlur",
58
+ "tspan",
59
+ "textPath",
60
+ "foreignObject",
61
+ ]);
62
+ function applyProps(el, props, cleanups) {
63
+ for (const [key, value] of Object.entries(props)) {
64
+ if (key === "key" || key === "children")
65
+ continue;
66
+ if (key in EVENT_MAP) {
67
+ const eventName = EVENT_MAP[key];
68
+ const eventListener = value;
69
+ el.addEventListener(eventName, eventListener);
70
+ cleanups.push(() => {
71
+ el.removeEventListener(eventName, eventListener);
72
+ });
73
+ continue;
74
+ }
75
+ if (key === "ref" && typeof value === "function") {
76
+ value(el);
77
+ continue;
78
+ }
79
+ if (key === "className" || key === "class") {
80
+ if (typeof value === "function") {
81
+ cleanups.push(effect(() => {
82
+ el.setAttribute("class", String(value()));
83
+ }));
84
+ }
85
+ else {
86
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
87
+ el.setAttribute("class", String(value ?? ""));
88
+ }
89
+ continue;
90
+ }
91
+ if (key === "style") {
92
+ if (typeof value === "function") {
93
+ cleanups.push(effect(() => {
94
+ const styleValue = value();
95
+ if (typeof styleValue === "object" && styleValue !== null) {
96
+ el.removeAttribute("style");
97
+ Object.assign(el.style, styleValue);
98
+ }
99
+ else {
100
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
101
+ el.setAttribute("style", String(styleValue ?? ""));
102
+ }
103
+ }));
104
+ }
105
+ else if (typeof value === "object" && value !== null) {
106
+ el.removeAttribute("style");
107
+ Object.assign(el.style, value);
108
+ }
109
+ else {
110
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
111
+ el.setAttribute("style", String(value ?? ""));
112
+ }
113
+ continue;
114
+ }
115
+ if (["checked", "value", "disabled", "selected"].includes(key)) {
116
+ if (typeof value === "function") {
117
+ cleanups.push(effect(() => {
118
+ el[key] = value();
119
+ }));
120
+ }
121
+ else {
122
+ el[key] = value;
123
+ }
124
+ continue;
125
+ }
126
+ if (typeof value === "function") {
127
+ const attrKey = key === "htmlFor" ? "for" : key;
128
+ cleanups.push(effect(() => {
129
+ const attrValue = value();
130
+ if (attrValue === false ||
131
+ attrValue === null ||
132
+ attrValue === undefined) {
133
+ el.removeAttribute(attrKey);
134
+ }
135
+ else if (attrValue === true) {
136
+ el.setAttribute(attrKey, "");
137
+ }
138
+ else {
139
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
140
+ el.setAttribute(attrKey, String(attrValue));
141
+ }
142
+ }));
143
+ continue;
144
+ }
145
+ if (typeof value === "boolean") {
146
+ if (value) {
147
+ el.setAttribute(key, "");
148
+ }
149
+ else {
150
+ el.removeAttribute(key);
151
+ }
152
+ continue;
153
+ }
154
+ if (value !== null && value !== undefined) {
155
+ const attrKey = key === "htmlFor" ? "for" : key;
156
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
157
+ el.setAttribute(attrKey, String(value));
158
+ }
159
+ }
160
+ }
161
+ function renderChildren(children, cleanups) {
162
+ if (children === null || children === undefined || children === false) {
163
+ return [document.createComment("empty")];
164
+ }
165
+ if (typeof children === "string" || typeof children === "number") {
166
+ return [document.createTextNode(String(children))];
167
+ }
168
+ if (Array.isArray(children)) {
169
+ return children.flatMap((child) => renderChildren(child, cleanups));
170
+ }
171
+ if (typeof children === "function") {
172
+ const fn = children;
173
+ const anchor = document.createComment("reactive");
174
+ let currentNodes = [];
175
+ let childCleanups = [];
176
+ let initialized = false;
177
+ cleanups.push(effect(() => {
178
+ const result = fn();
179
+ if (!initialized) {
180
+ currentNodes = renderChildren(result, childCleanups);
181
+ initialized = true;
182
+ return;
183
+ }
184
+ childCleanups.forEach((c) => { c(); });
185
+ childCleanups = [];
186
+ const parent = anchor.parentNode;
187
+ if (!parent)
188
+ return;
189
+ for (const node of currentNodes) {
190
+ if (node.parentNode === parent) {
191
+ parent.removeChild(node);
192
+ }
193
+ }
194
+ const newNodes = renderChildren(result, childCleanups);
195
+ newNodes.forEach((node) => parent.insertBefore(node, anchor));
196
+ currentNodes = newNodes;
197
+ }));
198
+ cleanups.push(() => {
199
+ childCleanups.forEach((c) => { c(); });
200
+ });
201
+ return [...currentNodes, anchor];
202
+ }
203
+ if (typeof children === "object" && "type" in children) {
204
+ const mounted = mountVNode(children, document.createComment("object"), cleanups);
205
+ return [mounted.el];
206
+ }
207
+ return [document.createTextNode(String(children))];
208
+ }
209
+ function mountVNode(vnode, _parent, parentCleanups) {
210
+ const cleanups = [];
211
+ const { type, props, children } = vnode;
212
+ if (typeof type === "function" && "isComponent" in type) {
213
+ const instance = new type({
214
+ ...props,
215
+ });
216
+ if (children.length > 0) {
217
+ initSlots(instance, children);
218
+ }
219
+ instance.onBeforeMount?.();
220
+ const wrapper = document.createElement("div");
221
+ wrapper.setAttribute("data-component", type.name || "AnonymousComponent");
222
+ const isMemoized = instance._isMemorized;
223
+ cleanups.push(effect(() => {
224
+ if (instance._mounted)
225
+ return;
226
+ if (!isMemoized) {
227
+ const resolvedProps = {};
228
+ for (const [key, value] of Object.entries(props)) {
229
+ if (key === "children" || key === "key")
230
+ continue;
231
+ if (typeof value === "function") {
232
+ resolvedProps[key] = value();
233
+ }
234
+ else {
235
+ resolvedProps[key] = value;
236
+ }
237
+ }
238
+ if (!instance._stateDirty) {
239
+ const arePropsEqual = instance._arePropsEqual;
240
+ const lastProps = instance._lastResolvedProps;
241
+ if (lastProps !== undefined &&
242
+ arePropsEqual?.(lastProps, resolvedProps)) {
243
+ return;
244
+ }
245
+ }
246
+ instance._lastResolvedProps = resolvedProps;
247
+ }
248
+ instance._stateDirty = false;
249
+ instance._setProps({ ...props });
250
+ let rerenderedVNode = null;
251
+ try {
252
+ rerenderedVNode = instance.render();
253
+ }
254
+ catch (e) {
255
+ console.error("Error rendering component:", e);
256
+ const error = e instanceof Error ? e : new Error(String(e));
257
+ instance.onError?.(error);
258
+ }
259
+ wrapper.innerHTML = "";
260
+ if (rerenderedVNode) {
261
+ const childNode = mountVNode(rerenderedVNode, wrapper, cleanups);
262
+ wrapper.appendChild(childNode.el);
263
+ }
264
+ }));
265
+ parentCleanups.push(() => {
266
+ instance.onUnmount?.();
267
+ instance._mounted = false;
268
+ cleanups.forEach((fn) => {
269
+ fn();
270
+ });
271
+ });
272
+ queueMicrotask(() => {
273
+ instance.onMount?.();
274
+ instance._mounted = true;
275
+ });
276
+ return {
277
+ el: wrapper,
278
+ vnode,
279
+ instance,
280
+ cleanups,
281
+ children: [],
282
+ };
283
+ }
284
+ if (typeof type === "function") {
285
+ const resolvedType = type;
286
+ const ctx = createFunctionalContext();
287
+ setFunctionalContext(ctx);
288
+ let resolvedVNode = null;
289
+ try {
290
+ resolvedVNode = resolvedType({ ...props, children });
291
+ }
292
+ catch (e) {
293
+ const error = e instanceof Error ? e : new Error(String(e));
294
+ ctx.onError.forEach((fn) => {
295
+ fn(error);
296
+ });
297
+ }
298
+ setFunctionalContext(null);
299
+ ctx.onBeforeMount.forEach((fn) => {
300
+ fn();
301
+ });
302
+ if (!resolvedVNode) {
303
+ const commentNode = document.createComment(`<${type.name || "AnonymousComponent"} />`);
304
+ queueMicrotask(() => {
305
+ ctx.onMount.forEach((fn) => {
306
+ fn();
307
+ });
308
+ });
309
+ cleanups.push(() => {
310
+ ctx.onUnmount.forEach((fn) => {
311
+ fn();
312
+ });
313
+ });
314
+ parentCleanups.push(() => {
315
+ cleanups.forEach((fn) => {
316
+ fn();
317
+ });
318
+ });
319
+ return {
320
+ el: commentNode,
321
+ cleanups,
322
+ children: [],
323
+ };
324
+ }
325
+ const childNode = mountVNode(resolvedVNode, _parent, cleanups);
326
+ queueMicrotask(() => {
327
+ ctx.onMount.forEach((fn) => {
328
+ fn();
329
+ });
330
+ });
331
+ cleanups.push(() => {
332
+ ctx.onUnmount.forEach((fn) => {
333
+ fn();
334
+ });
335
+ });
336
+ parentCleanups.push(() => {
337
+ cleanups.forEach((fn) => {
338
+ fn();
339
+ });
340
+ });
341
+ return {
342
+ el: childNode.el,
343
+ vnode,
344
+ cleanups,
345
+ children: [],
346
+ };
347
+ }
348
+ const el = SVG_TAGS.has(type)
349
+ ? document.createElementNS(SVG_NAMESPACE, type)
350
+ : document.createElement(type);
351
+ applyProps(el, props, cleanups);
352
+ for (const child of children) {
353
+ const childNodes = renderChildren(child, cleanups);
354
+ childNodes.forEach((node) => el.appendChild(node));
355
+ }
356
+ parentCleanups.push(() => {
357
+ cleanups.forEach((fn) => {
358
+ fn();
359
+ });
360
+ });
361
+ return {
362
+ el,
363
+ vnode,
364
+ cleanups,
365
+ children: [],
366
+ };
367
+ }
368
+ export function render(vnode, container) {
369
+ const cleanups = [];
370
+ container.innerHTML = "";
371
+ const mounted = mountVNode(vnode, container, cleanups);
372
+ container.appendChild(mounted.el);
373
+ return () => {
374
+ cleanups.forEach((fn) => {
375
+ fn();
376
+ });
377
+ container.innerHTML = "";
378
+ };
379
+ }
380
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@praxisjs/runtime",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "devDependencies": {
14
+ "typescript": "^5.9.3"
15
+ },
16
+ "dependencies": {
17
+ "@praxisjs/core": "0.1.0",
18
+ "@praxisjs/decorators": "0.1.0",
19
+ "@praxisjs/jsx": "0.1.0",
20
+ "@praxisjs/shared": "0.1.0"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "dev": "tsc --watch"
25
+ }
26
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { render } from "./renderer";
@@ -0,0 +1,473 @@
1
+ import {
2
+ effect,
3
+ createFunctionalContext,
4
+ setFunctionalContext,
5
+ } from "@praxisjs/core";
6
+ import { initSlots } from "@praxisjs/decorators";
7
+ import type {
8
+ VNode,
9
+ ChildrenInternal,
10
+ ComponentInstance,
11
+ } from "@praxisjs/shared";
12
+
13
+ const EVENT_MAP: Record<string, string> = {
14
+ onClick: "click",
15
+ onDblClick: "dblclick",
16
+ onChange: "change",
17
+ onInput: "input",
18
+ onSubmit: "submit",
19
+ onReset: "reset",
20
+ onKeyDown: "keydown",
21
+ onKeyUp: "keyup",
22
+ onKeyPress: "keypress",
23
+ onFocus: "focus",
24
+ onBlur: "blur",
25
+ onMouseDown: "mousedown",
26
+ onMouseUp: "mouseup",
27
+ onMouseEnter: "mouseenter",
28
+ onMouseLeave: "mouseleave",
29
+ onMouseMove: "mousemove",
30
+ onContextMenu: "contextmenu",
31
+ onScroll: "scroll",
32
+ onWheel: "wheel",
33
+ onDragStart: "dragstart",
34
+ onDragEnd: "dragend",
35
+ onDragOver: "dragover",
36
+ onDrop: "drop",
37
+ onTouchStart: "touchstart",
38
+ onTouchEnd: "touchend",
39
+ onTouchMove: "touchmove",
40
+ onAnimationEnd: "animationend",
41
+ onTransitionEnd: "transitionend",
42
+ };
43
+
44
+ interface MountedNode {
45
+ el: Node;
46
+ vnode?: VNode;
47
+ instance?: ComponentInstance;
48
+ cleanups: Array<() => void>;
49
+ children: MountedNode[];
50
+ }
51
+
52
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
53
+ const SVG_TAGS = new Set([
54
+ "svg",
55
+ "path",
56
+ "circle",
57
+ "rect",
58
+ "line",
59
+ "polyline",
60
+ "polygon",
61
+ "ellipse",
62
+ "text",
63
+ "g",
64
+ "defs",
65
+ "use",
66
+ "symbol",
67
+ "marker",
68
+ "clipPath",
69
+ "mask",
70
+ "pattern",
71
+ "image",
72
+ "linearGradient",
73
+ "radialGradient",
74
+ "stop",
75
+ "filter",
76
+ "feGaussianBlur",
77
+ "tspan",
78
+ "textPath",
79
+ "foreignObject",
80
+ ]);
81
+
82
+ function applyProps(
83
+ el: Element,
84
+ props: Record<string, unknown>,
85
+ cleanups: Array<() => void>,
86
+ ) {
87
+ for (const [key, value] of Object.entries(props)) {
88
+ if (key === "key" || key === "children") continue;
89
+
90
+ if (key in EVENT_MAP) {
91
+ const eventName = EVENT_MAP[key];
92
+ const eventListener = value as EventListener;
93
+ el.addEventListener(eventName, eventListener);
94
+ cleanups.push(() => {
95
+ el.removeEventListener(eventName, eventListener);
96
+ });
97
+ continue;
98
+ }
99
+
100
+ if (key === "ref" && typeof value === "function") {
101
+ (value as (el: Element) => void)(el);
102
+ continue;
103
+ }
104
+
105
+ if (key === "className" || key === "class") {
106
+ if (typeof value === "function") {
107
+ cleanups.push(
108
+ effect(() => {
109
+ el.setAttribute("class", String((value as () => unknown)()));
110
+ }),
111
+ );
112
+ } else {
113
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
114
+ el.setAttribute("class", String(value ?? ""));
115
+ }
116
+ continue;
117
+ }
118
+
119
+ if (key === "style") {
120
+ if (typeof value === "function") {
121
+ cleanups.push(
122
+ effect(() => {
123
+ const styleValue = (value as () => unknown)();
124
+ if (typeof styleValue === "object" && styleValue !== null) {
125
+ el.removeAttribute("style");
126
+ Object.assign((el as HTMLElement).style, styleValue);
127
+ } else {
128
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
129
+ el.setAttribute("style", String(styleValue ?? ""));
130
+ }
131
+ }),
132
+ );
133
+ } else if (typeof value === "object" && value !== null) {
134
+ el.removeAttribute("style");
135
+ Object.assign((el as HTMLElement).style, value);
136
+ } else {
137
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
138
+ el.setAttribute("style", String(value ?? ""));
139
+ }
140
+ continue;
141
+ }
142
+
143
+ if (["checked", "value", "disabled", "selected"].includes(key)) {
144
+ if (typeof value === "function") {
145
+ cleanups.push(
146
+ effect(() => {
147
+ (el as unknown as Record<string, unknown>)[key] = (
148
+ value as () => unknown
149
+ )();
150
+ }),
151
+ );
152
+ } else {
153
+ (el as unknown as Record<string, unknown>)[key] = value;
154
+ }
155
+ continue;
156
+ }
157
+
158
+ if (typeof value === "function") {
159
+ const attrKey = key === "htmlFor" ? "for" : key;
160
+ cleanups.push(
161
+ effect(() => {
162
+ const attrValue = (value as () => unknown)();
163
+ if (
164
+ attrValue === false ||
165
+ attrValue === null ||
166
+ attrValue === undefined
167
+ ) {
168
+ el.removeAttribute(attrKey);
169
+ } else if (attrValue === true) {
170
+ el.setAttribute(attrKey, "");
171
+ } else {
172
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
173
+ el.setAttribute(attrKey, String(attrValue));
174
+ }
175
+ }),
176
+ );
177
+ continue;
178
+ }
179
+
180
+ if (typeof value === "boolean") {
181
+ if (value) {
182
+ el.setAttribute(key, "");
183
+ } else {
184
+ el.removeAttribute(key);
185
+ }
186
+ continue;
187
+ }
188
+
189
+ if (value !== null && value !== undefined) {
190
+ const attrKey = key === "htmlFor" ? "for" : key;
191
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
192
+ el.setAttribute(attrKey, String(value));
193
+ }
194
+ }
195
+ }
196
+
197
+ function renderChildren(
198
+ children: ChildrenInternal,
199
+ cleanups: Array<() => void>,
200
+ ): Node[] {
201
+ if (children === null || children === undefined || children === false) {
202
+ return [document.createComment("empty")];
203
+ }
204
+
205
+ if (typeof children === "string" || typeof children === "number") {
206
+ return [document.createTextNode(String(children))];
207
+ }
208
+
209
+ if (Array.isArray(children)) {
210
+ return children.flatMap((child) => renderChildren(child, cleanups));
211
+ }
212
+
213
+ if (typeof children === "function") {
214
+ const fn = children as () => ChildrenInternal;
215
+
216
+ const anchor = document.createComment("reactive");
217
+ let currentNodes: Node[] = [];
218
+ let childCleanups: Array<() => void> = [];
219
+ let initialized = false;
220
+
221
+ cleanups.push(
222
+ effect(() => {
223
+ const result = fn();
224
+
225
+ if (!initialized) {
226
+ currentNodes = renderChildren(result, childCleanups);
227
+ initialized = true;
228
+ return;
229
+ }
230
+
231
+ childCleanups.forEach((c) => { c(); });
232
+ childCleanups = [];
233
+
234
+ const parent = anchor.parentNode;
235
+ if (!parent) return;
236
+
237
+ for (const node of currentNodes) {
238
+ if (node.parentNode === parent) {
239
+ parent.removeChild(node);
240
+ }
241
+ }
242
+
243
+ const newNodes = renderChildren(result, childCleanups);
244
+ newNodes.forEach((node) => parent.insertBefore(node, anchor));
245
+ currentNodes = newNodes;
246
+ }),
247
+ );
248
+
249
+ cleanups.push(() => {
250
+ childCleanups.forEach((c) => { c(); });
251
+ });
252
+
253
+ return [...currentNodes, anchor];
254
+ }
255
+
256
+ if (typeof children === "object" && "type" in children) {
257
+ const mounted = mountVNode(
258
+ children,
259
+ document.createComment("object"),
260
+ cleanups,
261
+ );
262
+ return [mounted.el];
263
+ }
264
+
265
+ return [document.createTextNode(String(children))];
266
+ }
267
+
268
+ function mountVNode(
269
+ vnode: VNode,
270
+ _parent: Node,
271
+ parentCleanups: Array<() => void>,
272
+ ): MountedNode {
273
+ const cleanups: Array<() => void> = [];
274
+ const { type, props, children } = vnode;
275
+
276
+ if (typeof type === "function" && "isComponent" in type) {
277
+ const instance = new type({
278
+ ...props,
279
+ });
280
+ if (children.length > 0) {
281
+ initSlots(instance, children);
282
+ }
283
+ instance.onBeforeMount?.();
284
+
285
+ const wrapper = document.createElement("div");
286
+ wrapper.setAttribute("data-component", type.name || "AnonymousComponent");
287
+
288
+ const isMemoized = instance._isMemorized;
289
+
290
+ cleanups.push(
291
+ effect(() => {
292
+ if (instance._mounted) return;
293
+
294
+ if (!isMemoized) {
295
+ const resolvedProps: Record<string, unknown> = {};
296
+ for (const [key, value] of Object.entries(props)) {
297
+ if (key === "children" || key === "key") continue;
298
+ if (typeof value === "function") {
299
+ resolvedProps[key] = (value as () => unknown)();
300
+ } else {
301
+ resolvedProps[key] = value;
302
+ }
303
+ }
304
+
305
+ if (!instance._stateDirty) {
306
+ const arePropsEqual = instance._arePropsEqual;
307
+ const lastProps = instance._lastResolvedProps;
308
+
309
+ if (
310
+ lastProps !== undefined &&
311
+ arePropsEqual?.(lastProps, resolvedProps)
312
+ ) {
313
+ return;
314
+ }
315
+ }
316
+
317
+ instance._lastResolvedProps = resolvedProps;
318
+ }
319
+
320
+ instance._stateDirty = false;
321
+ instance._setProps({ ...props });
322
+
323
+ let rerenderedVNode: VNode | null = null;
324
+ try {
325
+ rerenderedVNode = instance.render();
326
+ } catch (e) {
327
+ console.error("Error rendering component:", e);
328
+ const error = e instanceof Error ? e : new Error(String(e));
329
+ instance.onError?.(error);
330
+ }
331
+
332
+ wrapper.innerHTML = "";
333
+
334
+ if (rerenderedVNode) {
335
+ const childNode = mountVNode(rerenderedVNode, wrapper, cleanups);
336
+ wrapper.appendChild(childNode.el);
337
+ }
338
+ }),
339
+ );
340
+
341
+ parentCleanups.push(() => {
342
+ instance.onUnmount?.();
343
+ instance._mounted = false;
344
+ cleanups.forEach((fn) => {
345
+ fn();
346
+ });
347
+ });
348
+
349
+ queueMicrotask(() => {
350
+ instance.onMount?.();
351
+ instance._mounted = true;
352
+ });
353
+
354
+ return {
355
+ el: wrapper,
356
+ vnode,
357
+ instance,
358
+ cleanups,
359
+ children: [],
360
+ };
361
+ }
362
+
363
+ if (typeof type === "function") {
364
+ const resolvedType = type as (
365
+ props: Record<string, unknown> & { children?: ChildrenInternal[] },
366
+ ) => VNode | null;
367
+
368
+ const ctx = createFunctionalContext();
369
+ setFunctionalContext(ctx);
370
+
371
+ let resolvedVNode: VNode | null = null;
372
+ try {
373
+ resolvedVNode = resolvedType({ ...props, children });
374
+ } catch (e) {
375
+ const error = e instanceof Error ? e : new Error(String(e));
376
+ ctx.onError.forEach((fn) => {
377
+ fn(error);
378
+ });
379
+ }
380
+
381
+ setFunctionalContext(null);
382
+
383
+ ctx.onBeforeMount.forEach((fn) => {
384
+ fn();
385
+ });
386
+
387
+ if (!resolvedVNode) {
388
+ const commentNode = document.createComment(
389
+ `<${type.name || "AnonymousComponent"} />`,
390
+ );
391
+ queueMicrotask(() => {
392
+ ctx.onMount.forEach((fn) => {
393
+ fn();
394
+ });
395
+ });
396
+ cleanups.push(() => {
397
+ ctx.onUnmount.forEach((fn) => {
398
+ fn();
399
+ });
400
+ });
401
+ parentCleanups.push(() => {
402
+ cleanups.forEach((fn) => {
403
+ fn();
404
+ });
405
+ });
406
+ return {
407
+ el: commentNode,
408
+ cleanups,
409
+ children: [],
410
+ };
411
+ }
412
+
413
+ const childNode = mountVNode(resolvedVNode, _parent, cleanups);
414
+ queueMicrotask(() => {
415
+ ctx.onMount.forEach((fn) => {
416
+ fn();
417
+ });
418
+ });
419
+ cleanups.push(() => {
420
+ ctx.onUnmount.forEach((fn) => {
421
+ fn();
422
+ });
423
+ });
424
+ parentCleanups.push(() => {
425
+ cleanups.forEach((fn) => {
426
+ fn();
427
+ });
428
+ });
429
+ return {
430
+ el: childNode.el,
431
+ vnode,
432
+ cleanups,
433
+ children: [],
434
+ };
435
+ }
436
+
437
+ const el = SVG_TAGS.has(type)
438
+ ? document.createElementNS(SVG_NAMESPACE, type)
439
+ : document.createElement(type);
440
+ applyProps(el, props, cleanups);
441
+
442
+ for (const child of children) {
443
+ const childNodes = renderChildren(child, cleanups);
444
+ childNodes.forEach((node) => el.appendChild(node));
445
+ }
446
+
447
+ parentCleanups.push(() => {
448
+ cleanups.forEach((fn) => {
449
+ fn();
450
+ });
451
+ });
452
+
453
+ return {
454
+ el,
455
+ vnode,
456
+ cleanups,
457
+ children: [],
458
+ };
459
+ }
460
+
461
+ export function render(vnode: VNode, container: HTMLElement) {
462
+ const cleanups: Array<() => void> = [];
463
+ container.innerHTML = "";
464
+ const mounted = mountVNode(vnode, container, cleanups);
465
+ container.appendChild(mounted.el);
466
+
467
+ return () => {
468
+ cleanups.forEach((fn) => {
469
+ fn();
470
+ });
471
+ container.innerHTML = "";
472
+ };
473
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src"]
8
+ }