@simpreact/simpreact 0.0.4 → 0.0.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.
Files changed (78) hide show
  1. package/LICENSE.txt +1 -1
  2. package/compat/context.d.ts +4 -4
  3. package/compat/context.js +3 -2
  4. package/compat/core.d.ts +4 -0
  5. package/compat/core.js +14 -9
  6. package/compat/dom.d.ts +4 -5
  7. package/compat/dom.js +3 -2
  8. package/compat/hooks.d.ts +16 -13
  9. package/compat/hooks.js +19 -15
  10. package/compat/index.d.ts +10 -9
  11. package/compat/renderRuntime.d.ts +2 -0
  12. package/compat/renderRuntime.js +14 -0
  13. package/component/index.d.ts +16 -0
  14. package/component/index.js +164 -0
  15. package/context/index.d.ts +12 -5
  16. package/context/index.js +62 -57
  17. package/core/createElement.d.ts +29 -20
  18. package/core/createElement.js +159 -133
  19. package/core/hostAdapter.d.ts +8 -12
  20. package/core/hostAdapter.js +1 -4
  21. package/core/hostOperations.d.ts +5 -0
  22. package/core/hostOperations.js +15 -0
  23. package/core/index.d.ts +29 -6
  24. package/core/internal.d.ts +3 -0
  25. package/core/internal.js +3 -0
  26. package/core/lifecycleEventBus.d.ts +15 -6
  27. package/core/lifecycleEventBus.js +16 -2
  28. package/core/memo.d.ts +0 -2
  29. package/core/memo.js +1 -3
  30. package/core/mounting.d.ts +7 -9
  31. package/core/mounting.js +221 -82
  32. package/core/patching.d.ts +7 -8
  33. package/core/patching.js +235 -255
  34. package/core/patchingChildren.d.ts +6 -0
  35. package/core/patchingChildren.js +330 -0
  36. package/core/portal.d.ts +1 -1
  37. package/core/portal.js +17 -7
  38. package/core/processStack.d.ts +69 -0
  39. package/core/processStack.js +63 -0
  40. package/core/ref.d.ts +4 -3
  41. package/core/rerender.d.ts +4 -14
  42. package/core/rerender.js +67 -112
  43. package/core/runtime.d.ts +17 -0
  44. package/core/runtime.js +2 -0
  45. package/core/unmounting.d.ts +11 -6
  46. package/core/unmounting.js +81 -40
  47. package/core/utils.d.ts +10 -0
  48. package/core/utils.js +143 -0
  49. package/dom/attach-element-to-dom.d.ts +4 -3
  50. package/dom/attach-element-to-dom.js +12 -7
  51. package/dom/domAdapter.js +22 -25
  52. package/dom/events.d.ts +5 -5
  53. package/dom/events.js +33 -16
  54. package/dom/index.d.ts +16 -5
  55. package/dom/index.js +4 -3
  56. package/dom/props/controlled/index.d.ts +3 -3
  57. package/dom/props/controlled/index.js +8 -8
  58. package/dom/props/controlled/input.d.ts +3 -3
  59. package/dom/props/controlled/input.js +57 -34
  60. package/dom/props/controlled/select.d.ts +3 -3
  61. package/dom/props/controlled/select.js +39 -26
  62. package/dom/props/controlled/textarea.d.ts +3 -3
  63. package/dom/props/controlled/textarea.js +57 -34
  64. package/dom/props/dangerInnerHTML.d.ts +2 -2
  65. package/dom/props/dangerInnerHTML.js +3 -2
  66. package/dom/props/props.d.ts +4 -4
  67. package/dom/props/props.js +24 -21
  68. package/dom/render.d.ts +4 -5
  69. package/dom/render.js +38 -34
  70. package/hooks/index.d.ts +15 -13
  71. package/hooks/index.js +155 -159
  72. package/jsx-runtime/index.d.ts +2 -1
  73. package/package.json +9 -1
  74. package/shared/index.d.ts +10 -0
  75. package/shared/index.js +4 -7
  76. package/shared/utils.js +4 -4
  77. package/shared/EventBus.d.ts +0 -18
  78. package/shared/EventBus.js +0 -28
@@ -1,10 +1,8 @@
1
1
  import type { Maybe, Nullable } from '../shared/index.js';
