@simpreact/simpreact 0.0.7 → 0.0.9

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 (81) hide show
  1. package/compat/context.js +3 -3
  2. package/compat/core.js +105 -18
  3. package/compat/dom.js +5 -5
  4. package/compat/hooks.js +18 -3
  5. package/compat/index.d.ts +109 -45
  6. package/compat/jsx-runtime.js +4 -4
  7. package/compat/renderRuntime.js +47 -12
  8. package/component/index.d.ts +6 -7
  9. package/component/index.js +96 -94
  10. package/context/index.d.ts +5 -5
  11. package/context/index.js +27 -17
  12. package/core/createElement.js +14 -17
  13. package/core/flags.js +31 -0
  14. package/core/hostOperations.js +5 -13
  15. package/core/index.d.ts +48 -11
  16. package/core/index.js +4 -2
  17. package/core/internal.d.ts +136 -16
  18. package/core/internal.js +8 -16
  19. package/core/lifecycleEventBus.js +35 -16
  20. package/core/memo.js +4 -1
  21. package/core/mounting.js +70 -150
  22. package/core/mountingChildren.js +11 -29
  23. package/core/patching.js +122 -181
  24. package/core/patchingChildren.js +74 -145
  25. package/core/portal.js +1 -1
  26. package/core/processStack.js +115 -45
  27. package/core/ref.js +1 -0
  28. package/core/rerender.js +20 -22
  29. package/core/runtime.js +10 -2
  30. package/core/unmounting.js +41 -49
  31. package/core/unmountingChildren.js +9 -12
  32. package/core/utils.js +38 -16
  33. package/dom/attach-element-to-dom.js +16 -8
  34. package/dom/events.js +11 -15
  35. package/dom/index.d.ts +6 -5
  36. package/dom/props/attrMaps.js +90 -0
  37. package/dom/props/controlled/select.js +8 -10
  38. package/dom/props/props.js +13 -14
  39. package/hooks/index.d.ts +15 -10
  40. package/hooks/index.js +107 -84
  41. package/package.json +10 -5
  42. package/shared/index.d.ts +10 -6
  43. package/compat/context.d.ts +0 -8
  44. package/compat/core.d.ts +0 -47
  45. package/compat/dom.d.ts +0 -10
  46. package/compat/hooks.d.ts +0 -27
  47. package/compat/jsx-runtime.d.ts +0 -10
  48. package/compat/renderRuntime.d.ts +0 -6
  49. package/core/createElement.d.ts +0 -39
  50. package/core/fragment.d.ts +0 -5
  51. package/core/hostAdapter.d.ts +0 -23
  52. package/core/hostOperations.d.ts +0 -5
  53. package/core/lifecycleEventBus.d.ts +0 -39
  54. package/core/memo.d.ts +0 -8
  55. package/core/mounting.d.ts +0 -7
  56. package/core/mountingChildren.d.ts +0 -4
  57. package/core/patching.d.ts +0 -8
  58. package/core/patchingChildren.d.ts +0 -6
  59. package/core/portal.d.ts +0 -2
  60. package/core/processStack.d.ts +0 -106
  61. package/core/ref.d.ts +0 -18
  62. package/core/rerender.d.ts +0 -4
  63. package/core/runtime.d.ts +0 -17
  64. package/core/unmounting.d.ts +0 -7
  65. package/core/unmountingChildren.d.ts +0 -4
  66. package/core/utils.d.ts +0 -11
  67. package/dom/attach-element-to-dom.d.ts +0 -5
  68. package/dom/domAdapter.d.ts +0 -3
  69. package/dom/events.d.ts +0 -27
  70. package/dom/namespace.d.ts +0 -2
  71. package/dom/props/controlled/index.d.ts +0 -7
  72. package/dom/props/controlled/input.d.ts +0 -7
  73. package/dom/props/controlled/select.d.ts +0 -6
  74. package/dom/props/controlled/textarea.d.ts +0 -6
  75. package/dom/props/dangerInnerHTML.d.ts +0 -7
  76. package/dom/props/index.d.ts +0 -1
  77. package/dom/props/props.d.ts +0 -5
  78. package/dom/props/style.d.ts +0 -1
  79. package/dom/render.d.ts +0 -8
  80. package/shared/lang.d.ts +0 -3
  81. package/shared/utils.d.ts +0 -5
@@ -1,30 +1,14 @@
1
1
  import { SIMP_ELEMENT_CHILD_FLAG_ELEMENT, SIMP_ELEMENT_CHILD_FLAG_LIST, SIMP_ELEMENT_CHILD_FLAG_TEXT, } from './createElement.js';
