rask-ui 0.3.4 → 0.4.1

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.
Files changed (65) hide show
  1. package/README.md +266 -96
  2. package/dist/batch.d.ts +7 -0
  3. package/dist/batch.d.ts.map +1 -0
  4. package/dist/batch.js +107 -0
  5. package/dist/component.d.ts +9 -1
  6. package/dist/component.d.ts.map +1 -1
  7. package/dist/component.js +42 -12
  8. package/dist/createComputed.d.ts +4 -0
  9. package/dist/createComputed.d.ts.map +1 -0
  10. package/dist/createComputed.js +41 -0
  11. package/dist/createEffect.d.ts +2 -0
  12. package/dist/createEffect.d.ts.map +1 -0
  13. package/dist/createEffect.js +25 -0
  14. package/dist/createState.d.ts +1 -0
  15. package/dist/createState.d.ts.map +1 -1
  16. package/dist/createState.js +1 -1
  17. package/dist/index.d.ts +4 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +11 -1
  20. package/dist/observation.d.ts +82 -6
  21. package/dist/observation.d.ts.map +1 -1
  22. package/dist/observation.js +171 -21
  23. package/dist/plugin.d.ts +8 -0
  24. package/dist/plugin.d.ts.map +1 -0
  25. package/dist/plugin.js +195 -0
  26. package/dist/scheduler.d.ts +4 -0
  27. package/dist/scheduler.d.ts.map +1 -0
  28. package/dist/scheduler.js +107 -0
  29. package/package.json +1 -1
  30. package/dist/createRef.d.ts +0 -5
  31. package/dist/createRef.d.ts.map +0 -1
  32. package/dist/createRef.js +0 -7
  33. package/dist/test-setup.d.ts +0 -16
  34. package/dist/test-setup.d.ts.map +0 -1
  35. package/dist/test-setup.js +0 -40
  36. package/dist/vdom/AbstractVNode.d.ts +0 -44
  37. package/dist/vdom/AbstractVNode.d.ts.map +0 -1
  38. package/dist/vdom/AbstractVNode.js +0 -256
  39. package/dist/vdom/ComponentVNode.d.ts +0 -48
  40. package/dist/vdom/ComponentVNode.d.ts.map +0 -1
  41. package/dist/vdom/ComponentVNode.js +0 -221
  42. package/dist/vdom/ElementVNode.d.ts +0 -27
  43. package/dist/vdom/ElementVNode.d.ts.map +0 -1
  44. package/dist/vdom/ElementVNode.js +0 -220
  45. package/dist/vdom/FragmentVNode.d.ts +0 -13
  46. package/dist/vdom/FragmentVNode.d.ts.map +0 -1
  47. package/dist/vdom/FragmentVNode.js +0 -49
  48. package/dist/vdom/RootVNode.d.ts +0 -25
  49. package/dist/vdom/RootVNode.d.ts.map +0 -1
  50. package/dist/vdom/RootVNode.js +0 -79
  51. package/dist/vdom/TextVNode.d.ts +0 -11
  52. package/dist/vdom/TextVNode.d.ts.map +0 -1
  53. package/dist/vdom/TextVNode.js +0 -35
  54. package/dist/vdom/dom-utils.d.ts +0 -14
  55. package/dist/vdom/dom-utils.d.ts.map +0 -1
  56. package/dist/vdom/dom-utils.js +0 -103
  57. package/dist/vdom/index.d.ts +0 -10
  58. package/dist/vdom/index.d.ts.map +0 -1
  59. package/dist/vdom/index.js +0 -26
  60. package/dist/vdom/types.d.ts +0 -20
  61. package/dist/vdom/types.d.ts.map +0 -1
  62. package/dist/vdom/types.js +0 -1
  63. package/dist/vdom/utils.d.ts +0 -6
  64. package/dist/vdom/utils.d.ts.map +0 -1
  65. package/dist/vdom/utils.js +0 -63
