@rettangoli/fe 0.0.7-rc2 → 0.0.7-rc4
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/package.json +8 -2
- package/src/cli/watch.js +2 -0
- package/src/common.js +1 -1
- package/src/createComponent.js +9 -8
- package/src/parser.js +66 -52
package/package.json
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rettangoli/fe",
|
|
3
|
-
"version": "0.0.7-
|
|
3
|
+
"version": "0.0.7-rc4",
|
|
4
4
|
"description": "Frontend framework for building reactive web components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
|
-
"keywords": [
|
|
7
|
+
"keywords": [
|
|
8
|
+
"frontend",
|
|
9
|
+
"reactive",
|
|
10
|
+
"components",
|
|
11
|
+
"web",
|
|
12
|
+
"framework"
|
|
13
|
+
],
|
|
8
14
|
"files": [
|
|
9
15
|
"src",
|
|
10
16
|
"README.md",
|
package/src/cli/watch.js
CHANGED
package/src/common.js
CHANGED
|
@@ -8,7 +8,7 @@ import { Subject } from "rxjs";
|
|
|
8
8
|
* const subject = new CustomSubject();
|
|
9
9
|
*
|
|
10
10
|
* const subscription = subject.subscribe(({ action, payload }) => {
|
|
11
|
-
*
|
|
11
|
+
* // handle action and payload
|
|
12
12
|
* });
|
|
13
13
|
*
|
|
14
14
|
* subject.dispatch("action", { payload: "payload" });
|
package/src/createComponent.js
CHANGED
|
@@ -353,7 +353,15 @@ class BaseComponent extends HTMLElement {
|
|
|
353
353
|
}
|
|
354
354
|
|
|
355
355
|
try {
|
|
356
|
-
|
|
356
|
+
const deps = {
|
|
357
|
+
...this.deps,
|
|
358
|
+
refIds: this.refIds,
|
|
359
|
+
getRefIds: () => this.refIds,
|
|
360
|
+
dispatchEvent: this.dispatchEvent.bind(this),
|
|
361
|
+
store: this.store,
|
|
362
|
+
render: this.render.bind(this),
|
|
363
|
+
};
|
|
364
|
+
|
|
357
365
|
const vDom = parseView({
|
|
358
366
|
h: this.h,
|
|
359
367
|
template: this.template,
|
|
@@ -361,9 +369,6 @@ class BaseComponent extends HTMLElement {
|
|
|
361
369
|
refs: this.refs,
|
|
362
370
|
handlers: this.transformedHandlers,
|
|
363
371
|
});
|
|
364
|
-
|
|
365
|
-
// const parseTime = performance.now() - parseStart;
|
|
366
|
-
// console.log(`parseView took ${parseTime.toFixed(2)}ms`);
|
|
367
372
|
// parse through vDom and recursively find all elements with id
|
|
368
373
|
const ids = {};
|
|
369
374
|
const findIds = (vDom) => {
|
|
@@ -377,15 +382,11 @@ class BaseComponent extends HTMLElement {
|
|
|
377
382
|
findIds(vDom);
|
|
378
383
|
this.refIds = ids;
|
|
379
384
|
|
|
380
|
-
// const patchStart = performance.now();
|
|
381
385
|
if (!this._oldVNode) {
|
|
382
386
|
this._oldVNode = this.patch(this.renderTarget, vDom);
|
|
383
387
|
} else {
|
|
384
388
|
this._oldVNode = this.patch(this._oldVNode, vDom);
|
|
385
389
|
}
|
|
386
|
-
|
|
387
|
-
// const patchTime = performance.now() - patchStart;
|
|
388
|
-
// console.log(`patch took ${patchTime.toFixed(2)}ms`);
|
|
389
390
|
} catch (error) {
|
|
390
391
|
console.error("Error during patching:", error);
|
|
391
392
|
}
|
package/src/parser.js
CHANGED
|
@@ -4,16 +4,16 @@ import { flattenArrays } from './common.js';
|
|
|
4
4
|
|
|
5
5
|
const lodashGet = (obj, path) => {
|
|
6
6
|
if (!path) return obj;
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
// Parse path to handle both dot notation and bracket notation
|
|
9
9
|
const parts = [];
|
|
10
10
|
let current = '';
|
|
11
11
|
let inBrackets = false;
|
|
12
12
|
let quoteChar = null;
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
for (let i = 0; i < path.length; i++) {
|
|
15
15
|
const char = path[i];
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
if (!inBrackets && char === '.') {
|
|
18
18
|
if (current) {
|
|
19
19
|
parts.push(current);
|
|
@@ -28,14 +28,14 @@ const lodashGet = (obj, path) => {
|
|
|
28
28
|
} else if (inBrackets && char === ']') {
|
|
29
29
|
if (current) {
|
|
30
30
|
// Remove quotes if present and add the key
|
|
31
|
-
if ((current.startsWith('"') && current.endsWith('"')) ||
|
|
32
|
-
|
|
31
|
+
if ((current.startsWith('"') && current.endsWith('"')) ||
|
|
32
|
+
(current.startsWith("'") && current.endsWith("'"))) {
|
|
33
33
|
parts.push(current.slice(1, -1));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
} else {
|
|
35
|
+
// Numeric index or unquoted string
|
|
36
|
+
const numValue = Number(current);
|
|
37
|
+
parts.push(isNaN(numValue) ? current : numValue);
|
|
38
|
+
}
|
|
39
39
|
current = '';
|
|
40
40
|
}
|
|
41
41
|
inBrackets = false;
|
|
@@ -51,24 +51,20 @@ const lodashGet = (obj, path) => {
|
|
|
51
51
|
current += char;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
if (current) {
|
|
56
56
|
parts.push(current);
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
return parts.reduce((acc, part) => acc && acc[part], obj);
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
export const parseView = ({ h, template, viewData, refs, handlers }) => {
|
|
63
|
-
// const startTime = performance.now();
|
|
64
63
|
const result = jemplRender({
|
|
65
64
|
ast: template,
|
|
66
65
|
data: viewData,
|
|
67
66
|
});
|
|
68
|
-
|
|
69
|
-
// const executionTime = endTime - startTime;
|
|
70
|
-
// console.log(`jemplRender execution time: ${executionTime.toFixed(2)}ms`);
|
|
71
|
-
|
|
67
|
+
|
|
72
68
|
// Flatten the array carefully to maintain structure
|
|
73
69
|
const flattenedResult = flattenArrays(result);
|
|
74
70
|
|
|
@@ -98,7 +94,7 @@ export const createVirtualDom = ({
|
|
|
98
94
|
items,
|
|
99
95
|
refs = {},
|
|
100
96
|
handlers = {},
|
|
101
|
-
viewData = {}
|
|
97
|
+
viewData = {}
|
|
102
98
|
}) => {
|
|
103
99
|
if (!Array.isArray(items)) {
|
|
104
100
|
console.error("Input to createVirtualDom must be an array.");
|
|
@@ -335,42 +331,60 @@ export const createVirtualDom = ({
|
|
|
335
331
|
}
|
|
336
332
|
if (Object.keys(props).length > 0) {
|
|
337
333
|
snabbdomData.props = props;
|
|
334
|
+
}
|
|
338
335
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
336
|
+
// For web components, add a hook to detect prop and attr changes
|
|
337
|
+
if (isWebComponent) {
|
|
338
|
+
snabbdomData.hook = {
|
|
339
|
+
update: (oldVnode, vnode) => {
|
|
340
|
+
const oldProps = oldVnode.data?.props || {};
|
|
341
|
+
const newProps = vnode.data?.props || {};
|
|
342
|
+
const oldAttrs = oldVnode.data?.attrs || {};
|
|
343
|
+
const newAttrs = vnode.data?.attrs || {};
|
|
344
|
+
|
|
345
|
+
// Check if props have changed
|
|
346
|
+
const propsChanged =
|
|
347
|
+
JSON.stringify(oldProps) !== JSON.stringify(newProps);
|
|
348
|
+
|
|
349
|
+
// Check if attrs have changed
|
|
350
|
+
const attrsChanged =
|
|
351
|
+
JSON.stringify(oldAttrs) !== JSON.stringify(newAttrs);
|
|
352
|
+
|
|
353
|
+
if (propsChanged || attrsChanged) {
|
|
354
|
+
// Set isDirty attribute and trigger re-render
|
|
355
|
+
const element = vnode.elm;
|
|
356
|
+
if (
|
|
357
|
+
element &&
|
|
358
|
+
element.render &&
|
|
359
|
+
typeof element.render === "function"
|
|
360
|
+
) {
|
|
361
|
+
element.setAttribute("isDirty", "true");
|
|
362
|
+
requestAnimationFrame(() => {
|
|
363
|
+
element.render();
|
|
364
|
+
element.removeAttribute("isDirty");
|
|
365
|
+
// Call the specific component's handleOnUpdate instead of the parent's onUpdate
|
|
366
|
+
if (element.handlers && element.handlers.handleOnUpdate) {
|
|
367
|
+
const deps = {
|
|
368
|
+
...(element.deps || {}),
|
|
369
|
+
store: element.store,
|
|
370
|
+
render: element.render.bind(element),
|
|
371
|
+
handlers: element.handlers,
|
|
372
|
+
dispatchEvent: element.dispatchEvent.bind(element),
|
|
373
|
+
refIds: element.refIds || {},
|
|
374
|
+
getRefIds: () => element.refIds || {},
|
|
375
|
+
};
|
|
376
|
+
element.handlers.handleOnUpdate({
|
|
377
|
+
oldProps,
|
|
378
|
+
newProps,
|
|
379
|
+
oldAttrs,
|
|
380
|
+
newAttrs,
|
|
381
|
+
}, deps);
|
|
382
|
+
}
|
|
383
|
+
});
|
|
370
384
|
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
};
|
|
374
388
|
}
|
|
375
389
|
|
|
376
390
|
try {
|