rask-ui 0.2.4 → 0.2.6
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/dist/vdom/AbstractVNode.d.ts +24 -2
- package/dist/vdom/AbstractVNode.d.ts.map +1 -1
- package/dist/vdom/AbstractVNode.js +153 -13
- package/dist/vdom/ComponentVNode.d.ts +2 -2
- package/dist/vdom/ComponentVNode.d.ts.map +1 -1
- package/dist/vdom/ComponentVNode.js +11 -13
- package/dist/vdom/ElementVNode.d.ts +2 -8
- package/dist/vdom/ElementVNode.d.ts.map +1 -1
- package/dist/vdom/ElementVNode.js +15 -32
- package/dist/vdom/FragmentVNode.d.ts +2 -2
- package/dist/vdom/FragmentVNode.d.ts.map +1 -1
- package/dist/vdom/FragmentVNode.js +12 -3
- package/dist/vdom/RootVNode.d.ts +2 -2
- package/dist/vdom/RootVNode.d.ts.map +1 -1
- package/dist/vdom/RootVNode.js +7 -5
- package/package.json +1 -1
- package/dist/component.d.ts +0 -38
- package/dist/component.d.ts.map +0 -1
- package/dist/component.js +0 -130
- package/dist/context.d.ts +0 -5
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -29
- package/dist/createAsync.test.d.ts +0 -2
- package/dist/createAsync.test.d.ts.map +0 -1
- package/dist/createAsync.test.js +0 -110
- package/dist/createAsyncState.d.ts +0 -16
- package/dist/createAsyncState.d.ts.map +0 -1
- package/dist/createAsyncState.js +0 -24
- package/dist/createContext.test.d.ts +0 -2
- package/dist/createContext.test.d.ts.map +0 -1
- package/dist/createContext.test.js +0 -136
- package/dist/createMutation.test.d.ts +0 -2
- package/dist/createMutation.test.d.ts.map +0 -1
- package/dist/createMutation.test.js +0 -168
- package/dist/createQuery.test.d.ts +0 -2
- package/dist/createQuery.test.d.ts.map +0 -1
- package/dist/createQuery.test.js +0 -156
- package/dist/createRef.test.d.ts +0 -2
- package/dist/createRef.test.d.ts.map +0 -1
- package/dist/createRef.test.js +0 -80
- package/dist/createState.test.d.ts +0 -2
- package/dist/createState.test.d.ts.map +0 -1
- package/dist/createState.test.js +0 -111
- package/dist/createView.test.d.ts +0 -2
- package/dist/createView.test.d.ts.map +0 -1
- package/dist/createView.test.js +0 -203
- package/dist/error.test.d.ts +0 -2
- package/dist/error.test.d.ts.map +0 -1
- package/dist/error.test.js +0 -144
- package/dist/integration.test.d.ts +0 -2
- package/dist/integration.test.d.ts.map +0 -1
- package/dist/integration.test.js +0 -155
- package/dist/jsx.d.ts.map +0 -1
- package/dist/jsx.js +0 -42
- package/dist/observation.test.d.ts +0 -2
- package/dist/observation.test.d.ts.map +0 -1
- package/dist/observation.test.js +0 -113
- package/dist/render-test.d.ts +0 -2
- package/dist/render-test.d.ts.map +0 -1
- package/dist/render-test.js +0 -21
- package/dist/render.d.ts +0 -7
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -77
- package/dist/suspense.d.ts +0 -25
- package/dist/suspense.d.ts.map +0 -1
- package/dist/suspense.js +0 -97
- package/dist/tests/class.test.d.ts +0 -2
- package/dist/tests/class.test.d.ts.map +0 -1
- package/dist/tests/class.test.js +0 -185
- package/dist/tests/complex-rendering.test.d.ts +0 -2
- package/dist/tests/complex-rendering.test.d.ts.map +0 -1
- package/dist/tests/complex-rendering.test.js +0 -400
- package/dist/tests/component.cleanup.test.d.ts +0 -2
- package/dist/tests/component.cleanup.test.d.ts.map +0 -1
- package/dist/tests/component.cleanup.test.js +0 -325
- package/dist/tests/component.counter.test.d.ts +0 -2
- package/dist/tests/component.counter.test.d.ts.map +0 -1
- package/dist/tests/component.counter.test.js +0 -124
- package/dist/tests/component.interaction.test.d.ts +0 -2
- package/dist/tests/component.interaction.test.d.ts.map +0 -1
- package/dist/tests/component.interaction.test.js +0 -73
- package/dist/tests/component.props.test.d.ts +0 -2
- package/dist/tests/component.props.test.d.ts.map +0 -1
- package/dist/tests/component.props.test.js +0 -334
- package/dist/tests/component.return-types.test.d.ts +0 -2
- package/dist/tests/component.return-types.test.d.ts.map +0 -1
- package/dist/tests/component.return-types.test.js +0 -357
- package/dist/tests/component.state.test.d.ts +0 -2
- package/dist/tests/component.state.test.d.ts.map +0 -1
- package/dist/tests/component.state.test.js +0 -135
- package/dist/tests/component.test.d.ts +0 -2
- package/dist/tests/component.test.d.ts.map +0 -1
- package/dist/tests/component.test.js +0 -63
- package/dist/tests/createAsync.test.d.ts +0 -2
- package/dist/tests/createAsync.test.d.ts.map +0 -1
- package/dist/tests/createAsync.test.js +0 -110
- package/dist/tests/createContext.test.d.ts +0 -2
- package/dist/tests/createContext.test.d.ts.map +0 -1
- package/dist/tests/createContext.test.js +0 -141
- package/dist/tests/createMutation.test.d.ts +0 -2
- package/dist/tests/createMutation.test.d.ts.map +0 -1
- package/dist/tests/createMutation.test.js +0 -168
- package/dist/tests/createQuery.test.d.ts +0 -2
- package/dist/tests/createQuery.test.d.ts.map +0 -1
- package/dist/tests/createQuery.test.js +0 -156
- package/dist/tests/createRef.test.d.ts +0 -2
- package/dist/tests/createRef.test.d.ts.map +0 -1
- package/dist/tests/createRef.test.js +0 -84
- package/dist/tests/createState.test.d.ts +0 -2
- package/dist/tests/createState.test.d.ts.map +0 -1
- package/dist/tests/createState.test.js +0 -103
- package/dist/tests/createView.test.d.ts +0 -2
- package/dist/tests/createView.test.d.ts.map +0 -1
- package/dist/tests/createView.test.js +0 -203
- package/dist/tests/edge-cases.test.d.ts +0 -2
- package/dist/tests/edge-cases.test.d.ts.map +0 -1
- package/dist/tests/edge-cases.test.js +0 -637
- package/dist/tests/error-no-boundary.test.d.ts +0 -2
- package/dist/tests/error-no-boundary.test.d.ts.map +0 -1
- package/dist/tests/error-no-boundary.test.js +0 -174
- package/dist/tests/error.test.d.ts +0 -2
- package/dist/tests/error.test.d.ts.map +0 -1
- package/dist/tests/error.test.js +0 -199
- package/dist/tests/fragment.test.d.ts +0 -2
- package/dist/tests/fragment.test.d.ts.map +0 -1
- package/dist/tests/fragment.test.js +0 -618
- package/dist/tests/integration.test.d.ts +0 -2
- package/dist/tests/integration.test.d.ts.map +0 -1
- package/dist/tests/integration.test.js +0 -192
- package/dist/tests/keys.test.d.ts +0 -2
- package/dist/tests/keys.test.d.ts.map +0 -1
- package/dist/tests/keys.test.js +0 -293
- package/dist/tests/mount.test.d.ts +0 -2
- package/dist/tests/mount.test.d.ts.map +0 -1
- package/dist/tests/mount.test.js +0 -91
- package/dist/tests/observation.test.d.ts +0 -2
- package/dist/tests/observation.test.d.ts.map +0 -1
- package/dist/tests/observation.test.js +0 -113
- package/dist/tests/patch.test.d.ts +0 -2
- package/dist/tests/patch.test.d.ts.map +0 -1
- package/dist/tests/patch.test.js +0 -498
- package/dist/tests/patchChildren.test.d.ts +0 -2
- package/dist/tests/patchChildren.test.d.ts.map +0 -1
- package/dist/tests/patchChildren.test.js +0 -387
- package/dist/tests/primitives.test.d.ts +0 -2
- package/dist/tests/primitives.test.d.ts.map +0 -1
- package/dist/tests/primitives.test.js +0 -132
- package/dist/vdom/class.test.d.ts +0 -2
- package/dist/vdom/class.test.d.ts.map +0 -1
- package/dist/vdom/class.test.js +0 -143
- package/dist/vdom/complex-rendering.test.d.ts +0 -2
- package/dist/vdom/complex-rendering.test.d.ts.map +0 -1
- package/dist/vdom/complex-rendering.test.js +0 -400
- package/dist/vdom/component.cleanup.test.d.ts +0 -2
- package/dist/vdom/component.cleanup.test.d.ts.map +0 -1
- package/dist/vdom/component.cleanup.test.js +0 -323
- package/dist/vdom/component.counter.test.d.ts +0 -2
- package/dist/vdom/component.counter.test.d.ts.map +0 -1
- package/dist/vdom/component.counter.test.js +0 -124
- package/dist/vdom/component.interaction.test.d.ts +0 -2
- package/dist/vdom/component.interaction.test.d.ts.map +0 -1
- package/dist/vdom/component.interaction.test.js +0 -73
- package/dist/vdom/component.props.test.d.ts +0 -2
- package/dist/vdom/component.props.test.d.ts.map +0 -1
- package/dist/vdom/component.props.test.js +0 -88
- package/dist/vdom/component.return-types.test.d.ts +0 -2
- package/dist/vdom/component.return-types.test.d.ts.map +0 -1
- package/dist/vdom/component.return-types.test.js +0 -357
- package/dist/vdom/component.state.test.d.ts +0 -2
- package/dist/vdom/component.state.test.d.ts.map +0 -1
- package/dist/vdom/component.state.test.js +0 -129
- package/dist/vdom/component.test.d.ts +0 -2
- package/dist/vdom/component.test.d.ts.map +0 -1
- package/dist/vdom/component.test.js +0 -63
- package/dist/vdom/edge-cases.test.d.ts +0 -2
- package/dist/vdom/edge-cases.test.d.ts.map +0 -1
- package/dist/vdom/edge-cases.test.js +0 -637
- package/dist/vdom/fragment.test.d.ts +0 -2
- package/dist/vdom/fragment.test.d.ts.map +0 -1
- package/dist/vdom/fragment.test.js +0 -618
- package/dist/vdom/keys.test.d.ts +0 -2
- package/dist/vdom/keys.test.d.ts.map +0 -1
- package/dist/vdom/keys.test.js +0 -293
- package/dist/vdom/mount.test.d.ts +0 -2
- package/dist/vdom/mount.test.d.ts.map +0 -1
- package/dist/vdom/mount.test.js +0 -91
- package/dist/vdom/patch.test.d.ts +0 -2
- package/dist/vdom/patch.test.d.ts.map +0 -1
- package/dist/vdom/patch.test.js +0 -498
- package/dist/vdom/patchChildren.test.d.ts +0 -2
- package/dist/vdom/patchChildren.test.d.ts.map +0 -1
- package/dist/vdom/patchChildren.test.js +0 -392
- package/dist/vdom/primitives.test.d.ts +0 -2
- package/dist/vdom/primitives.test.d.ts.map +0 -1
- package/dist/vdom/primitives.test.js +0 -132
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { RootVNode } from "./RootVNode";
|
|
2
2
|
import { VNode } from "./types";
|
|
3
|
+
export type PatchOperation = {
|
|
4
|
+
type: "add";
|
|
5
|
+
elm: Node | Node[];
|
|
6
|
+
} | {
|
|
7
|
+
type: "replace";
|
|
8
|
+
oldElm: Node | Node[];
|
|
9
|
+
newElm: Node | Node[];
|
|
10
|
+
} | {
|
|
11
|
+
type: "remove";
|
|
12
|
+
elm: Node | Node[];
|
|
13
|
+
};
|
|
3
14
|
export declare abstract class AbstractVNode {
|
|
4
15
|
key?: string;
|
|
5
16
|
parent?: VNode;
|
|
@@ -9,7 +20,7 @@ export declare abstract class AbstractVNode {
|
|
|
9
20
|
abstract mount(parent?: VNode): Node | Node[];
|
|
10
21
|
abstract patch(oldNode: VNode): void;
|
|
11
22
|
abstract unmount(): void;
|
|
12
|
-
abstract rerender(): void;
|
|
23
|
+
abstract rerender(operations?: PatchOperation[]): void;
|
|
13
24
|
protected getHTMLElement(): HTMLElement;
|
|
14
25
|
/**
|
|
15
26
|
* A VNode can represent multiple elements (fragment of component)
|
|
@@ -17,6 +28,17 @@ export declare abstract class AbstractVNode {
|
|
|
17
28
|
getElements(): Node[];
|
|
18
29
|
getParentElement(): HTMLElement;
|
|
19
30
|
protected canPatch(oldNode: VNode, newNode: VNode): boolean;
|
|
20
|
-
patchChildren(newChildren: VNode[]):
|
|
31
|
+
patchChildren(newChildren: VNode[]): {
|
|
32
|
+
children: VNode[];
|
|
33
|
+
hasChangedStructure: boolean;
|
|
34
|
+
operations: PatchOperation[];
|
|
35
|
+
};
|
|
36
|
+
applyPatchOperations(target: HTMLElement, operations: PatchOperation[]): void;
|
|
37
|
+
/**
|
|
38
|
+
* Intelligently sync DOM to match children VNode order.
|
|
39
|
+
* Only performs DOM operations when elements are out of position.
|
|
40
|
+
* This is used by both patch() and rerender() to efficiently update children.
|
|
41
|
+
*/
|
|
42
|
+
protected syncDOMChildren(): void;
|
|
21
43
|
}
|
|
22
44
|
//# sourceMappingURL=AbstractVNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/AbstractVNode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AbstractVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/AbstractVNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,MAAM,cAAc,GACtB;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;IACtB,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACvB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;CACpB,CAAC;AAEN,8BAAsB,aAAa;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;IACnB,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,EAAE;IAC7C,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI;IACpC,QAAQ,CAAC,OAAO,IAAI,IAAI;IACxB,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IACtD,SAAS,CAAC,cAAc;IAOxB;;OAEG;IACH,WAAW,IAAI,IAAI,EAAE;IAWrB,gBAAgB,IAAI,WAAW;IAiB/B,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAG,OAAO;IAoB3D,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG;QACnC,QAAQ,EAAE,KAAK,EAAE,CAAC;QAClB,mBAAmB,EAAE,OAAO,CAAC;QAC7B,UAAU,EAAE,cAAc,EAAE,CAAC;KAC9B;IAkJD,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE;IAqCtE;;;;OAIG;IACH,SAAS,CAAC,eAAe;CA6B1B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { elementsToFragment } from "./dom-utils";
|
|
1
2
|
export class AbstractVNode {
|
|
2
3
|
key;
|
|
3
4
|
parent;
|
|
@@ -57,50 +58,189 @@ export class AbstractVNode {
|
|
|
57
58
|
// When there are only new children, we just mount them
|
|
58
59
|
if (newChildren && prevChildren.length === 0) {
|
|
59
60
|
newChildren.forEach((child) => child.mount(this));
|
|
60
|
-
return
|
|
61
|
+
return {
|
|
62
|
+
children: newChildren,
|
|
63
|
+
hasChangedStructure: true,
|
|
64
|
+
operations: [],
|
|
65
|
+
};
|
|
61
66
|
}
|
|
62
67
|
// If we want to remove all children, we just unmount the previous ones
|
|
63
68
|
if (!newChildren.length && prevChildren.length) {
|
|
64
69
|
prevChildren.forEach((child) => child.unmount());
|
|
65
|
-
return [];
|
|
70
|
+
return { children: [], hasChangedStructure: true, operations: [] };
|
|
66
71
|
}
|
|
67
72
|
const oldKeys = {};
|
|
68
73
|
prevChildren.forEach((prevChild, index) => {
|
|
69
|
-
oldKeys[prevChild.key || index] =
|
|
74
|
+
oldKeys[prevChild.key || index] = {
|
|
75
|
+
vnode: prevChild,
|
|
76
|
+
index,
|
|
77
|
+
};
|
|
70
78
|
});
|
|
71
79
|
// Build result array in the NEW order
|
|
72
80
|
const result = [];
|
|
81
|
+
const operations = [];
|
|
82
|
+
// Track indices of reused nodes in their original order
|
|
83
|
+
const reusedOldIndices = [];
|
|
84
|
+
// Track which result positions contain new nodes (not reused/replaced)
|
|
85
|
+
const isNewNode = [];
|
|
86
|
+
let forceStructuralChange = false;
|
|
73
87
|
newChildren.forEach((newChild, index) => {
|
|
74
88
|
const key = newChild.key || index;
|
|
75
89
|
const prevChild = oldKeys[key];
|
|
76
90
|
if (!prevChild) {
|
|
77
91
|
// New child - mount and add to result
|
|
78
|
-
newChild.mount(this);
|
|
92
|
+
const elm = newChild.mount(this);
|
|
79
93
|
result.push(newChild);
|
|
94
|
+
isNewNode.push(true);
|
|
95
|
+
operations.push({ type: "add", elm });
|
|
80
96
|
}
|
|
81
|
-
else if (prevChild === newChild) {
|
|
97
|
+
else if (prevChild?.vnode === newChild) {
|
|
82
98
|
// Same instance - no patching needed, just reuse
|
|
83
|
-
result.push(prevChild);
|
|
99
|
+
result.push(prevChild.vnode);
|
|
100
|
+
isNewNode.push(false);
|
|
101
|
+
reusedOldIndices.push(prevChild.index);
|
|
84
102
|
delete oldKeys[key];
|
|
85
103
|
}
|
|
86
|
-
else if (this.canPatch(prevChild, newChild)) {
|
|
104
|
+
else if (this.canPatch(prevChild.vnode, newChild)) {
|
|
87
105
|
// Compatible types - patch and reuse old VNode
|
|
88
|
-
prevChild.patch(newChild);
|
|
89
|
-
result.push(prevChild);
|
|
106
|
+
prevChild.vnode.patch(newChild);
|
|
107
|
+
result.push(prevChild.vnode);
|
|
108
|
+
isNewNode.push(false);
|
|
109
|
+
reusedOldIndices.push(prevChild.index);
|
|
90
110
|
delete oldKeys[key];
|
|
91
111
|
}
|
|
92
112
|
else {
|
|
93
113
|
// Incompatible types - replace completely
|
|
94
|
-
newChild.mount(this);
|
|
95
|
-
prevChild.unmount();
|
|
114
|
+
const newElm = newChild.mount(this);
|
|
115
|
+
prevChild.vnode.unmount();
|
|
96
116
|
result.push(newChild);
|
|
117
|
+
isNewNode.push(false); // Replacement, not an insertion
|
|
97
118
|
delete oldKeys[key];
|
|
119
|
+
const oldElm = prevChild.vnode.getElements();
|
|
120
|
+
// We need to fall back to structural change when the old node does
|
|
121
|
+
// not have any elements. This can happen when a component returns null,
|
|
122
|
+
// throws an error etc.
|
|
123
|
+
if (!oldElm.length) {
|
|
124
|
+
forceStructuralChange = true;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
operations.push({
|
|
128
|
+
type: "replace",
|
|
129
|
+
oldElm,
|
|
130
|
+
newElm,
|
|
131
|
+
});
|
|
98
132
|
}
|
|
99
133
|
});
|
|
100
134
|
// Unmount any old children that weren't reused
|
|
101
135
|
for (const key in oldKeys) {
|
|
102
|
-
oldKeys[key].unmount();
|
|
136
|
+
oldKeys[key].vnode.unmount();
|
|
137
|
+
operations.push({
|
|
138
|
+
type: "remove",
|
|
139
|
+
elm: oldKeys[key].vnode.getElements(),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Detect structural changes:
|
|
143
|
+
// 1. Reordering: reused nodes are not in their original relative order
|
|
144
|
+
// 2. Insertion in middle: new nodes inserted before existing nodes
|
|
145
|
+
let hasReordering = false;
|
|
146
|
+
let hasInsertionInMiddle = false;
|
|
147
|
+
if (!forceStructuralChange) {
|
|
148
|
+
for (let i = 1; i < reusedOldIndices.length; i++) {
|
|
149
|
+
if (reusedOldIndices[i] < reusedOldIndices[i - 1]) {
|
|
150
|
+
hasReordering = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (!hasReordering) {
|
|
156
|
+
// Find the last position that contains a reused/replaced node
|
|
157
|
+
let lastReusedResultIndex = -1;
|
|
158
|
+
for (let i = result.length - 1; i >= 0; i--) {
|
|
159
|
+
if (!isNewNode[i]) {
|
|
160
|
+
lastReusedResultIndex = i;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Check if any new nodes were inserted before the last reused/replaced node
|
|
165
|
+
if (lastReusedResultIndex >= 0) {
|
|
166
|
+
for (let i = 0; i < lastReusedResultIndex; i++) {
|
|
167
|
+
if (isNewNode[i]) {
|
|
168
|
+
hasInsertionInMiddle = true;
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const hasChangedStructure = forceStructuralChange || hasReordering || hasInsertionInMiddle;
|
|
175
|
+
if (hasChangedStructure) {
|
|
176
|
+
operations.length = 0;
|
|
177
|
+
}
|
|
178
|
+
return { children: result, hasChangedStructure, operations };
|
|
179
|
+
}
|
|
180
|
+
applyPatchOperations(target, operations) {
|
|
181
|
+
operations.forEach((operation) => {
|
|
182
|
+
switch (operation.type) {
|
|
183
|
+
case "add": {
|
|
184
|
+
target.appendChild(elementsToFragment(operation.elm));
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case "remove": {
|
|
188
|
+
if (Array.isArray(operation.elm)) {
|
|
189
|
+
const range = new Range();
|
|
190
|
+
range.setStartBefore(operation.elm[0]);
|
|
191
|
+
range.setEndAfter(operation.elm[operation.elm.length - 1]);
|
|
192
|
+
range.deleteContents();
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
target.removeChild(operation.elm);
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "replace": {
|
|
200
|
+
if (Array.isArray(operation.oldElm)) {
|
|
201
|
+
const range = new Range();
|
|
202
|
+
range.setStartBefore(operation.oldElm[0]);
|
|
203
|
+
range.setEndAfter(operation.oldElm[operation.oldElm.length - 1]);
|
|
204
|
+
range.deleteContents();
|
|
205
|
+
range.insertNode(elementsToFragment(operation.newElm));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
target.replaceChild(elementsToFragment(operation.newElm), operation.oldElm);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Intelligently sync DOM to match children VNode order.
|
|
217
|
+
* Only performs DOM operations when elements are out of position.
|
|
218
|
+
* This is used by both patch() and rerender() to efficiently update children.
|
|
219
|
+
*/
|
|
220
|
+
syncDOMChildren() {
|
|
221
|
+
if (!this.children) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const elm = this.elm;
|
|
225
|
+
let currentDomChild = elm.firstChild;
|
|
226
|
+
for (const child of this.children) {
|
|
227
|
+
const childNodes = child.getElements();
|
|
228
|
+
for (const node of childNodes) {
|
|
229
|
+
if (currentDomChild === node) {
|
|
230
|
+
// Already in correct position, advance pointer
|
|
231
|
+
currentDomChild = currentDomChild.nextSibling;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Insert (or move if it exists elsewhere in DOM)
|
|
235
|
+
elm.insertBefore(node, currentDomChild);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Remove any leftover nodes (shouldn't happen if unmount works correctly)
|
|
240
|
+
while (currentDomChild) {
|
|
241
|
+
const next = currentDomChild.nextSibling;
|
|
242
|
+
elm.removeChild(currentDomChild);
|
|
243
|
+
currentDomChild = next;
|
|
103
244
|
}
|
|
104
|
-
return result;
|
|
105
245
|
}
|
|
106
246
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Observer } from "../observation";
|
|
2
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
2
|
+
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
3
3
|
import { Props, VNode } from "./types";
|
|
4
4
|
export type ComponentChild = VNode | string | null | number | undefined | boolean;
|
|
5
5
|
export type ComponentChildren = ComponentChild | ComponentChild[];
|
|
@@ -40,7 +40,7 @@ export declare class ComponentVNode extends AbstractVNode {
|
|
|
40
40
|
children: VNode[];
|
|
41
41
|
instance?: ComponentInstance;
|
|
42
42
|
constructor(component: Component<any>, props: Props, children: VNode[], key?: string);
|
|
43
|
-
rerender(): void;
|
|
43
|
+
rerender(operations?: PatchOperation[]): void;
|
|
44
44
|
mount(parent?: VNode): Node[];
|
|
45
45
|
patch(newNode: ComponentVNode): void;
|
|
46
46
|
unmount(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ComponentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ComponentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ComponentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,QAAQ,EAAU,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGvC,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,MAAM,GACN,IAAI,GACJ,MAAM,GACN,SAAS,GACT,OAAO,CAAC;AACZ,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,cAAc,EAAE,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,KAAK,IACjC,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,iBAAiB,CAAC,GACvC,CAAC,MAAM,MAAM,iBAAiB,CAAC,CAAC;AAEpC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACtC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC,CAAC;AAKF,wBAAgB,mBAAmB,sBAYlC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAYrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAYvC;AAED,qBAAa,cAAe,SAAQ,aAAa;IAC/C,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;IAEb,QAAQ,EAAE,KAAK,EAAE,CAAM;IACvB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;gBAE3B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EACzB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,KAAK,EAAE,EACjB,GAAG,CAAC,EAAE,MAAM;IAWd,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAG7C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE;IA0I7B,KAAK,CAAC,OAAO,EAAE,cAAc;IAW7B,OAAO;CAcR"}
|
|
@@ -4,7 +4,6 @@ import { FragmentVNode } from "./FragmentVNode";
|
|
|
4
4
|
import { RootVNode } from "./RootVNode";
|
|
5
5
|
import { normalizeChildren } from "./utils";
|
|
6
6
|
import { currentRoot } from "./RootVNode";
|
|
7
|
-
import { ElementVNode } from "./ElementVNode";
|
|
8
7
|
export function getCurrentComponent() {
|
|
9
8
|
if (!currentRoot) {
|
|
10
9
|
throw new Error("No current root");
|
|
@@ -51,8 +50,8 @@ export class ComponentVNode extends AbstractVNode {
|
|
|
51
50
|
this.children = [];
|
|
52
51
|
this.key = key;
|
|
53
52
|
}
|
|
54
|
-
rerender() {
|
|
55
|
-
this.parent?.rerender();
|
|
53
|
+
rerender(operations) {
|
|
54
|
+
this.parent?.rerender(operations);
|
|
56
55
|
}
|
|
57
56
|
mount(parent) {
|
|
58
57
|
this.parent = parent;
|
|
@@ -96,18 +95,17 @@ export class ComponentVNode extends AbstractVNode {
|
|
|
96
95
|
isObserverQueued = false;
|
|
97
96
|
this.root?.setAsCurrent();
|
|
98
97
|
const newChildren = executeRender();
|
|
99
|
-
const
|
|
100
|
-
this.children =
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
prevChildren[0] instanceof ElementVNode &&
|
|
106
|
-
this.children[0] instanceof ElementVNode &&
|
|
107
|
-
this.canPatch(prevChildren[0], this.children[0]);
|
|
108
|
-
if (!canSelfUpdate) {
|
|
98
|
+
const { children, hasChangedStructure, operations } = this.patchChildren(newChildren);
|
|
99
|
+
this.children = children;
|
|
100
|
+
// So if a fragment is returned where we add new elements we can not safely
|
|
101
|
+
// add them yet, check Fragment for a potential later optimization
|
|
102
|
+
const hasAddOperation = operations.some((operation) => operation.type === "add");
|
|
103
|
+
if (hasChangedStructure || hasAddOperation) {
|
|
109
104
|
this.parent?.rerender();
|
|
110
105
|
}
|
|
106
|
+
else if (operations.length) {
|
|
107
|
+
this.parent?.rerender(operations);
|
|
108
|
+
}
|
|
111
109
|
this.root?.clearCurrent();
|
|
112
110
|
});
|
|
113
111
|
}),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
1
|
+
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
2
|
import { Props, VNode } from "./types";
|
|
3
3
|
export declare class ElementVNode extends AbstractVNode {
|
|
4
4
|
tag: string;
|
|
@@ -8,7 +8,7 @@ export declare class ElementVNode extends AbstractVNode {
|
|
|
8
8
|
private ref?;
|
|
9
9
|
private eventListeners?;
|
|
10
10
|
constructor(tag: string, { ref, ...props }: Props, children: VNode[], key?: string);
|
|
11
|
-
rerender(): void;
|
|
11
|
+
rerender(operations?: PatchOperation[]): void;
|
|
12
12
|
mount(parent?: VNode): Node;
|
|
13
13
|
/**
|
|
14
14
|
* An ELEMENT patch goes through three operations
|
|
@@ -20,11 +20,5 @@ export declare class ElementVNode extends AbstractVNode {
|
|
|
20
20
|
private setProp;
|
|
21
21
|
private patchProps;
|
|
22
22
|
private addEventListener;
|
|
23
|
-
/**
|
|
24
|
-
* Intelligently sync DOM to match children VNode order.
|
|
25
|
-
* Only performs DOM operations when elements are out of position.
|
|
26
|
-
* This is used by both patch() and rerender() to efficiently update children.
|
|
27
|
-
*/
|
|
28
|
-
private syncDOMChildren;
|
|
29
23
|
}
|
|
30
24
|
//# sourceMappingURL=ElementVNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ElementVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ElementVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/ElementVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAUvC,qBAAa,YAAa,SAAQ,aAAa;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,GAAG,CAAC,CAA0D;IACtE,OAAO,CAAC,cAAc,CAAC,CAA6B;gBAElD,GAAG,EAAE,MAAM,EACX,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,EACxB,QAAQ,EAAE,KAAK,EAAE,EACjB,GAAG,CAAC,EAAE,MAAM;IASd,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAO7C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;IAkC3B;;;;OAIG;IACH,KAAK,CAAC,OAAO,EAAE,YAAY;IAc3B,OAAO;IAYP,OAAO,CAAC,OAAO,CAoCb;IACF,OAAO,CAAC,UAAU;IAGlB,OAAO,CAAC,gBAAgB;CAgBzB"}
|
|
@@ -17,8 +17,13 @@ export class ElementVNode extends AbstractVNode {
|
|
|
17
17
|
this.key = key;
|
|
18
18
|
this.ref = ref;
|
|
19
19
|
}
|
|
20
|
-
rerender() {
|
|
21
|
-
|
|
20
|
+
rerender(operations) {
|
|
21
|
+
if (operations) {
|
|
22
|
+
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.syncDOMChildren();
|
|
26
|
+
}
|
|
22
27
|
}
|
|
23
28
|
mount(parent) {
|
|
24
29
|
this.parent = parent;
|
|
@@ -57,8 +62,14 @@ export class ElementVNode extends AbstractVNode {
|
|
|
57
62
|
patch(newNode) {
|
|
58
63
|
this.patchProps(newNode.props);
|
|
59
64
|
this.props = newNode.props;
|
|
60
|
-
|
|
61
|
-
this.
|
|
65
|
+
const { children, hasChangedStructure, operations } = this.patchChildren(newNode.children);
|
|
66
|
+
this.children = children;
|
|
67
|
+
if (hasChangedStructure) {
|
|
68
|
+
this.syncDOMChildren();
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
72
|
+
}
|
|
62
73
|
}
|
|
63
74
|
unmount() {
|
|
64
75
|
this.children.forEach((child) => child.unmount());
|
|
@@ -117,32 +128,4 @@ export class ElementVNode extends AbstractVNode {
|
|
|
117
128
|
delete this.eventListeners[type];
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
|
-
/**
|
|
121
|
-
* Intelligently sync DOM to match children VNode order.
|
|
122
|
-
* Only performs DOM operations when elements are out of position.
|
|
123
|
-
* This is used by both patch() and rerender() to efficiently update children.
|
|
124
|
-
*/
|
|
125
|
-
syncDOMChildren() {
|
|
126
|
-
const elm = this.elm;
|
|
127
|
-
let currentDomChild = elm.firstChild;
|
|
128
|
-
for (const child of this.children) {
|
|
129
|
-
const childNodes = child.getElements();
|
|
130
|
-
for (const node of childNodes) {
|
|
131
|
-
if (currentDomChild === node) {
|
|
132
|
-
// Already in correct position, advance pointer
|
|
133
|
-
currentDomChild = currentDomChild.nextSibling;
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
// Insert (or move if it exists elsewhere in DOM)
|
|
137
|
-
elm.insertBefore(node, currentDomChild);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
// Remove any leftover nodes (shouldn't happen if unmount works correctly)
|
|
142
|
-
while (currentDomChild) {
|
|
143
|
-
const next = currentDomChild.nextSibling;
|
|
144
|
-
elm.removeChild(currentDomChild);
|
|
145
|
-
currentDomChild = next;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
131
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
1
|
+
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
2
|
import { VNode } from "./types";
|
|
3
3
|
export declare const Fragment: unique symbol;
|
|
4
4
|
export declare class FragmentVNode extends AbstractVNode {
|
|
@@ -6,7 +6,7 @@ export declare class FragmentVNode extends AbstractVNode {
|
|
|
6
6
|
key?: string;
|
|
7
7
|
constructor(children: VNode[], key?: string);
|
|
8
8
|
mount(parent?: VNode): Node[];
|
|
9
|
-
rerender(): void;
|
|
9
|
+
rerender(operations?: PatchOperation[]): void;
|
|
10
10
|
patch(newNode: FragmentVNode): void;
|
|
11
11
|
unmount(): void;
|
|
12
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FragmentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/FragmentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"FragmentVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/FragmentVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAKhE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,eAAO,MAAM,QAAQ,eAAqB,CAAC;AAE3C,qBAAa,aAAc,SAAQ,aAAa;IAC9C,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;gBAED,QAAQ,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM;IAK3C,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE;IAW7B,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAG7C,KAAK,CAAC,OAAO,EAAE,aAAa;IAiB5B,OAAO;CAMR"}
|
|
@@ -19,11 +19,20 @@ export class FragmentVNode extends AbstractVNode {
|
|
|
19
19
|
}
|
|
20
20
|
return this.children.map((child) => child.mount(this)).flat();
|
|
21
21
|
}
|
|
22
|
-
rerender() {
|
|
23
|
-
this.parent?.rerender();
|
|
22
|
+
rerender(operations) {
|
|
23
|
+
this.parent?.rerender(operations);
|
|
24
24
|
}
|
|
25
25
|
patch(newNode) {
|
|
26
|
-
|
|
26
|
+
const { children, hasChangedStructure, operations } = this.patchChildren(newNode.children);
|
|
27
|
+
this.children = children;
|
|
28
|
+
// So we can safely pass remove/replace operations up to the parent, but add
|
|
29
|
+
// is very tricky as parent has potentially other children as well. This can be
|
|
30
|
+
// handled with some additional detection, changing it to insertBefore. This can be
|
|
31
|
+
// done by passing this vnode up to the parent
|
|
32
|
+
this.rerender(hasChangedStructure ||
|
|
33
|
+
operations.some((operation) => operation.type === "add")
|
|
34
|
+
? undefined
|
|
35
|
+
: operations);
|
|
27
36
|
}
|
|
28
37
|
unmount() {
|
|
29
38
|
this.children.forEach((child) => child.unmount());
|
package/dist/vdom/RootVNode.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractVNode } from "./AbstractVNode";
|
|
1
|
+
import { AbstractVNode, PatchOperation } from "./AbstractVNode";
|
|
2
2
|
import { VNode } from "./types";
|
|
3
3
|
import { ComponentInstance } from "./ComponentVNode";
|
|
4
4
|
export declare let currentRoot: RootVNode | undefined;
|
|
@@ -19,7 +19,7 @@ export declare class RootVNode extends AbstractVNode {
|
|
|
19
19
|
clearCurrent(): void;
|
|
20
20
|
mount(): Node | Node[];
|
|
21
21
|
patch(): void;
|
|
22
|
-
rerender(): void;
|
|
22
|
+
rerender(operations?: PatchOperation[]): void;
|
|
23
23
|
unmount(): void;
|
|
24
24
|
}
|
|
25
25
|
//# sourceMappingURL=RootVNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RootVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/RootVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"RootVNode.d.ts","sourceRoot":"","sources":["../../src/vdom/RootVNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAIrD,eAAO,IAAI,WAAW,EAAE,SAAS,GAAG,SAAS,CAAC;AAE9C,qBAAa,SAAU,SAAQ,aAAa;IAC1C,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,cAAc,EAAE,iBAAiB,EAAE,CAAM;IACzC,OAAO,CAAC,cAAc,CAGpB;IACF,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,gBAAgB,CAAyB;gBAErC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW;IAMnD,UAAU,CAAC,EAAE,EAAE,MAAM,IAAI;IAIzB,YAAY,CAAC,EAAE,EAAE,MAAM,IAAI;IAG3B,aAAa,CAAC,EAAE,EAAE,MAAM,IAAI;IAa5B,cAAc;IAOd,aAAa,CAAC,QAAQ,EAAE,iBAAiB;IAIzC,YAAY;IAIZ,YAAY;IAIZ,YAAY;IAMZ,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE;IAGtB,KAAK,IAAI,IAAI;IACb,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAS7C,OAAO,IAAI,IAAI;CAChB"}
|
package/dist/vdom/RootVNode.js
CHANGED
|
@@ -59,11 +59,13 @@ export class RootVNode extends AbstractVNode {
|
|
|
59
59
|
return this.children.map((childNode) => childNode.mount(this)).flat();
|
|
60
60
|
}
|
|
61
61
|
patch() { }
|
|
62
|
-
rerender() {
|
|
63
|
-
|
|
64
|
-
.
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
rerender(operations) {
|
|
63
|
+
if (operations) {
|
|
64
|
+
this.applyPatchOperations(this.getHTMLElement(), operations);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.syncDOMChildren();
|
|
68
|
+
}
|
|
67
69
|
this.flushLifecycle();
|
|
68
70
|
}
|
|
69
71
|
unmount() { }
|
package/package.json
CHANGED
package/dist/component.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { type VNode } from "snabbdom";
|
|
2
|
-
import { Observer } from "./observation";
|
|
3
|
-
import { ChildNode } from "./render";
|
|
4
|
-
/**
|
|
5
|
-
* Component function type. Components receive reactive props that should not be destructured.
|
|
6
|
-
*
|
|
7
|
-
* @warning **Do not destructure props!** Props are wrapped in a reactive proxy, and destructuring
|
|
8
|
-
* breaks reactivity. This is the same rule as Solid.js.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* // ❌ Bad - destructuring props loses reactivity
|
|
12
|
-
* function MyComponent({ count, name }) {
|
|
13
|
-
* return () => <div>{count} {name}</div>; // Won't update!
|
|
14
|
-
* }
|
|
15
|
-
*
|
|
16
|
-
* // ✅ Good - access props directly in render
|
|
17
|
-
* function MyComponent(props) {
|
|
18
|
-
* return () => <div>{props.count} {props.name}</div>; // Reactive!
|
|
19
|
-
* }
|
|
20
|
-
*/
|
|
21
|
-
export type Component<P> = ((props: P) => () => VNode) | (() => () => VNode);
|
|
22
|
-
export type ComponentInstance = {
|
|
23
|
-
parent: ComponentInstance | null;
|
|
24
|
-
component: Component<any>;
|
|
25
|
-
contexts: Map<object, object> | null;
|
|
26
|
-
onMounts: Array<() => void>;
|
|
27
|
-
onCleanups: Array<() => void>;
|
|
28
|
-
hostNode?: VNode;
|
|
29
|
-
observer: Observer;
|
|
30
|
-
reactiveProps: object;
|
|
31
|
-
error: unknown;
|
|
32
|
-
notifyError(error: unknown): void;
|
|
33
|
-
};
|
|
34
|
-
export declare function getCurrentComponent(): ComponentInstance;
|
|
35
|
-
export declare function onMount(cb: () => void): void;
|
|
36
|
-
export declare function onCleanup(cb: () => void): void;
|
|
37
|
-
export declare function createComponent(component: Component<any>, props: Record<string, unknown>, children: ChildNode[] | ChildNode): import("snabbdom").Thunk;
|
|
38
|
-
//# sourceMappingURL=component.d.ts.map
|
package/dist/component.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,KAAK,EAAkB,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAsB,QAAQ,EAAU,MAAM,eAAe,CAAC;AACrE,OAAO,EAAc,SAAS,EAAE,MAAM,UAAU,CAAC;AAGjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AAE7E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC5B,UAAU,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC,CAAC;AAIF,wBAAgB,mBAAmB,sBAElC;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,QAQrC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,QAQvC;AAuGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,EACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,4BAWlC"}
|