2
- import type { HostReference } from './hostAdapter.js';
3
- import type { SimpElement } from './createElement.js';
4
- export declare function mount(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
5
- export declare function mountTextElement(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>): void;
6
- export declare function mountHostElement(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
7
- export declare function mountFunctionalElement(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
8
- export declare function mountFragment(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
9
- export declare function mountArrayChildren(children: SimpElement[], reference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown, parentElement: SimpElement, hostNamespace: Maybe<string>): void;
10
- export declare function mountPortal(element: SimpElement, parentReference: Nullable<HostReference>, nextReference: Nullable<HostReference>, context: unknown): void;
2
+ import { type SimpElement } from './createElement.js';
3
+ import { type MountFrame, type MountFrameMeta } from './processStack.js';
4
+ import { type SimpRenderRuntime } from './runtime.js';
5
+ export declare function mount(element: SimpElement, parentReference: unknown, rightSibling: Nullable<SimpElement>, context: unknown, hostNamespace: Maybe<string>, renderRuntime: SimpRenderRuntime): void;
6
+ export declare function _mount(frame: MountFrame): void;
7
+ export declare function _pushMountEnterFrame(element: SimpElement, meta: MountFrameMeta): void;
8
+ export declare function _pushMountArrayChildrenFrame(element: SimpElement, meta: MountFrameMeta): void;
package/core/mounting.js CHANGED
@@ -1,76 +1,134 @@
1
- import { emptyObject } from '../shared/index.js';
2
- import { hostAdapter } from './hostAdapter.js';
3
- import { createTextElement, normalizeRoot } from './createElement.js';
4
- import { applyRef } from './ref.js';
1
+ import { createTextElement, normalizeRoot, SIMP_ELEMENT_CHILD_FLAG_ELEMENT, SIMP_ELEMENT_CHILD_FLAG_LIST, SIMP_ELEMENT_CHILD_FLAG_TEXT, } from './createElement.js';
2
+ import { _pushHostOperationPlaceElement } from './hostOperations.js';
5
3
  import { lifecycleEventBus } from './lifecycleEventBus.js';
6
- import { batchingRerenderLocker } from './rerender.js';
7
- export function mount(element, parentReference, nextReference, context, hostNamespace) {
8
- if (element.flag === 'TEXT') {
9
- mountTextElement(element, parentReference, nextReference);
10
- }
11
- else if (element.flag === 'HOST') {
12
- mountHostElement(element, parentReference, nextReference, context, hostNamespace);
13
- }
14
- else if (element.flag === 'FC') {
15
- mountFunctionalElement(element, parentReference, nextReference, context, hostNamespace);
16
- }
17
- else if (element.flag === 'FRAGMENT') {
18
- mountFragment(element, parentReference, nextReference, context, hostNamespace);
19
- }
20
- else {
21
- mountPortal(element, parentReference, nextReference, context);
4
+ import { MOUNT_ENTER, MOUNT_EXIT, processStack } from './processStack.js';
5
+ import { applyRef } from './ref.js';
6
+ import { MOUNTING_PHASE } from './runtime.js';
7
+ import { bitScanForwardIndex } from './utils.js';
8
+ const mountHandlers = [_mountHostElement, _mountFunctionalElement, _mountTextElement, _mountPortal, _mountFragment];
9
+ export function mount(element, parentReference, rightSibling, context, hostNamespace, renderRuntime) {
10
+ if (renderRuntime.renderStack.length !== 0) {
11
+ throw new Error('Cannot mount while rendering.');
22
12
  }
13
+ _pushMountEnterFrame(element, {
14
+ parentReference,
15
+ rightSibling,
16
+ context,
17
+ hostNamespace,
18
+ renderRuntime,
19
+ placeHolderElement: null,
20
+ });
21
+ processStack(renderRuntime);
23
22
  }
24
- export function mountTextElement(element, parentReference, nextReference) {
25
- const reference = (element.reference = hostAdapter.createTextReference(element.children));
26
- if (parentReference) {
27
- hostAdapter.insertOrAppend(parentReference, reference, nextReference);
28
- }
23
+ export function _mount(frame) {
24
+ mountHandlers[bitScanForwardIndex(frame.node.flag)](frame);
25
+ }
26
+ export function _pushMountEnterFrame(element, meta) {
27
+ meta.renderRuntime.renderStack.push({
28
+ node: element,
29
+ kind: MOUNT_ENTER,
30
+ meta,
31
+ });
29
32
  }
30
- export function mountHostElement(element, parentReference, nextReference, context, hostNamespace) {
31
- const hostNamespaces = hostAdapter.getHostNamespaces(element, hostNamespace);
32
- hostNamespace = hostNamespaces?.self;
33
- const hostReference = (element.reference = hostAdapter.createReference(element.type, hostNamespace));
34
- hostAdapter.attachElementToReference(element, hostReference);
35
- // HOST element always has Maybe<Many<SimpElement>> children due to normalization process.
33
+ function _pushMountExitFrame(element, meta) {
34
+ meta.renderRuntime.renderStack.push({
35
+ node: element,
36
+ kind: MOUNT_EXIT,
37
+ meta,
38
+ });
39
+ }
40
+ export function _pushMountArrayChildrenFrame(element, meta) {
36
41
  const children = element.children;
37
- if (Array.isArray(children)) {
38
- mountArrayChildren(children, hostReference, null, context, element, hostNamespaces?.children);
39
- }
40
- else if (children) {
41
- children.parent = element;
42
- mount(children, hostReference, null, context, hostNamespaces?.children);
42
+ for (let i = children.length - 1; i >= 0; i--) {
43
+ const child = children[i];
44
+ child.parent = element;
45
+ const rightSibling = children[child.index + 1] ?? meta.rightSibling;
46
+ _pushMountEnterFrame(child, { ...meta, rightSibling });
43
47
  }
44
- if (element.props) {
45
- hostAdapter.mountProps(hostReference, element, hostNamespace);
46
- // HOST elements can have either children elements or string children in the props due to normalization.
47
- if (typeof element.props.children === 'string') {
48
- hostAdapter.setTextContent(hostReference, element.props.children);
48
+ }
49
+ function _mountHostElement(frame) {
50
+ const element = frame.node;
51
+ const { parentReference, rightSibling, context, hostNamespace, renderRuntime } = frame.meta;
52
+ if (frame.kind === MOUNT_EXIT) {
53
+ if (element.childFlag === SIMP_ELEMENT_CHILD_FLAG_TEXT) {
54
+ renderRuntime.hostAdapter.setTextContent(element.reference, element.props.children);
49
55
  }
56
+ if (element.props) {
57
+ renderRuntime.hostAdapter.mountProps(element.reference, element, renderRuntime, hostNamespace);
58
+ }
59
+ if (element.className) {
60
+ renderRuntime.hostAdapter.setClassname(element.reference, element.className, hostNamespace);
61
+ }
62
+ if (parentReference) {
63
+ _pushHostOperationPlaceElement(element, {
64
+ renderRuntime,
65
+ rightSibling,
66
+ parentReference,
67
+ });
68
+ }
69
+ applyRef(element);
70
+ return;
50
71
  }
51
- if (element.className) {
52
- hostAdapter.setClassname(hostReference, element.className, hostNamespace);
53
- }
54
- if (parentReference) {
55
- hostAdapter.insertOrAppend(parentReference, hostReference, nextReference);
72
+ const hostNamespaces = renderRuntime.hostAdapter.getHostNamespaces(element, hostNamespace);
73
+ const hostReference = (element.reference = renderRuntime.hostAdapter.createReference(element.type, hostNamespaces?.self));
74
+ renderRuntime.hostAdapter.attachElementToReference(element, hostReference, renderRuntime);
75
+ _pushMountExitFrame(element, {
76
+ renderRuntime,
77
+ hostNamespace: hostNamespaces?.self,
78
+ rightSibling,
79
+ context,
80
+ parentReference,
81
+ placeHolderElement: null,
82
+ });
83
+ switch (element.childFlag) {
84
+ case SIMP_ELEMENT_CHILD_FLAG_LIST: {
85
+ _pushMountArrayChildrenFrame(element, {
86
+ renderRuntime,
87
+ hostNamespace: hostNamespaces?.children,
88
+ rightSibling: null,
89
+ context,
90
+ parentReference: hostReference,
91
+ placeHolderElement: null,
92
+ });
93
+ break;
94
+ }
95
+ case SIMP_ELEMENT_CHILD_FLAG_ELEMENT: {
96
+ element.children.parent = element;
97
+ _pushMountEnterFrame(element.children, {
98
+ renderRuntime,
99
+ hostNamespace: hostNamespaces?.children,
100
+ rightSibling: null,
101
+ context,
102
+ parentReference: hostReference,
103
+ placeHolderElement: null,
104
+ });
105
+ }
56
106
  }
57
- applyRef(element);
58
107
  }
59
- export function mountFunctionalElement(element, parentReference, nextReference, context, hostNamespace) {
108
+ function _mountFunctionalElement(frame) {
109
+ const element = frame.node;
110
+ const { parentReference, rightSibling, context, hostNamespace, renderRuntime } = frame.meta;
111
+ if (frame.kind === MOUNT_EXIT) {
112
+ lifecycleEventBus.publish({ type: 'mounted', element, renderRuntime });
113
+ return;
114
+ }
60
115
  if (context) {
61
116
  element.context = context;
62
117
  }
63
118
  if (element.unmounted) {
64
119
  element.unmounted = false;
65
120
  }
66
- element.store = { latestElement: element };
121
+ element.store = { latestElement: null, hostNamespace: null, forceRerender: false };
122
+ element.store.latestElement = element;
67
123
  if (hostNamespace) {
68
124
  element.store.hostNamespace = hostNamespace;
69
125
  }
70
- // FC element always has Maybe<SimpElement> children due to normalization process.
126
+ // FC element always has Maybe<SimpElement> children due to a normalization process.
71
127
  let children;
72
128
  let triedToRerenderUnsubscribe;
73
129
  try {
130
+ renderRuntime.renderPhase = MOUNTING_PHASE;
131
+ renderRuntime.currentRenderingFCElement = element;
74
132
  let triedToRerender = false;
75
133
  let rerenderCounter = 0;
76
134
  triedToRerenderUnsubscribe = lifecycleEventBus.subscribe(event => {
@@ -83,49 +141,130 @@ export function mountFunctionalElement(element, parentReference, nextReference,
83
141
  if (++rerenderCounter >= 25) {
84
142
  throw new Error('Too many re-renders.');
85
143
  }
86
- lifecycleEventBus.publish({ type: 'beforeRender', element, phase: 'mounting' });
87
- batchingRerenderLocker.lock();
88
- children = element.type(element.props || emptyObject);
89
- batchingRerenderLocker.flush();
90
- lifecycleEventBus.publish({ type: 'afterRender', element, phase: 'mounting' });
144
+ lifecycleEventBus.publish({
145
+ type: 'beforeRender',
146
+ element,
147
+ renderRuntime,
148
+ });
149
+ children = renderRuntime.renderer(element.type, element, renderRuntime);
150
+ lifecycleEventBus.publish({
151
+ type: 'afterRender',
152
+ element,
153
+ renderRuntime,
154
+ });
91
155
  } while (triedToRerender);
92
- children = normalizeRoot(children, false);
156
+ normalizeRoot(element, children, false);
93
157
  }
94
158
  catch (error) {
95
- lifecycleEventBus.publish({ type: 'errored', element, error, phase: 'mounting' });
159
+ const event = {
160
+ type: 'errored',
161
+ element,
162
+ error,
163
+ handled: false,
164
+ renderRuntime,
165
+ };
166
+ lifecycleEventBus.publish(event);
167
+ if (!event.handled) {
168
+ throw new Error('Error occurred during rendering a component', { cause: event.error });
169
+ }
96
170
  return;
97
171
  }
98
172
  finally {
99
173
  triedToRerenderUnsubscribe();
174
+ renderRuntime.renderPhase = null;
175
+ renderRuntime.currentRenderingFCElement = null;
100
176
  }
101
- if (children) {
102
- children.parent = element;
103
- mount((element.children = children), parentReference, nextReference, element.context, hostNamespace);
177
+ _pushMountExitFrame(element, {
178
+ renderRuntime,
179
+ hostNamespace: null,
180
+ rightSibling: null,
181
+ context: null,
182
+ parentReference: null,
183
+ placeHolderElement: null,
184
+ });
185
+ if (element.children) {
186
+ const child = element.children;
187
+ child.parent = element;
188
+ _pushMountEnterFrame(child, {
189
+ renderRuntime,
190
+ hostNamespace,
191
+ rightSibling,
192
+ context: element.context,
193
+ parentReference,
194
+ placeHolderElement: null,
195
+ });
104
196
  }
105
- lifecycleEventBus.publish({ type: 'mounted', element });
106
197
  }
107
- export function mountFragment(element, parentReference, nextReference, context, hostNamespace) {
108
- // FRAGMENT element always has Maybe<Many<SimpElement>> children due to normalization process.
109
- if (Array.isArray(element.children)) {
110
- mountArrayChildren(element.children, parentReference, nextReference, context, element, hostNamespace);
111
- }
112
- else if (element.children) {
113
- element.children.parent = element;
114
- mount(element.children, parentReference, nextReference, context, hostNamespace);
115
- }
198
+ function _mountTextElement(frame) {
199
+ const { renderRuntime, parentReference } = frame.meta;
200
+ frame.node.reference = renderRuntime.hostAdapter.createTextReference(frame.node.children);
201
+ _pushHostOperationPlaceElement(frame.node, {
202
+ renderRuntime,
203
+ rightSibling: frame.meta.rightSibling,
204
+ parentReference,
205
+ });
116
206
  }
117
- export function mountArrayChildren(children, reference, nextReference, context, parentElement, hostNamespace) {
118
- for (const child of children) {
119
- child.parent = parentElement;
120
- mount(child, reference, nextReference, context, hostNamespace);
207
+ function _mountPortal(frame) {
208
+ const element = frame.node;
209
+ const { parentReference, rightSibling, context, renderRuntime } = frame.meta;
210
+ if (frame.kind === MOUNT_EXIT) {
211
+ element.reference = frame.meta.placeHolderElement.reference;
212
+ return;
121
213
  }
122
- }
123
- export function mountPortal(element, parentReference, nextReference, context) {
214
+ const placeHolderElement = createTextElement('');
215
+ _pushMountExitFrame(element, {
216
+ renderRuntime,
217
+ rightSibling: null,
218
+ context: null,
219
+ parentReference: null,
220
+ hostNamespace: null,
221
+ placeHolderElement,
222
+ });
124
223
  if (element.children) {
125
- element.children.parent = element;
126
- mount(element.children, element.ref, null, context, hostAdapter.getHostNamespaces(element.children, undefined)?.self);
224
+ const child = element.children;
225
+ child.parent = element;
226
+ _pushMountEnterFrame(child, {
227
+ renderRuntime,
228
+ rightSibling: null,
229
+ context,
230
+ parentReference: element.ref,
231
+ hostNamespace: renderRuntime.hostAdapter.getHostNamespaces(child, undefined)?.self,
232
+ placeHolderElement: null,
233
+ });
234
+ }
235
+ _pushMountEnterFrame(placeHolderElement, {
236
+ renderRuntime,
237
+ rightSibling,
238
+ context: null,
239
+ parentReference,
240
+ hostNamespace: null,
241
+ placeHolderElement: null,
242
+ });
243
+ }
244
+ function _mountFragment(frame) {
245
+ const element = frame.node;
246
+ const { parentReference, hostNamespace, context, renderRuntime, rightSibling } = frame.meta;
247
+ switch (element.childFlag) {
248
+ case SIMP_ELEMENT_CHILD_FLAG_LIST:
249
+ _pushMountArrayChildrenFrame(element, {
250
+ renderRuntime,
251
+ hostNamespace,
252
+ rightSibling,
253
+ context,
254
+ parentReference,
255
+ placeHolderElement: null,
256
+ });
257
+ break;
258
+ case SIMP_ELEMENT_CHILD_FLAG_ELEMENT:
259
+ const child = element.children;
260
+ child.parent = element;
261
+ _pushMountEnterFrame(child, {
262
+ renderRuntime,
263
+ hostNamespace,
264
+ rightSibling,
265
+ context,
266
+ parentReference,
267
+ placeHolderElement: null,
268
+ });
127
269
  }
128
- const placeHolderElement = createTextElement('');
129
- mountTextElement(placeHolderElement, parentReference, nextReference);
130
- element.reference = placeHolderElement.reference;
131
270
  }
@@ -1,9 +1,8 @@
1
1
  import type { Maybe, Nullable } from '../shared/index.js';
2
- import type { SimpElement } from './createElement.js';
3
- import type { HostReference } from './hostAdapter.js';
4
- export declare function patch(prevElement: SimpElement, nextElement: SimpElement, parentReference: HostReference, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
5
- export declare function patchPortal(prevElement: SimpElement, nextElement: SimpElement, context: unknown): void;
6
- export declare function updateFunctionalComponent(element: SimpElement, parentReference: HostReference, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
7
- export declare function patchKeyedChildren(prevChildren: SimpElement[], nextChildren: SimpElement[], parentReference: HostReference, nextReference: Nullable<HostReference>, context: unknown, hostNamespace: Maybe<string>): void;
8
- export declare function findParentReferenceFromElement(element: SimpElement): Nullable<HostReference>;
9
- export declare function findHostReferenceFromElement(element: SimpElement): Nullable<HostReference>;
2
+ import { type SimpElement } from './createElement.js';
3
+ import { type PatchFrame, type PatchFrameMeta } from './processStack.js';
4
+ import { type SimpRenderRuntime } from './runtime.js';
5
+ export declare function patch(prevElement: SimpElement, nextElement: SimpElement, parentReference: unknown, rightSibling: Nullable<SimpElement>, context: unknown, hostNamespace: Maybe<string>, renderRuntime: SimpRenderRuntime): void;
6
+ export declare function _pushPatchEnterFrame(element: SimpElement, meta: PatchFrameMeta): void;
7
+ export declare function _pushPatchExitFrame(element: SimpElement, meta: PatchFrameMeta): void;
8
+ export declare function _patch(frame: PatchFrame): void;