@@ -1,256 +0,0 @@
1
- import { elementsToFragment } from "./dom-utils";
2
- export class AbstractVNode {
3
- key;
4
- parent;
5
- root;
6
- elm;
7
- children;
8
- getHTMLElement() {
9
- if (!this.elm || !(this.elm instanceof HTMLElement)) {
10
- throw new Error("This VNode does not have an HTMLElement");
11
- }
12
- return this.elm;
13
- }
14
- /**
15
- * A VNode can represent multiple elements (fragment of component)
16
- */
17
- getElements() {
18
- if (this.elm) {
19
- return [this.elm];
20
- }
21
- if (!this.children) {
22
- throw new Error("This VNode has no element or children");
23
- }
24
- // Optimized: avoid intermediate arrays from map+flat
25
- const result = [];
26
- for (let i = 0; i < this.children.length; i++) {
27
- const childElms = this.children[i].getElements();
28
- for (let j = 0; j < childElms.length; j++) {
29
- result.push(childElms[j]);
30
- }
31
- }
32
- return result;
33
- }
34
- getParentElement() {
35
- let parent = this.parent;
36
- // This VNode might not have an element, but relies
37
- // on a parent for it. So we make sure that we get
38
- // the actual parent of the element related to this VNode
39
- while (parent) {
40
- if (parent.elm instanceof HTMLElement) {
41
- // This will always be an HTMLElement as text nodes has no children
42
- return parent.elm;
43
- }
44
- parent = parent.parent;
45
- }
46
- throw new Error("There is no parent element for this VNode");
47
- }
48
- canPatch(oldNode, newNode) {
49
- // Must be same constructor type
50
- if (oldNode.constructor !== newNode.constructor) {
51
- return false;
52
- }
53
- // For ElementVNodes, must have same tag
54
- if ("tag" in oldNode && "tag" in newNode) {
55
- return oldNode.tag === newNode.tag;
56
- }
57
- // For ComponentVNodes, must have same component function
58
- if ("component" in oldNode && "component" in newNode) {
59
- return oldNode.component === newNode.component;
60
- }
61
- // TextVNodes and FragmentVNodes can always patch
62
- return true;
63
- }
64
- patchChildren(newChildren) {
65
- const prevChildren = this.children;
66
- if (newChildren.length === 0 && prevChildren.length === 0) {
67
- return { children: [], hasChangedStructure: false };
68
- }
69
- // When there are only new children, we just mount them
70
- if (prevChildren.length === 0) {
71
- newChildren.forEach((child) => child.mount(this));
72
- return {
73
- children: newChildren,
74
- hasChangedStructure: true,
75
- };
76
- }
77
- // If we want to remove all children, we just unmount the previous ones
78
- if (!newChildren.length && prevChildren.length) {
79
- prevChildren.forEach((child) => child.unmount());
80
- return { children: [], hasChangedStructure: true, operations: [] };
81
- }
82
- const oldKeys = {};
83
- prevChildren.forEach((prevChild, index) => {
84
- oldKeys[prevChild.key || index] = {
85
- vnode: prevChild,
86
- index,
87
- };
88
- });
89
- // Build result array in the NEW order
90
- const result = [];
91
- const operations = [];
92
- // Track indices of reused nodes in their original order
93
- const reusedOldIndices = [];
94
- // Track which result positions contain new nodes (not reused/replaced)
95
- const isNewNode = [];
96
- let forceStructuralChange = false;
97
- newChildren.forEach((newChild, index) => {
98
- const key = newChild.key || index;
99
- const prevChild = oldKeys[key];
100
- if (!prevChild) {
101
- // New child - mount and add to result
102
- const elm = newChild.mount(this);
103
- result.push(newChild);
104
- isNewNode.push(true);
105
- operations.push({ type: "add", elm });
106
- }
107
- else if (prevChild?.vnode === newChild) {
108
- // Same instance - no patching needed, just reuse
109
- result.push(prevChild.vnode);
110
- isNewNode.push(false);
111
- reusedOldIndices.push(prevChild.index);
112
- delete oldKeys[key];
113
- }
114
- else if (this.canPatch(prevChild.vnode, newChild)) {
115
- // Compatible types - patch and reuse old VNode
116
- prevChild.vnode.patch(newChild);
117
- result.push(prevChild.vnode);
118
- isNewNode.push(false);
119
- reusedOldIndices.push(prevChild.index);
120
- delete oldKeys[key];
121
- }
122
- else {
123
- // Incompatible types - replace completely
124
- const newElm = newChild.mount(this);
125
- prevChild.vnode.unmount();
126
- result.push(newChild);
127
- isNewNode.push(false); // Replacement, not an insertion
128
- delete oldKeys[key];
129
- const oldElm = prevChild.vnode.getElements();
130
- // We need to fall back to structural change when the old node does
131
- // not have any elements. This can happen when a component returns null,
132
- // throws an error etc.
133
- if (!oldElm.length) {
134
- forceStructuralChange = true;
135
- return;
136
- }
137
- operations.push({
138
- type: "replace",
139
- oldElm,
140
- newElm,
141
- });
142
- }
143
- });
144
- // Unmount any old children that weren't reused
145
- for (const key in oldKeys) {
146
- oldKeys[key].vnode.unmount();
147
- operations.push({
148
- type: "remove",
149
- elm: oldKeys[key].vnode.getElements(),
150
- });
151
- }
152
- // Detect structural changes:
153
- // 1. Reordering: reused nodes are not in their original relative order
154
- // 2. Insertion in middle: new nodes inserted before existing nodes
155
- let hasReordering = false;
156
- let hasInsertionInMiddle = false;
157
- if (!forceStructuralChange) {
158
- for (let i = 1; i < reusedOldIndices.length; i++) {
159
- if (reusedOldIndices[i] < reusedOldIndices[i - 1]) {
160
- hasReordering = true;
161
- break;
162
- }
163
- }
164
- }
165
- if (!hasReordering) {
166
- // Find the last position that contains a reused/replaced node
167
- let lastReusedResultIndex = -1;
168
- for (let i = result.length - 1; i >= 0; i--) {
169
- if (!isNewNode[i]) {
170
- lastReusedResultIndex = i;
171
- break;
172
- }
173
- }
174
- // Check if any new nodes were inserted before the last reused/replaced node
175
- if (lastReusedResultIndex >= 0) {
176
- for (let i = 0; i < lastReusedResultIndex; i++) {
177
- if (isNewNode[i]) {
178
- hasInsertionInMiddle = true;
179
- break;
180
- }
181
- }
182
- }
183
- }
184
- const hasChangedStructure = forceStructuralChange || hasReordering || hasInsertionInMiddle;
185
- if (hasChangedStructure) {
186
- operations.length = 0;
187
- }
188
- return { children: result, hasChangedStructure, operations };
189
- }
190
- applyPatchOperations(target, operations) {
191
- operations.forEach((operation) => {
192
- switch (operation.type) {
193
- case "add": {
194
- target.appendChild(elementsToFragment(operation.elm));
195
- break;
196
- }
197
- case "remove": {
198
- if (Array.isArray(operation.elm)) {
199
- const range = new Range();
200
- range.setStartBefore(operation.elm[0]);
201
- range.setEndAfter(operation.elm[operation.elm.length - 1]);
202
- range.deleteContents();
203
- }
204
- else {
205
- target.removeChild(operation.elm);
206
- }
207
- break;
208
- }
209
- case "replace": {
210
- if (Array.isArray(operation.oldElm)) {
211
- const range = new Range();
212
- range.setStartBefore(operation.oldElm[0]);
213
- range.setEndAfter(operation.oldElm[operation.oldElm.length - 1]);
214
- range.deleteContents();
215
- range.insertNode(elementsToFragment(operation.newElm));
216
- }
217
- else {
218
- target.replaceChild(elementsToFragment(operation.newElm), operation.oldElm);
219
- }
220
- break;
221
- }
222
- }
223
- });
224
- }
225
- /**
226
- * Intelligently sync DOM to match children VNode order.
227
- * Only performs DOM operations when elements are out of position.
228
- * This is used by both patch() and rerender() to efficiently update children.
229
- */
230
- syncDOMChildren() {
231
- if (!this.children) {
232
- return;
233
- }
234
- const elm = this.elm;
235
- let currentDomChild = elm.firstChild;
236
- for (const child of this.children) {
237
- const childNodes = child.getElements();
238
- for (const node of childNodes) {
239
- if (currentDomChild === node) {
240
- // Already in correct position, advance pointer
241
- currentDomChild = currentDomChild.nextSibling;
242
- }
243
- else {
244
- // Insert (or move if it exists elsewhere in DOM)
245
- elm.insertBefore(node, currentDomChild);
246
- }
247
- }
248
- }
249
- // Remove any leftover nodes (shouldn't happen if unmount works correctly)
250
- while (currentDomChild) {
251
- const next = currentDomChild.nextSibling;
252
- elm.removeChild(currentDomChild);
253
- currentDomChild = next;
254
- }
255
- }
256
- }
@@ -1,48 +0,0 @@
1
- import { Observer } from "../observation";
2
- import { AbstractVNode, PatchOperation } from "./AbstractVNode";
3
- import { Props, VNode } from "./types";
4
- export type ComponentChild = VNode | string | null | number | undefined | boolean;
5
- export type ComponentChildren = ComponentChild | ComponentChild[];
6
- /**
7
- * Component function type. Components receive reactive props that should not be destructured.
8
- *
9
- * @warning **Do not destructure props!** Props are wrapped in a reactive proxy, and destructuring
10
- * breaks reactivity. This is the same rule as Solid.js.
11
- *
12
- * @example
13
- * // ❌ Bad - destructuring props loses reactivity
14
- * function MyComponent({ count, name }) {
15
- * return () => <div>{count} {name}</div>; // Won't update!
16
- * }
17
- *
18
- * // ✅ Good - access props directly in render
19
- * function MyComponent(props) {
20
- * return () => <div>{props.count} {props.name}</div>; // Reactive!
21
- * }
22
- */
23
- export type Component<P extends Props> = ((props: P) => () => ComponentChildren) | (() => () => ComponentChildren);
24
- export type ComponentInstance = {
25
- parent?: VNode;
26
- contexts: Map<object, unknown> | null;
27
- onMounts: Array<() => void>;
28
- onCleanups: Array<() => void>;
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 class ComponentVNode extends AbstractVNode {
38
- component: Component<any>;
39
- props: Props;
40
- children: VNode[];
41
- instance?: ComponentInstance;
42
- constructor(component: Component<any>, props: Props, children: VNode[], key?: string);
43
- rerender(operations?: PatchOperation[]): void;
44
- mount(parent?: VNode): Node[];
45
- patch(newNode: ComponentVNode): void;
46
- unmount(): void;
47
- }
48
- //# sourceMappingURL=ComponentVNode.d.ts.map
@@ -1 +0,0 @@
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;AAIvC,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;IA6I7B,KAAK,CAAC,OAAO,EAAE,cAAc;IAW7B,OAAO;CAcR"}
@@ -1,221 +0,0 @@
1
- import { getCurrentObserver, Observer, Signal } from "../observation";
2
- import { AbstractVNode } from "./AbstractVNode";
3
- import { FragmentVNode } from "./FragmentVNode";
4
- import { RootVNode } from "./RootVNode";
5
- import { normalizeChildren } from "./utils";
6
- import { flattenNodes } from "./dom-utils";
7
- import { currentRoot } from "./RootVNode";
8
- export function getCurrentComponent() {
9
- if (!currentRoot) {
10
- throw new Error("No current root");
11
- }
12
- const currentComponent = currentRoot.componentStack[0];
13
- if (!currentComponent) {
14
- throw new Error("No current component");
15
- }
16
- return currentComponent;
17
- }
18
- export function onMount(cb) {
19
- if (!currentRoot) {
20
- throw new Error("Only use onCleanup in component setup");
21
- }
22
- const current = currentRoot.componentStack[0];
23
- if (!current) {
24
- throw new Error("Only use onCleanup in component setup");
25
- }
26
- current.onMounts.push(cb);
27
- }
28
- export function onCleanup(cb) {
29
- if (!currentRoot) {
30
- throw new Error("Only use onCleanup in component setup");
31
- }
32
- const current = currentRoot.componentStack[0];
33
- if (!current) {
34
- throw new Error("Only use onCleanup in component setup");
35
- }
36
- current.onCleanups.push(cb);
37
- }
38
- export class ComponentVNode extends AbstractVNode {
39
- component;
40
- props;
41
- // These are the actual current children returned by component
42
- children = [];
43
- instance;
44
- constructor(component, props, children, key) {
45
- super();
46
- this.component = component;
47
- this.props = {
48
- ...props,
49
- children,
50
- };
51
- this.children = [];
52
- this.key = key;
53
- }
54
- rerender(operations) {
55
- this.parent?.rerender(operations);
56
- }
57
- mount(parent) {
58
- this.parent = parent;
59
- if (parent instanceof RootVNode) {
60
- this.root = parent;
61
- }
62
- else {
63
- this.root = parent?.root;
64
- }
65
- let errorSignal;
66
- let error;
67
- const executeRender = () => {
68
- const stopObserving = instance.observer.observe();
69
- let renderResult = new FragmentVNode([]);
70
- try {
71
- renderResult = render();
72
- }
73
- catch (error) {
74
- instance.notifyError(error);
75
- }
76
- finally {
77
- stopObserving();
78
- }
79
- return normalizeChildren(renderResult);
80
- };
81
- let isObserverQueued = false;
82
- const instance = (this.instance = {
83
- parent,
84
- contexts: null,
85
- onCleanups: [],
86
- onMounts: [],
87
- observer: new Observer(() => {
88
- if (isObserverQueued) {
89
- return;
90
- }
91
- isObserverQueued = true;
92
- this.root?.queueObserver(() => {
93
- if (instance.observer.isDisposed) {
94
- return;
95
- }
96
- isObserverQueued = false;
97
- this.root?.setAsCurrent();
98
- const newChildren = executeRender();
99
- const { children, hasChangedStructure, operations } = this.patchChildren(newChildren);
100
- this.children = children;
101
- // So if a fragment is returned where we add new elements we can not safely
102
- // add them yet, check Fragment for a potential later optimization
103
- const hasAddOperation = operations?.some((operation) => operation.type === "add");
104
- if (hasChangedStructure || hasAddOperation) {
105
- this.parent?.rerender();
106
- }
107
- else if (operations?.length) {
108
- this.parent?.rerender(operations);
109
- }
110
- this.root?.clearCurrent();
111
- });
112
- }),
113
- reactiveProps: createReactiveProps(this.props),
114
- get error() {
115
- if (!errorSignal) {
116
- errorSignal = new Signal();
117
- }
118
- const observer = getCurrentObserver();
119
- if (observer) {
120
- observer.subscribeSignal(errorSignal);
121
- }
122
- return error;
123
- },
124
- notifyError(childError) {
125
- if (errorSignal) {
126
- error = childError;
127
- errorSignal.notify();
128
- }
129
- else if (instance.parent) {
130
- let parent = instance.parent;
131
- while (parent && !(parent instanceof ComponentVNode)) {
132
- parent = parent?.parent;
133
- }
134
- // Only call notifyError if we found a ComponentVNode parent
135
- if (parent instanceof ComponentVNode) {
136
- parent.instance?.notifyError(childError);
137
- }
138
- // Otherwise there's no ErrorBoundary, so do nothing
139
- }
140
- else {
141
- throw childError;
142
- }
143
- },
144
- });
145
- this.root?.setAsCurrent();
146
- this.root?.pushComponent(instance);
147
- const render = this.component(instance.reactiveProps);
148
- // Validate that render is a function
149
- if (typeof render !== "function") {
150
- const initError = new Error(`Component must return a render function, but got ${render instanceof AbstractVNode ? "JSX" : typeof render}. ` +
151
- `Components should return a function that returns JSX: \`return () => <div>...</div>\``);
152
- console.error("Error initializing component:", initError);
153
- error = initError;
154
- instance.notifyError(initError);
155
- this.root?.popComponent();
156
- this.root?.clearCurrent();
157
- return [];
158
- }
159
- this.children = executeRender();
160
- this.root?.popComponent();
161
- this.root?.clearCurrent();
162
- // Optimized: avoid intermediate arrays from map+flat
163
- const childResults = [];
164
- for (let i = 0; i < this.children.length; i++) {
165
- childResults.push(this.children[i].mount(this));
166
- }
167
- const childElements = flattenNodes(childResults);
168
- // Queue onMount callbacks after children are mounted
169
- // This ensures refs and other child lifecycle hooks run before parent onMount
170
- instance.onMounts.forEach((cb) => {
171
- this.root?.queueMount(cb);
172
- });
173
- return childElements;
174
- }
175
- patch(newNode) {
176
- this.root?.setAsCurrent();
177
- this.root?.pushComponent(this.instance);
178
- for (const prop in newNode.props) {
179
- this.instance.reactiveProps[prop] = newNode.props[prop];
180
- }
181
- this.root?.popComponent();
182
- this.root?.clearCurrent();
183
- }
184
- unmount() {
185
- this.instance.observer.dispose();
186
- this.children.forEach((child) => child.unmount());
187
- this.root?.queueUnmount(() => {
188
- this.instance.onCleanups.forEach((cb) => {
189
- try {
190
- cb();
191
- }
192
- catch (error) {
193
- // Log error but continue executing remaining cleanups
194
- console.error("Error during cleanup:", error);
195
- }
196
- });
197
- });
198
- }
199
- }
200
- function createReactiveProps(props) {
201
- const reactiveProps = {};
202
- for (const prop in props) {
203
- const signal = new Signal();
204
- Object.defineProperty(reactiveProps, prop, {
205
- get() {
206
- const observer = getCurrentObserver();
207
- if (observer) {
208
- observer.subscribeSignal(signal);
209
- }
210
- return props[prop];
211
- },
212
- set(value) {
213
- if (props[prop] !== value) {
214
- props[prop] = value;
215
- signal.notify();
216
- }
217
- },
218
- });
219
- }
220
- return reactiveProps;
221
- }
@@ -1,27 +0,0 @@
1
- import { AbstractVNode, PatchOperation } from "./AbstractVNode";
2
- import { Props, VNode, VFlags } from "./types";
3
- export declare class ElementVNode extends AbstractVNode {
4
- tag: string;
5
- props: Props;
6
- children: VNode[];
7
- key?: string;
8
- flags: VFlags;
9
- private ref?;
10
- private eventListeners?;
11
- constructor(tag: string, { ref, ...props }: Props, children: VNode[], key?: string);
12
- private computeFlags;
13
- rerender(operations?: PatchOperation[]): void;
14
- mount(parent?: VNode): Node;
15
- /**
16
- * An ELEMENT patch goes through three operations
17
- * - Patch or replace the element
18
- * - Patch the children
19
- */
20
- patch(newNode: ElementVNode): void;
21
- unmount(): void;
22
- private setProp;
23
- private patchProps;
24
- private patchStyle;
25
- private addEventListener;
26
- }
27
- //# sourceMappingURL=ElementVNode.d.ts.map
@@ -1 +0,0 @@
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,EAAE,MAAM,SAAS,CAAC;AAU/C,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,KAAK,EAAE,MAAM,CAAC;IACd,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;IAad,OAAO,CAAC,YAAY;IAwBpB,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;IAwB3B,OAAO;IAYP,OAAO,CAAC,OAAO,CAoCb;IACF,OAAO,CAAC,UAAU;IAsClB,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,gBAAgB;CAgBzB"}