2
- import { _pushHostOperationPlaceElement } from './hostOperations.js';
3
- import { _pushMountEnterFrame } from './mounting.js';
4
- import { _pushMountChildrenFrame } from './mountingChildren.js';
5
- import { _pushPatchEnterFrame } from './patching.js';
6
- import { PATCH_CHILDREN, PATCH_KEYED_CHILDREN, } from './processStack.js';
7
- import { _pushUnmountEnterFrame } from './unmounting.js';
8
- import { _pushUnmountChildrenFrame } from './unmountingChildren.js';
9
- import { _clearElementHostReference, getLongestIncreasingSubsequenceIndexes, isHostLike } from './utils.js';
10
- export function _pushPatchChildrenFrame(parent, meta) {
11
- meta.renderRuntime.renderStack.push({
12
- node: parent,
13
- kind: PATCH_CHILDREN,
14
- meta,
15
- });
16
- }
17
- export function _pushPatchKeyedChildrenFrame(element, meta) {
18
- meta.renderRuntime.renderStack.push({
19
- node: element,
20
- kind: PATCH_KEYED_CHILDREN,
21
- meta,
22
- });
23
- }
24
- export function _patchChildren(frame) {
25
- const parentElement = frame.node;
26
- const { renderRuntime, parentReference, context, hostNamespace, nextChildren, prevChildren, prevParentChildFlag, nextParentChildFlag, prevParentElement, } = frame.meta;
27
- const subtreeRightBoundary = isHostLike(parentElement.flag) ? null : frame.meta.subtreeRightBoundary;
2
+ import { pushHostOperationPlaceElement } from './hostOperations.js';
3
+ import { pushMountEnterFrame } from './mounting.js';
4
+ import { pushMountChildrenFrame } from './mountingChildren.js';
5
+ import { pushPatchEnterFrame } from './patching.js';
6
+ import { pushUnmountEnterFrame } from './unmounting.js';
7
+ import { pushUnmountChildrenFrame } from './unmountingChildren.js';
8
+ import { clearElementHostReference, getLongestIncreasingSubsequenceIndexes, isHostLike } from './utils.js';
9
+ export function patchChildren(parentElement, meta) {
10
+ const { renderRuntime, parentReference, context, hostNamespace, nextChildren, prevChildren, prevParentChildFlag, nextParentChildFlag, prevParentElement, } = meta;
11
+ const subtreeRightBoundary = isHostLike(parentElement.flag) ? null : meta.subtreeRightBoundary;
28
12
  switch (prevParentChildFlag) {
29
13
  case SIMP_ELEMENT_CHILD_FLAG_LIST: {
30
14
  switch (nextParentChildFlag) {
@@ -32,7 +16,7 @@ export function _patchChildren(frame) {
32
16
  for (const child of nextChildren) {
33
17
  child.parent = parentElement;
34
18
  }
35
- _pushPatchKeyedChildrenFrame(parentElement, {
19
+ patchKeyedChildren(parentElement, {
36
20
  prevChildren,
37
21
  nextChildren,
38
22
  subtreeRightBoundary,
@@ -48,7 +32,7 @@ export function _patchChildren(frame) {
48
32
  }
49
33
  case SIMP_ELEMENT_CHILD_FLAG_ELEMENT: {
50
34
  nextChildren.parent = parentElement;
51
- _pushPatchKeyedChildrenFrame(parentElement, {
35
+ patchKeyedChildren(parentElement, {
52
36
  prevChildren,
53
37
  nextChildren,
54
38
  subtreeRightBoundary,
@@ -63,12 +47,12 @@ export function _patchChildren(frame) {
63
47
  break;
64
48
  }
65
49
  case SIMP_ELEMENT_CHILD_FLAG_TEXT: {
66
- _pushUnmountChildrenFrame(prevParentElement, frame.meta);
50
+ pushUnmountChildrenFrame(prevParentElement, renderRuntime);
67
51
  renderRuntime.hostAdapter.setTextContent(parentReference, parentElement.props?.children);
68
52
  break;
69
53
  }
70
54
  default: {
71
- _pushUnmountChildrenFrame(prevParentElement, frame.meta);
55
+ pushUnmountChildrenFrame(prevParentElement, renderRuntime);
72
56
  renderRuntime.hostAdapter.clearNode(parentReference);
73
57
  }
74
58
  }
@@ -80,7 +64,7 @@ export function _patchChildren(frame) {
80
64
  for (const child of nextChildren) {
81
65
  child.parent = parentElement;
82
66
  }
83
- _pushPatchKeyedChildrenFrame(parentElement, {
67
+ patchKeyedChildren(parentElement, {
84
68
  prevChildren,
85
69
  nextChildren,
86
70
  subtreeRightBoundary,
@@ -96,24 +80,17 @@ export function _patchChildren(frame) {
96
80
  }
97
81
  case SIMP_ELEMENT_CHILD_FLAG_ELEMENT: {
98
82
  nextChildren.parent = parentElement;
99
- _pushPatchEnterFrame(nextChildren, {
100
- prevElement: prevChildren,
101
- parentReference,
102
- renderRuntime,
103
- subtreeRightBoundary: subtreeRightBoundary,
104
- context,
105
- hostNamespace,
106
- });
83
+ pushPatchEnterFrame(nextChildren, renderRuntime, prevChildren, parentReference, subtreeRightBoundary, context, hostNamespace);
107
84
  break;
108
85
  }
109
86
  case SIMP_ELEMENT_CHILD_FLAG_TEXT: {
110
- _pushUnmountChildrenFrame(prevParentElement, frame.meta);
87
+ pushUnmountChildrenFrame(prevParentElement, renderRuntime);
111
88
  renderRuntime.hostAdapter.setTextContent(parentReference, parentElement.props?.children);
112
89
  break;
113
90
  }
114
91
  default: {
115
- _clearElementHostReference(prevChildren, parentReference, renderRuntime);
116
- _pushUnmountEnterFrame(prevChildren, frame.meta);
92
+ clearElementHostReference(prevChildren, parentReference, renderRuntime);
93
+ pushUnmountEnterFrame(prevChildren, renderRuntime);
117
94
  }
118
95
  }
119
96
  break;
@@ -122,34 +99,20 @@ export function _patchChildren(frame) {
122
99
  switch (nextParentChildFlag) {
123
100
  case SIMP_ELEMENT_CHILD_FLAG_LIST: {
124
101
  renderRuntime.hostAdapter.clearNode(parentReference);
125
- _pushMountChildrenFrame(parentElement, {
126
- children: parentElement.children,
127
- context,
128
- hostNamespace,
129
- renderRuntime,
130
- subtreeRightBoundary,
131
- parentReference,
132
- });
102
+ pushMountChildrenFrame(parentElement, renderRuntime, parentElement.children, parentReference, subtreeRightBoundary, context, hostNamespace);
133
103
  break;
134
104
  }
135
105
  case SIMP_ELEMENT_CHILD_FLAG_ELEMENT: {
136
106
  renderRuntime.hostAdapter.clearNode(parentReference);
137
107
  nextChildren.parent = parentElement;
138
- _pushMountEnterFrame(nextChildren, {
139
- parentReference,
140
- subtreeRightBoundary: subtreeRightBoundary,
141
- context,
142
- hostNamespace,
143
- renderRuntime,
144
- placeHolderElement: null,
145
- });
108
+ pushMountEnterFrame(nextChildren, renderRuntime, parentReference, subtreeRightBoundary, context, hostNamespace, null);
146
109
  break;
147
110
  }
148
111
  case SIMP_ELEMENT_CHILD_FLAG_TEXT: {
149
- const prevChildren = prevParentElement.props?.children;
150
- const nextChildren = parentElement.props?.children;
151
- if (prevChildren !== nextChildren) {
152
- renderRuntime.hostAdapter.setTextContent(parentReference, nextChildren, true);
112
+ const prevText = prevParentElement.props?.children;
113
+ const nextText = parentElement.props?.children;
114
+ if (prevText !== nextText) {
115
+ renderRuntime.hostAdapter.setTextContent(parentReference, nextText, true);
153
116
  }
154
117
  }
155
118
  }
@@ -158,26 +121,12 @@ export function _patchChildren(frame) {
158
121
  default: {
159
122
  switch (nextParentChildFlag) {
160
123
  case SIMP_ELEMENT_CHILD_FLAG_LIST: {
161
- _pushMountChildrenFrame(parentElement, {
162
- parentReference,
163
- subtreeRightBoundary,
164
- context,
165
- hostNamespace,
166
- renderRuntime,
167
- children: parentElement.children,
168
- });
124
+ pushMountChildrenFrame(parentElement, renderRuntime, parentElement.children, parentReference, subtreeRightBoundary, context, hostNamespace);
169
125
  break;
170
126
  }
171
127
  case SIMP_ELEMENT_CHILD_FLAG_ELEMENT: {
172
128
  nextChildren.parent = parentElement;
173
- _pushMountEnterFrame(nextChildren, {
174
- parentReference,
175
- context,
176
- hostNamespace,
177
- renderRuntime,
178
- placeHolderElement: null,
179
- subtreeRightBoundary: subtreeRightBoundary,
180
- });
129
+ pushMountEnterFrame(nextChildren, renderRuntime, parentReference, subtreeRightBoundary, context, hostNamespace, null);
181
130
  break;
182
131
  }
183
132
  case SIMP_ELEMENT_CHILD_FLAG_TEXT: {
@@ -187,19 +136,12 @@ export function _patchChildren(frame) {
187
136
  }
188
137
  }
189
138
  }
190
- export function _patchKeyedChildren(frame) {
191
- const { parentReference, subtreeRightBoundary, context, hostNamespace, renderRuntime } = frame.meta;
192
- const nextChildren = frame.meta.nextChildren;
193
- const prevChildren = frame.meta.prevChildren;
139
+ export function patchKeyedChildren(parentElement, meta) {
140
+ const { parentReference, subtreeRightBoundary, context, hostNamespace, renderRuntime } = meta;
141
+ const nextChildren = meta.nextChildren;
142
+ const prevChildren = meta.prevChildren;
194
143
  const nextLen = Array.isArray(nextChildren) ? nextChildren.length : 1;
195
144
  const prevLen = Array.isArray(prevChildren) ? prevChildren.length : 1;
196
- const base = {
197
- parentReference,
198
- renderRuntime,
199
- context,
200
- hostNamespace,
201
- placeHolderElement: null,
202
- };
203
145
  const getRightSibling = (child) => {
204
146
  return child.index + 1 < nextLen ? getChild(nextChildren, child.index + 1) : subtreeRightBoundary;
205
147
  };
@@ -223,11 +165,7 @@ export function _patchKeyedChildren(frame) {
223
165
  for (let i = 0; i < nextStart; i++) {
224
166
  const nextChild = getChild(nextChildren, i);
225
167
  const prevChild = getChild(prevChildren, nextChild.index);
226
- _pushPatchEnterFrame(nextChild, {
227
- ...base,
228
- prevElement: prevChild,
229
- subtreeRightBoundary: getRightSibling(nextChild),
230
- });
168
+ pushPatchEnterFrame(nextChild, renderRuntime, prevChild, parentReference, getRightSibling(nextChild), context, hostNamespace);
231
169
  }
232
170
  };
233
171
  const pushSuffixPatches = () => {
@@ -235,19 +173,15 @@ export function _patchKeyedChildren(frame) {
235
173
  for (let i = nextEnd + 1; i < nextLen; i++) {
236
174
  const nextChild = getChild(nextChildren, i);
237
175
  const prevChild = getChild(prevChildren, nextChild.index - delta);
238
- _pushPatchEnterFrame(nextChild, {
239
- ...base,
240
- prevElement: prevChild,
241
- subtreeRightBoundary: getRightSibling(nextChild),
242
- });
176
+ pushPatchEnterFrame(nextChild, renderRuntime, prevChild, parentReference, getRightSibling(nextChild), context, hostNamespace);
243
177
  }
244
178
  };
245
179
  if (nextStart > nextEnd) {
246
180
  pushPrefixPatches();
247
181
  for (let i = prevStart; i <= prevEnd; i++) {
248
182
  const child = getChild(prevChildren, i);
249
- _clearElementHostReference(child, parentReference, renderRuntime);
250
- _pushUnmountEnterFrame(child, frame.meta);
183
+ clearElementHostReference(child, parentReference, renderRuntime);
184
+ pushUnmountEnterFrame(child, renderRuntime);
251
185
  }
252
186
  pushSuffixPatches();
253
187
  return;
@@ -256,32 +190,31 @@ export function _patchKeyedChildren(frame) {
256
190
  pushPrefixPatches();
257
191
  for (let i = nextStart; i <= nextEnd; i++) {
258
192
  const nextChild = getChild(nextChildren, i);
259
- _pushMountEnterFrame(nextChild, {
260
- ...base,
261
- subtreeRightBoundary: getRightSibling(nextChild),
262
- });
193
+ pushMountEnterFrame(nextChild, renderRuntime, parentReference, getRightSibling(nextChild), context, hostNamespace, null);
263
194
  }
264
195
  pushSuffixPatches();
265
196
  return;
266
197
  }
267
- const keyToPrevChild = new Map();
198
+ const keyToPrevChild = Object.create(null);
268
199
  for (let i = prevStart; i <= prevEnd; i++) {
269
200
  const prevChild = getChild(prevChildren, i);
270
201
  const key = prevChild.key;
271
202
  if (key != null) {
272
- keyToPrevChild.set(key, prevChild);
203
+ keyToPrevChild[key] = prevChild;
273
204
  }
274
205
  }
275
206
  const middleLen = nextEnd - nextStart + 1;
276
207
  const newIndexToOldIndex = new Int32Array(middleLen);
208
+ const matchedPrev = new Uint8Array(prevEnd - prevStart + 1);
277
209
  let moved = false;
278
210
  let maxPrevIndexSoFar = -1;
279
211
  for (let i = nextStart; i <= nextEnd; i++) {
280
212
  const nextChild = getChild(nextChildren, i);
281
- const prevChild = keyToPrevChild.get(nextChild.key);
213
+ const prevChild = nextChild.key != null ? keyToPrevChild[nextChild.key] : undefined;
282
214
  if (prevChild != null) {
283
215
  const prevIndex = prevChild.index;
284
216
  newIndexToOldIndex[nextChild.index - nextStart] = prevIndex + 1;
217
+ matchedPrev[prevIndex - prevStart] = 1;
285
218
  if (prevIndex < maxPrevIndexSoFar) {
286
219
  moved = true;
287
220
  }
@@ -291,50 +224,46 @@ export function _patchKeyedChildren(frame) {
291
224
  }
292
225
  }
293
226
  pushPrefixPatches();
294
- const matchedPrev = new Uint8Array(prevEnd - prevStart + 1);
295
- for (let i = 0; i < middleLen; i++) {
296
- const oldIndex = newIndexToOldIndex[i];
297
- if (oldIndex !== 0) {
298
- matchedPrev[oldIndex - 1 - prevStart] = 1;
299
- }
300
- }
301
227
  for (let i = prevStart; i <= prevEnd; i++) {
302
228
  if (!matchedPrev[i - prevStart]) {
303
229
  const child = getChild(prevChildren, i);
304
- _clearElementHostReference(child, parentReference, renderRuntime);
305
- _pushUnmountEnterFrame(child, frame.meta);
230
+ clearElementHostReference(child, parentReference, renderRuntime);
231
+ pushUnmountEnterFrame(child, renderRuntime);
306
232
  }
307
233
  }
308
- const stableNewIndexes = moved ? getLongestIncreasingSubsequenceIndexes(newIndexToOldIndex) : new Int32Array(0);
309
- let stableCursor = 0;
310
- for (let i = nextStart; i <= nextEnd; i++) {
311
- const nextChild = getChild(nextChildren, i);
312
- const newIndex = nextChild.index - nextStart;
313
- const oldIndex = newIndexToOldIndex[newIndex];
314
- if (oldIndex === 0) {
315
- _pushMountEnterFrame(nextChild, {
316
- ...base,
317
- subtreeRightBoundary: getRightSibling(nextChild),
318
- });
319
- continue;
320
- }
321
- const prevChild = getChild(prevChildren, oldIndex - 1);
322
- const isStable = moved && stableNewIndexes[stableCursor] === newIndex;
323
- if (isStable) {
324
- stableCursor++;
234
+ if (moved) {
235
+ const stableNewIndexes = getLongestIncreasingSubsequenceIndexes(newIndexToOldIndex);
236
+ let stableCursor = 0;
237
+ for (let i = nextStart; i <= nextEnd; i++) {
238
+ const nextChild = getChild(nextChildren, i);
239
+ const newIndex = nextChild.index - nextStart;
240
+ const oldIndex = newIndexToOldIndex[newIndex];
241
+ if (oldIndex === 0) {
242
+ pushMountEnterFrame(nextChild, renderRuntime, parentReference, getRightSibling(nextChild), context, hostNamespace, null);
243
+ continue;
244
+ }
245
+ const prevChild = getChild(prevChildren, oldIndex - 1);
246
+ if (stableNewIndexes[stableCursor] === newIndex) {
247
+ stableCursor++;
248
+ }
249
+ else {
250
+ pushHostOperationPlaceElement(nextChild, renderRuntime, parentReference, getRightSibling(nextChild));
251
+ }
252
+ pushPatchEnterFrame(nextChild, renderRuntime, prevChild, parentReference, null, context, hostNamespace);
325
253
  }
326
- else if (moved) {
327
- _pushHostOperationPlaceElement(nextChild, {
328
- parentReference,
329
- renderRuntime,
330
- subtreeRightBoundary: getRightSibling(nextChild),
331
- });
254
+ }
255
+ else {
256
+ for (let i = nextStart; i <= nextEnd; i++) {
257
+ const nextChild = getChild(nextChildren, i);
258
+ const newIndex = nextChild.index - nextStart;
259
+ const oldIndex = newIndexToOldIndex[newIndex];
260
+ if (oldIndex === 0) {
261
+ pushMountEnterFrame(nextChild, renderRuntime, parentReference, getRightSibling(nextChild), context, hostNamespace, null);
262
+ continue;
263
+ }
264
+ const prevChild = getChild(prevChildren, oldIndex - 1);
265
+ pushPatchEnterFrame(nextChild, renderRuntime, prevChild, parentReference, null, context, hostNamespace);
332
266
  }
333
- _pushPatchEnterFrame(nextChild, {
334
- ...base,
335
- prevElement: prevChild,
336
- subtreeRightBoundary: null,
337
- });
338
267
  }
339
268
  pushSuffixPatches();
340
269
  }
package/core/portal.js CHANGED
@@ -10,7 +10,7 @@ export function createPortal(children, container) {
10
10
  children: null,
11
11
  className: null,
12
12
  reference: null,
13
- store: null,
13
+ hostNamespace: null,
14
14
  context: null,
15
15
  ref: container,
16
16
  unmounted: null,
@@ -1,75 +1,145 @@
1
- import { _mount } from './mounting.js';
2
- import { _mountChildren } from './mountingChildren.js';
3
- import { _patch } from './patching.js';
4
- import { _patchChildren, _patchKeyedChildren } from './patchingChildren.js';
5
- import { _unmount } from './unmounting.js';
6
- import { _unmountChildren } from './unmountingChildren.js';
1
+ import { mountEnter, mountExit } from './mounting.js';
2
+ import { mountChildren } from './mountingChildren.js';
3
+ import { patchEnter, patchExit } from './patching.js';
4
+ import { unmountEnter, unmountExit } from './unmounting.js';
5
+ import { unmountChildren } from './unmountingChildren.js';
7
6
  import { placeElementBeforeAnchor, resolveAnchorReference } from './utils.js';
8
7
  export const MOUNT_ENTER = 10;
9
8
  export const MOUNT_EXIT = 11;
10
9
  export const MOUNT_CHILDREN_ENTER = 12;
11
10
  export const PATCH_ENTER = 20;
12
11
  export const PATCH_EXIT = 21;
13
- export const PATCH_CHILDREN = 22;
14
- export const PATCH_KEYED_CHILDREN = 24;
15
12
  export const UNMOUNT_ENTER = 30;
16
13
  export const UNMOUNT_EXIT = 31;
17
14
  export const UNMOUNT_CHILDREN_ENTER = 32;
18
15
  export const HOST_OPS_PLACE_ELEMENT_BEFORE_ANCHOR = 40;
19
16
  export const HOST_OPS_REPLACE_CHILD = 42;
17
+ function createFrame() {
18
+ return {
19
+ kind: 0,
20
+ node: null,
21
+ renderRuntime: null,
22
+ parentReference: null,
23
+ subtreeRightBoundary: null,
24
+ context: null,
25
+ hostNamespace: null,
26
+ prevElement: null,
27
+ children: null,
28
+ placeHolderElement: null,
29
+ };
30
+ }
31
+ export function acquireMountFrame(renderRuntime, element, kind, parentReference, subtreeRightBoundary, context, hostNamespace, placeHolderElement) {
32
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
33
+ frame.kind = kind;
34
+ frame.node = element;
35
+ frame.renderRuntime = renderRuntime;
36
+ frame.parentReference = parentReference;
37
+ frame.subtreeRightBoundary = subtreeRightBoundary;
38
+ frame.context = context;
39
+ frame.hostNamespace = hostNamespace;
40
+ frame.placeHolderElement = placeHolderElement;
41
+ return frame;
42
+ }
43
+ export function acquireMountChildrenFrame(renderRuntime, parent, children, parentReference, subtreeRightBoundary, context, hostNamespace) {
44
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
45
+ frame.kind = MOUNT_CHILDREN_ENTER;
46
+ frame.node = parent;
47
+ frame.renderRuntime = renderRuntime;
48
+ frame.children = children;
49
+ frame.parentReference = parentReference;
50
+ frame.subtreeRightBoundary = subtreeRightBoundary;
51
+ frame.context = context;
52
+ frame.hostNamespace = hostNamespace;
53
+ return frame;
54
+ }
55
+ export function acquirePatchFrame(renderRuntime, element, kind, prevElement, parentReference, subtreeRightBoundary, context, hostNamespace) {
56
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
57
+ frame.kind = kind;
58
+ frame.node = element;
59
+ frame.renderRuntime = renderRuntime;
60
+ frame.prevElement = prevElement;
61
+ frame.parentReference = parentReference;
62
+ frame.subtreeRightBoundary = subtreeRightBoundary;
63
+ frame.context = context;
64
+ frame.hostNamespace = hostNamespace;
65
+ return frame;
66
+ }
67
+ export function acquireUnmountFrame(renderRuntime, element, kind) {
68
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
69
+ frame.kind = kind;
70
+ frame.node = element;
71
+ frame.renderRuntime = renderRuntime;
72
+ return frame;
73
+ }
74
+ export function acquireUnmountChildrenFrame(renderRuntime, parent) {
75
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
76
+ frame.kind = UNMOUNT_CHILDREN_ENTER;
77
+ frame.node = parent;
78
+ frame.renderRuntime = renderRuntime;
79
+ return frame;
80
+ }
81
+ export function acquirePlaceFrame(renderRuntime, element, parentReference, subtreeRightBoundary) {
82
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
83
+ frame.kind = HOST_OPS_PLACE_ELEMENT_BEFORE_ANCHOR;
84
+ frame.node = element;
85
+ frame.renderRuntime = renderRuntime;
86
+ frame.parentReference = parentReference;
87
+ frame.subtreeRightBoundary = subtreeRightBoundary;
88
+ return frame;
89
+ }
90
+ export function acquireReplaceFrame(renderRuntime, element, parentReference, prevElement) {
91
+ const frame = renderRuntime.framePool.pop() ?? createFrame();
92
+ frame.kind = HOST_OPS_REPLACE_CHILD;
93
+ frame.node = element;
94
+ frame.renderRuntime = renderRuntime;
95
+ frame.parentReference = parentReference;
96
+ frame.prevElement = prevElement;
97
+ return frame;
98
+ }
20
99
  export function processStack(renderRuntime) {
21
100
  const stack = renderRuntime.renderStack;
101
+ const pool = renderRuntime.framePool;
22
102
  while (stack.length > 0) {
23
103
  const frame = stack.pop();
24
104
  switch (frame.kind) {
25
- case MOUNT_ENTER: {
26
- _mount(frame);
27
- break;
28
- }
29
- case MOUNT_CHILDREN_ENTER: {
30
- _mountChildren(frame);
31
- break;
32
- }
33
- case MOUNT_EXIT: {
34
- _mount(frame);
105
+ case MOUNT_ENTER:
106
+ mountEnter(frame);
35
107
  break;
36
- }
37
- case PATCH_ENTER: {
38
- _patch(frame);
108
+ case MOUNT_EXIT:
109
+ mountExit(frame);
39
110
  break;
40
- }
41
- case PATCH_EXIT: {
42
- _patch(frame);
111
+ case MOUNT_CHILDREN_ENTER:
112
+ mountChildren(frame);
43
113
  break;
44
- }
45
- case PATCH_CHILDREN: {
46
- _patchChildren(frame);
114
+ case PATCH_ENTER:
115
+ patchEnter(frame);
47
116
  break;
48
- }
49
- case PATCH_KEYED_CHILDREN: {
50
- _patchKeyedChildren(frame);
117
+ case PATCH_EXIT:
118
+ patchExit(frame);
51
119
  break;
52
- }
53
- case UNMOUNT_ENTER: {
54
- _unmount(frame);
120
+ case UNMOUNT_ENTER:
121
+ unmountEnter(frame);
55
122
  break;
56
- }
57
- case UNMOUNT_EXIT: {
58
- _unmount(frame);
123
+ case UNMOUNT_EXIT:
124
+ unmountExit(frame);
59
125
  break;
60
- }
61
- case UNMOUNT_CHILDREN_ENTER: {
62
- _unmountChildren(frame);
126
+ case UNMOUNT_CHILDREN_ENTER:
127
+ unmountChildren(frame);
63
128
  break;
64
- }
65
129
  case HOST_OPS_PLACE_ELEMENT_BEFORE_ANCHOR: {
66
- const anchor = resolveAnchorReference(frame.meta.subtreeRightBoundary);
67
- placeElementBeforeAnchor(frame.node, anchor, frame.meta.parentReference, renderRuntime);
130
+ const anchor = resolveAnchorReference(frame.subtreeRightBoundary);
131
+ placeElementBeforeAnchor(frame.node, anchor, frame.parentReference, renderRuntime);
68
132
  break;
69
133
  }
70
- case HOST_OPS_REPLACE_CHILD: {
71
- renderRuntime.hostAdapter.replaceChild(frame.meta.parentReference, frame.node.reference, frame.meta.prevElement.reference);
72
- }
134
+ case HOST_OPS_REPLACE_CHILD:
135
+ renderRuntime.hostAdapter.replaceChild(frame.parentReference, frame.node.reference, frame.prevElement.reference);
136
+ break;
73
137
  }
138
+ frame.node = null;
139
+ frame.prevElement = null;
140
+ frame.children = null;
141
+ frame.subtreeRightBoundary = null;
142
+ frame.placeHolderElement = null;
143
+ pool.push(frame);
74
144
  }
75
145
  }
package/core/ref.js CHANGED
@@ -4,6 +4,7 @@ export function unmountRef(element) {
4
4
  }
5
5
  if (typeof element.ref.cleanup === 'function') {
6
6
  element.ref.cleanup();
7
+ element.ref.cleanup = null;
7
8
  }
8
9
  if (typeof element.ref.value !== 'function') {
9
10
  element.ref.value.current = null;
package/core/rerender.js CHANGED
@@ -1,4 +1,4 @@
1
- import { lifecycleEventBus } from './lifecycleEventBus.js';
1
+ import { registerLifecyclePlugin } from './lifecycleEventBus.js';
2
2
  import { patch } from './patching.js';
3
3
  import { findParentReferenceFromElement } from './utils.js';
4
4
  const rerenderSpecificDataByRuntime = new WeakMap();
@@ -15,12 +15,14 @@ function getRerenderSpecificData(renderRuntime) {
15
15
  }
16
16
  return data;
17
17
  }
18
- lifecycleEventBus.subscribe(event => {
19
- const data = getRerenderSpecificData(event.renderRuntime);
20
- if (event.type === 'afterRender' || event.type === 'errored' || event.type === 'unmounted') {
21
- data.asyncQueue.delete(event.element.store);
22
- data.syncQueue.delete(event.element.store);
23
- }
18
+ registerLifecyclePlugin(bus => {
19
+ bus.subscribe(event => {
20
+ if (event.type === 'afterRender' || event.type === 'errored' || event.type === 'unmounted') {
21
+ const data = getRerenderSpecificData(event.renderRuntime);
22
+ data.asyncQueue.delete(event.element);
23
+ data.syncQueue.delete(event.element);
24
+ }
25
+ });
24
26
  });
25
27
  function scheduleAsyncFlush(renderRuntime) {
26
28
  const data = getRerenderSpecificData(renderRuntime);
@@ -38,19 +40,21 @@ function scheduleAsyncFlush(renderRuntime) {
38
40
  };
39
41
  queueMicrotask(process);
40
42
  }
41
- export function rerender(store, renderRuntime) {
43
+ export function rerender(element, renderRuntime) {
42
44
  const data = getRerenderSpecificData(renderRuntime);
43
- const element = store.latestElement;
44
45
  if (element.unmounted) {
45
46
  console.warn('The component is unmounted.');
46
47
  return;
47
48
  }
48
- lifecycleEventBus.publish({ type: 'triedToRerender', element, renderRuntime });
49
+ if (renderRuntime.activeRenderElement === element) {
50
+ renderRuntime.pendingRerenderFlag = true;
51
+ return;
52
+ }
49
53
  if (data.syncLockDepth > 0) {
50
- data.syncQueue.add(store);
54
+ data.syncQueue.add(element);
51
55
  return;
52
56
  }
53
- data.asyncQueue.add(store);
57
+ data.asyncQueue.add(element);
54
58
  scheduleAsyncFlush(renderRuntime);
55
59
  }
56
60
  export function withSyncRerender(renderRuntime, callback) {
@@ -67,17 +71,11 @@ export function withSyncRerender(renderRuntime, callback) {
67
71
  }
68
72
  }
69
73
  function flushQueue(queue, renderRuntime) {
70
- for (const store of queue) {
71
- queue.delete(store);
72
- performRerender(store.latestElement, renderRuntime);
74
+ for (const element of queue) {
75
+ queue.delete(element);
76
+ performRerender(element, renderRuntime);
73
77
  }
74
78
  }
75
79
  function performRerender(element, renderRuntime) {
76
- element.store.forceRerender = true;
77
- try {
78
- patch(element, element, findParentReferenceFromElement(element), null, element.context || null, element.store.hostNamespace, renderRuntime);
79
- }
80
- finally {
81
- element.store.forceRerender = false;
82
- }
80
+ patch(element, element, findParentReferenceFromElement(element), null, element.context || null, element.hostNamespace, renderRuntime);
83
81
  }
package/core/runtime.js CHANGED
@@ -1,2 +1,10 @@
1
- export const MOUNTING_PHASE = 0;
2
- export const UPDATING_PHASE = 1;
1
+ export function createRenderRuntime(hostAdapter, renderer) {
2
+ return {
3
+ hostAdapter,
4
+ renderer,
5
+ renderStack: [],
6
+ framePool: [],
7
+ activeRenderElement: null,
8
+ pendingRerenderFlag: false,
9
+ };
10
+ }