@simpreact/simpreact 0.0.3 → 0.0.5
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/compat/context.d.ts +8 -0
- package/compat/context.js +7 -0
- package/compat/core.d.ts +4 -7
- package/compat/core.js +7 -9
- package/compat/hooks.d.ts +0 -2
- package/compat/hooks.js +0 -2
- package/compat/index.d.ts +5 -4
- package/compat/index.js +3 -0
- package/context/index.d.ts +24 -0
- package/context/index.js +64 -0
- package/core/createElement.d.ts +6 -9
- package/core/createElement.js +1 -24
- package/core/index.d.ts +2 -21
- package/core/index.js +3 -3
- package/core/internal.d.ts +1 -1
- package/core/internal.js +1 -1
- package/core/memo.d.ts +10 -0
- package/core/memo.js +11 -0
- package/core/mounting.d.ts +6 -9
- package/core/mounting.js +21 -56
- package/core/patching.d.ts +4 -5
- package/core/patching.js +55 -85
- package/core/rerender.d.ts +5 -4
- package/core/rerender.js +76 -24
- package/core/unmounting.js +3 -3
- package/dom/attach-element-to-dom.js +10 -1
- package/dom/events.d.ts +6 -1
- package/dom/events.js +12 -2
- package/hooks/index.d.ts +1 -3
- package/hooks/index.js +20 -21
- package/package.json +1 -1
- package/shared/index.d.ts +6 -0
- package/shared/index.js +12 -3
- package/shared/utils.d.ts +1 -0
- package/shared/utils.js +20 -0
- package/compat/utils.d.ts +0 -1
- package/compat/utils.js +0 -3
- package/core/context.d.ts +0 -18
- package/core/context.js +0 -18
package/core/patching.js
CHANGED
|
@@ -1,50 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { emptyObject } from '../shared/index.js';
|
|
2
2
|
import { normalizeRoot } from './createElement.js';
|
|
3
3
|
import { hostAdapter } from './hostAdapter.js';
|
|
4
4
|
import { clearElementHostReference, remove, unmount } from './unmounting.js';
|
|
5
|
-
import { mount, mountArrayChildren } from './mounting.js';
|
|
5
|
+
import { mount, mountArrayChildren, mountFunctionalElement } from './mounting.js';
|
|
6
6
|
import { applyRef } from './ref.js';
|
|
7
7
|
import { lifecycleEventBus } from './lifecycleEventBus.js';
|
|
8
|
-
import {
|
|
9
|
-
export function patch(prevElement, nextElement, parentReference, nextReference,
|
|
8
|
+
import { isMemo } from './memo.js';
|
|
9
|
+
export function patch(prevElement, nextElement, parentReference, nextReference, context, hostNamespace) {
|
|
10
10
|
if (prevElement.type !== nextElement.type || prevElement.key !== nextElement.key) {
|
|
11
|
-
replaceWithNewElement(prevElement, nextElement, parentReference,
|
|
11
|
+
replaceWithNewElement(prevElement, nextElement, parentReference, context, hostNamespace);
|
|
12
12
|
}
|
|
13
13
|
else if (nextElement.flag === 'HOST') {
|
|
14
|
-
patchHostElement(prevElement, nextElement,
|
|
14
|
+
patchHostElement(prevElement, nextElement, context, hostNamespace);
|
|
15
15
|
}
|
|
16
16
|
else if (nextElement.flag === 'FC') {
|
|
17
|
-
patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference,
|
|
17
|
+
patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference, context, hostNamespace);
|
|
18
18
|
}
|
|
19
19
|
else if (nextElement.flag === 'TEXT') {
|
|
20
20
|
patchTextElement(prevElement, nextElement);
|
|
21
21
|
}
|
|
22
22
|
else if (nextElement.flag === 'FRAGMENT') {
|
|
23
|
-
patchFragment(prevElement, nextElement, parentReference,
|
|
24
|
-
}
|
|
25
|
-
else if (nextElement.flag === 'PROVIDER') {
|
|
26
|
-
patchProvider(prevElement, nextElement, parentReference, contextMap, hostNamespace);
|
|
27
|
-
}
|
|
28
|
-
else if (nextElement.flag === 'PORTAL') {
|
|
29
|
-
patchPortal(prevElement, nextElement, contextMap);
|
|
23
|
+
patchFragment(prevElement, nextElement, parentReference, context, hostNamespace);
|
|
30
24
|
}
|
|
31
25
|
else {
|
|
32
|
-
|
|
26
|
+
patchPortal(prevElement, nextElement, context);
|
|
33
27
|
}
|
|
34
28
|
}
|
|
35
|
-
function replaceWithNewElement(prevElement, nextElement, parentReference,
|
|
29
|
+
function replaceWithNewElement(prevElement, nextElement, parentReference, context, hostNamespace) {
|
|
36
30
|
unmount(prevElement);
|
|
37
31
|
nextElement.parent = prevElement.parent;
|
|
38
32
|
if (nextElement.flag === 'HOST' && prevElement.flag === 'HOST') {
|
|
39
|
-
mount(nextElement, null, null,
|
|
33
|
+
mount(nextElement, null, null, context, hostNamespace);
|
|
40
34
|
hostAdapter.replaceChild(parentReference, nextElement.reference, prevElement.reference);
|
|
41
35
|
}
|
|
42
36
|
else {
|
|
43
|
-
mount(nextElement, parentReference, findHostReferenceFromElement(prevElement),
|
|
37
|
+
mount(nextElement, parentReference, findHostReferenceFromElement(prevElement), context, hostNamespace);
|
|
44
38
|
clearElementHostReference(prevElement, parentReference);
|
|
45
39
|
}
|
|
46
40
|
}
|
|
47
|
-
function patchHostElement(prevElement, nextElement,
|
|
41
|
+
function patchHostElement(prevElement, nextElement, context, hostNamespace) {
|
|
48
42
|
if (prevElement.ref) {
|
|
49
43
|
nextElement.ref = prevElement.ref;
|
|
50
44
|
}
|
|
@@ -52,25 +46,32 @@ function patchHostElement(prevElement, nextElement, contextMap, hostNamespace) {
|
|
|
52
46
|
hostNamespace = hostNamespaces?.self;
|
|
53
47
|
nextElement.reference = prevElement.reference;
|
|
54
48
|
hostAdapter.attachElementToReference(nextElement, nextElement.reference);
|
|
55
|
-
patchChildren(prevElement.children || prevElement.props?.children, nextElement.children || nextElement.props?.children, nextElement.reference, null, nextElement,
|
|
49
|
+
patchChildren(prevElement.children || prevElement.props?.children, nextElement.children || nextElement.props?.children, nextElement.reference, null, nextElement, context, hostNamespaces?.children);
|
|
56
50
|
hostAdapter.patchProps(nextElement.reference, prevElement, nextElement, hostNamespace);
|
|
57
51
|
if (prevElement.className !== nextElement.className) {
|
|
58
52
|
hostAdapter.setClassname(nextElement.reference, nextElement.className, hostNamespace);
|
|
59
53
|
}
|
|
60
54
|
applyRef(nextElement);
|
|
61
55
|
}
|
|
62
|
-
function patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
: prevElement.store;
|
|
66
|
-
prevStore.latestElement = nextElement;
|
|
67
|
-
nextElement.store = prevStore;
|
|
56
|
+
function patchFunctionalComponent(prevElement, nextElement, parentReference, nextReference, context, hostNamespace) {
|
|
57
|
+
nextElement.store = prevElement.store || {};
|
|
58
|
+
nextElement.store.latestElement = nextElement;
|
|
68
59
|
if (hostNamespace) {
|
|
69
60
|
nextElement.store.hostNamespace = hostNamespace;
|
|
70
61
|
}
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
let forceRender = false;
|
|
63
|
+
if (prevElement.store?.forceRender) {
|
|
64
|
+
forceRender = true;
|
|
65
|
+
prevElement.store.forceRender = false;
|
|
73
66
|
}
|
|
67
|
+
if (prevElement.unmounted) {
|
|
68
|
+
mountFunctionalElement(nextElement, parentReference, nextReference, context, hostNamespace);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (!forceRender && isMemo(nextElement.type) && nextElement.type._compare(prevElement.props, nextElement.props)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
nextElement.context = prevElement.context || context;
|
|
74
75
|
// FC element always has Maybe<SimpElement> children due to normalization process.
|
|
75
76
|
let nextChildren;
|
|
76
77
|
let triedToRerenderUnsubscribe;
|
|
@@ -85,44 +86,29 @@ function patchFunctionalComponent(prevElement, nextElement, parentReference, nex
|
|
|
85
86
|
do {
|
|
86
87
|
triedToRerender = false;
|
|
87
88
|
if (++rerenderCounter >= 25) {
|
|
88
|
-
|
|
89
|
-
type: 'errored',
|
|
90
|
-
element: nextElement,
|
|
91
|
-
error: new Error('Too many re-renders. SimpReact limits the number of renders to prevent an infinite loop.'),
|
|
92
|
-
phase: 'updating',
|
|
93
|
-
});
|
|
94
|
-
return;
|
|
89
|
+
throw new Error('Too many re-renders.');
|
|
95
90
|
}
|
|
96
91
|
lifecycleEventBus.publish({ type: 'beforeRender', element: nextElement, phase: 'updating' });
|
|
97
|
-
batchingRerenderLocker.lock();
|
|
98
92
|
nextChildren = nextElement.type(nextElement.props || emptyObject);
|
|
99
|
-
batchingRerenderLocker.flush();
|
|
100
93
|
lifecycleEventBus.publish({ type: 'afterRender', element: nextElement, phase: 'updating' });
|
|
101
94
|
} while (triedToRerender);
|
|
102
95
|
nextChildren = normalizeRoot(nextChildren, false);
|
|
103
96
|
}
|
|
104
97
|
catch (error) {
|
|
105
98
|
lifecycleEventBus.publish({ type: 'errored', element: nextElement, error, phase: 'updating' });
|
|
99
|
+
remove(prevElement, parentReference);
|
|
106
100
|
return;
|
|
107
101
|
}
|
|
108
102
|
finally {
|
|
109
103
|
triedToRerenderUnsubscribe();
|
|
110
104
|
}
|
|
105
|
+
// Keep prevElement's children reference when prev and next elements are identical to avoid reassignment.
|
|
111
106
|
const prevChildren = prevElement.children;
|
|
112
107
|
if (nextChildren) {
|
|
113
108
|
nextElement.children = nextChildren;
|
|
114
109
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
lifecycleEventBus.publish({ type: 'updated', element: nextElement });
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
prevElement.unmounted = false;
|
|
121
|
-
if (nextChildren) {
|
|
122
|
-
nextChildren.parent = nextElement;
|
|
123
|
-
mount(nextChildren, parentReference, nextReference, contextMap, hostNamespace);
|
|
124
|
-
}
|
|
125
|
-
lifecycleEventBus.publish({ type: 'mounted', element: nextElement });
|
|
110
|
+
patchChildren(prevChildren, nextChildren, parentReference, nextReference, nextElement, nextElement.context, hostNamespace);
|
|
111
|
+
lifecycleEventBus.publish({ type: 'updated', element: nextElement });
|
|
126
112
|
}
|
|
127
113
|
function patchTextElement(prevElement, nextElement) {
|
|
128
114
|
nextElement.reference = prevElement.reference;
|
|
@@ -130,57 +116,41 @@ function patchTextElement(prevElement, nextElement) {
|
|
|
130
116
|
hostAdapter.setTextContent(nextElement.reference, nextElement.children);
|
|
131
117
|
}
|
|
132
118
|
}
|
|
133
|
-
function patchFragment(prevElement, nextElement, parentReference,
|
|
134
|
-
let nextReference = null;
|
|
135
|
-
if (Array.isArray(prevElement.children) && !Array.isArray(nextElement.children) && nextElement.children) {
|
|
136
|
-
nextReference = hostAdapter.findNextSiblingReference(findHostReferenceFromElement(prevElement.children[prevElement.children.length - 1]));
|
|
137
|
-
}
|
|
138
|
-
patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
|
|
139
|
-
}
|
|
140
|
-
function patchProvider(prevElement, nextElement, parentReference, contextMap, hostNamespace) {
|
|
119
|
+
function patchFragment(prevElement, nextElement, parentReference, context, hostNamespace) {
|
|
141
120
|
let nextReference = null;
|
|
142
121
|
if (Array.isArray(prevElement.children) && !Array.isArray(nextElement.children) && nextElement.children) {
|
|
143
122
|
nextReference = hostAdapter.findNextSiblingReference(findHostReferenceFromElement(prevElement.children[prevElement.children.length - 1]));
|
|
144
123
|
}
|
|
145
|
-
|
|
146
|
-
contextMap.set(nextElement.type.context, nextElement.props.value);
|
|
147
|
-
patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
|
|
148
|
-
}
|
|
149
|
-
function patchConsumer(prevElement, nextElement, parentReference, nextReference, contextMap, hostNamespace) {
|
|
150
|
-
const children = normalizeRoot(nextElement.type(nextElement.props || emptyObject, contextMap || emptyMap), false);
|
|
151
|
-
if (children) {
|
|
152
|
-
nextElement.children = children;
|
|
153
|
-
}
|
|
154
|
-
patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, contextMap, hostNamespace);
|
|
124
|
+
patchChildren(prevElement.children, nextElement.children, parentReference, nextReference, nextElement, context, hostNamespace);
|
|
155
125
|
}
|
|
156
|
-
export function patchPortal(prevElement, nextElement,
|
|
126
|
+
export function patchPortal(prevElement, nextElement, context) {
|
|
157
127
|
const prevContainer = prevElement.ref;
|
|
158
128
|
const nextContainer = nextElement.ref;
|
|
159
129
|
const nextChildren = nextElement.children;
|
|
160
|
-
patchChildren(prevElement.children, nextChildren, prevContainer, null, nextElement,
|
|
130
|
+
patchChildren(prevElement.children, nextChildren, prevContainer, null, nextElement, context, hostAdapter.getHostNamespaces(nextChildren, undefined)?.self);
|
|
161
131
|
nextElement.reference = prevElement.reference;
|
|
162
132
|
if (prevContainer !== nextContainer && nextChildren != null) {
|
|
163
133
|
hostAdapter.removeChild(prevContainer, nextChildren.reference);
|
|
164
134
|
hostAdapter.appendChild(nextContainer, nextChildren.reference);
|
|
165
135
|
}
|
|
166
136
|
}
|
|
167
|
-
export function updateFunctionalComponent(element, parentReference, nextReference,
|
|
168
|
-
patchFunctionalComponent(element, element, parentReference, nextReference,
|
|
137
|
+
export function updateFunctionalComponent(element, parentReference, nextReference, context, hostNamespace) {
|
|
138
|
+
patchFunctionalComponent(element, element, parentReference, nextReference, context, hostNamespace);
|
|
169
139
|
}
|
|
170
|
-
function patchChildren(prevChildren, nextChildren, parentReference, nextReference, nextElement,
|
|
140
|
+
function patchChildren(prevChildren, nextChildren, parentReference, nextReference, nextElement, context, hostNamespace) {
|
|
171
141
|
if (Array.isArray(prevChildren)) {
|
|
172
142
|
if (Array.isArray(nextChildren)) {
|
|
173
143
|
for (const child of nextChildren) {
|
|
174
144
|
child.parent = nextElement;
|
|
175
145
|
}
|
|
176
|
-
patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference,
|
|
146
|
+
patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference, context, hostNamespace);
|
|
177
147
|
}
|
|
178
148
|
else if (typeof nextChildren === 'string') {
|
|
179
149
|
unmount(prevChildren);
|
|
180
150
|
hostAdapter.setTextContent(parentReference, nextChildren);
|
|
181
151
|
}
|
|
182
152
|
else if (nextChildren) {
|
|
183
|
-
patchKeyedChildren(prevChildren, [nextChildren], parentReference, nextReference,
|
|
153
|
+
patchKeyedChildren(prevChildren, [nextChildren], parentReference, nextReference, context, hostNamespace);
|
|
184
154
|
}
|
|
185
155
|
else {
|
|
186
156
|
unmount(prevChildren);
|
|
@@ -190,7 +160,7 @@ function patchChildren(prevChildren, nextChildren, parentReference, nextReferenc
|
|
|
190
160
|
else if (typeof prevChildren === 'string') {
|
|
191
161
|
if (Array.isArray(nextChildren)) {
|
|
192
162
|
hostAdapter.clearNode(parentReference);
|
|
193
|
-
mountArrayChildren(nextChildren, parentReference, nextReference,
|
|
163
|
+
mountArrayChildren(nextChildren, parentReference, nextReference, context, nextElement, hostNamespace);
|
|
194
164
|
}
|
|
195
165
|
else if (typeof nextChildren === 'string') {
|
|
196
166
|
if (prevChildren !== nextChildren) {
|
|
@@ -200,7 +170,7 @@ function patchChildren(prevChildren, nextChildren, parentReference, nextReferenc
|
|
|
200
170
|
else if (nextChildren) {
|
|
201
171
|
hostAdapter.clearNode(parentReference);
|
|
202
172
|
nextChildren.parent = nextElement;
|
|
203
|
-
mount(nextChildren, parentReference, nextReference,
|
|
173
|
+
mount(nextChildren, parentReference, nextReference, context, hostNamespace);
|
|
204
174
|
}
|
|
205
175
|
else {
|
|
206
176
|
hostAdapter.clearNode(parentReference);
|
|
@@ -208,7 +178,7 @@ function patchChildren(prevChildren, nextChildren, parentReference, nextReferenc
|
|
|
208
178
|
}
|
|
209
179
|
else if (prevChildren) {
|
|
210
180
|
if (Array.isArray(nextChildren)) {
|
|
211
|
-
patchKeyedChildren([prevChildren], nextChildren, parentReference, nextReference,
|
|
181
|
+
patchKeyedChildren([prevChildren], nextChildren, parentReference, nextReference, context, hostNamespace);
|
|
212
182
|
}
|
|
213
183
|
else if (typeof nextChildren === 'string') {
|
|
214
184
|
unmount(prevChildren);
|
|
@@ -216,7 +186,7 @@ function patchChildren(prevChildren, nextChildren, parentReference, nextReferenc
|
|
|
216
186
|
}
|
|
217
187
|
else if (nextChildren) {
|
|
218
188
|
nextChildren.parent = nextElement;
|
|
219
|
-
patch(prevChildren, nextChildren, parentReference, nextReference,
|
|
189
|
+
patch(prevChildren, nextChildren, parentReference, nextReference, context, hostNamespace);
|
|
220
190
|
}
|
|
221
191
|
else {
|
|
222
192
|
remove(prevChildren, parentReference);
|
|
@@ -224,18 +194,18 @@ function patchChildren(prevChildren, nextChildren, parentReference, nextReferenc
|
|
|
224
194
|
}
|
|
225
195
|
else {
|
|
226
196
|
if (Array.isArray(nextChildren)) {
|
|
227
|
-
mountArrayChildren(nextChildren, parentReference, nextReference,
|
|
197
|
+
mountArrayChildren(nextChildren, parentReference, nextReference, context, nextElement, hostNamespace);
|
|
228
198
|
}
|
|
229
199
|
else if (typeof nextChildren === 'string') {
|
|
230
200
|
hostAdapter.setTextContent(parentReference, nextChildren);
|
|
231
201
|
}
|
|
232
202
|
else if (nextChildren) {
|
|
233
203
|
nextChildren.parent = nextElement;
|
|
234
|
-
mount(nextChildren, parentReference, nextReference,
|
|
204
|
+
mount(nextChildren, parentReference, nextReference, context, hostNamespace);
|
|
235
205
|
}
|
|
236
206
|
}
|
|
237
207
|
}
|
|
238
|
-
export function patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference,
|
|
208
|
+
export function patchKeyedChildren(prevChildren, nextChildren, parentReference, nextReference, context, hostNamespace) {
|
|
239
209
|
let prevStart = 0;
|
|
240
210
|
let nextStart = 0;
|
|
241
211
|
let prevEnd = prevChildren.length - 1;
|
|
@@ -244,13 +214,13 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
|
|
|
244
214
|
while (prevStart <= prevEnd &&
|
|
245
215
|
nextStart <= nextEnd &&
|
|
246
216
|
prevChildren[prevStart].key === nextChildren[nextStart].key) {
|
|
247
|
-
patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null,
|
|
217
|
+
patch(prevChildren[prevStart], nextChildren[nextStart], parentReference, null, context, hostNamespace);
|
|
248
218
|
prevStart++;
|
|
249
219
|
nextStart++;
|
|
250
220
|
}
|
|
251
221
|
// Step 2: Sync from end
|
|
252
222
|
while (prevStart <= prevEnd && nextStart <= nextEnd && prevChildren[prevEnd].key === nextChildren[nextEnd].key) {
|
|
253
|
-
patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null,
|
|
223
|
+
patch(prevChildren[prevEnd], nextChildren[nextEnd], parentReference, null, context, hostNamespace);
|
|
254
224
|
prevEnd--;
|
|
255
225
|
nextEnd--;
|
|
256
226
|
}
|
|
@@ -258,7 +228,7 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
|
|
|
258
228
|
if (prevStart > prevEnd) {
|
|
259
229
|
const before = findHostReferenceFromElement(nextChildren[nextEnd + 1]) || nextReference;
|
|
260
230
|
for (let i = nextStart; i <= nextEnd; i++) {
|
|
261
|
-
mount(nextChildren[i], parentReference, before,
|
|
231
|
+
mount(nextChildren[i], parentReference, before, context, hostNamespace);
|
|
262
232
|
}
|
|
263
233
|
// Step 4: Remove prev nodes if next list is exhausted
|
|
264
234
|
}
|
|
@@ -286,12 +256,12 @@ export function patchKeyedChildren(prevChildren, nextChildren, parentReference,
|
|
|
286
256
|
const prevIndex = keyToPrevIndexMap.get(nextChild.key);
|
|
287
257
|
if (prevIndex != null) {
|
|
288
258
|
const prevElement = prevChildren[prevIndex];
|
|
289
|
-
patch(prevElement, nextChild, parentReference, null,
|
|
259
|
+
patch(prevElement, nextChild, parentReference, null, context, hostNamespace);
|
|
290
260
|
toMove[i - nextStart] = prevIndex;
|
|
291
261
|
usedIndices.add(prevIndex);
|
|
292
262
|
}
|
|
293
263
|
else {
|
|
294
|
-
mount(nextChild, parentReference, findHostReferenceFromElement(nextChildren[i + 1]) || nextReference,
|
|
264
|
+
mount(nextChild, parentReference, findHostReferenceFromElement(nextChildren[i + 1]) || nextReference, context, hostNamespace);
|
|
295
265
|
toMove[i - nextStart] = -1;
|
|
296
266
|
}
|
|
297
267
|
}
|
package/core/rerender.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { SimpElement } from './createElement.js';
|
|
1
|
+
import type { SimpElement, SimpElementStore } from './createElement.js';
|
|
2
2
|
export declare function rerender(element: SimpElement): void;
|
|
3
3
|
interface IRendererLocker {
|
|
4
4
|
_isLocked: boolean;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
_elementStores: Set<SimpElementStore>;
|
|
6
|
+
_last: SimpElementStore | undefined;
|
|
7
|
+
_track(element: SimpElementStore): void;
|
|
8
|
+
_untrack(element: SimpElementStore): void;
|
|
8
9
|
lock(): void;
|
|
9
10
|
flush(): void;
|
|
10
11
|
}
|
package/core/rerender.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { findParentReferenceFromElement, updateFunctionalComponent } from './patching.js';
|
|
2
2
|
import { lifecycleEventBus } from './lifecycleEventBus.js';
|
|
3
3
|
lifecycleEventBus.subscribe(event => {
|
|
4
|
-
if (event.type === 'afterRender') {
|
|
5
|
-
batchingRerenderLocker._untrack(event.element);
|
|
6
|
-
renderingRerenderLocker._untrack(event.element);
|
|
4
|
+
if (event.type === 'afterRender' || event.type === 'errored' || event.type === 'unmounted') {
|
|
5
|
+
batchingRerenderLocker._untrack(event.element.store);
|
|
6
|
+
renderingRerenderLocker._untrack(event.element.store);
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
9
|
export function rerender(element) {
|
|
@@ -15,62 +15,114 @@ export function rerender(element) {
|
|
|
15
15
|
}
|
|
16
16
|
lifecycleEventBus.publish({ type: 'triedToRerender', element });
|
|
17
17
|
if (batchingRerenderLocker._isLocked) {
|
|
18
|
-
batchingRerenderLocker._track(element);
|
|
18
|
+
batchingRerenderLocker._track(element.store);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
if (renderingRerenderLocker._isLocked) {
|
|
22
|
-
renderingRerenderLocker._track(element);
|
|
22
|
+
renderingRerenderLocker._track(element.store);
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
renderingRerenderLocker.lock();
|
|
26
|
-
updateFunctionalComponent(element, findParentReferenceFromElement(element), null, element.
|
|
26
|
+
updateFunctionalComponent(element, findParentReferenceFromElement(element), null, element.context || null, element.store.hostNamespace);
|
|
27
27
|
renderingRerenderLocker.flush();
|
|
28
28
|
}
|
|
29
29
|
export const batchingRerenderLocker = {
|
|
30
30
|
_isLocked: false,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
_elementStores: new Set(),
|
|
32
|
+
_last: undefined,
|
|
33
|
+
_track(store) {
|
|
34
|
+
if (this._elementStores.has(store)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (this._elementStores.size === 0 || store.forceRender) {
|
|
38
|
+
this._elementStores.add(store);
|
|
39
|
+
this._last = store;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (isParentOf(store.latestElement, this._last.latestElement)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (isParentOf(this._last.latestElement, store.latestElement)) {
|
|
46
|
+
this._elementStores.clear();
|
|
47
|
+
this._elementStores.add(store);
|
|
48
|
+
this._last = store;
|
|
49
|
+
}
|
|
34
50
|
},
|
|
35
|
-
_untrack(
|
|
36
|
-
this.
|
|
51
|
+
_untrack(store) {
|
|
52
|
+
if (this._elementStores.delete(store) && store === this._last) {
|
|
53
|
+
this._last = undefined;
|
|
54
|
+
for (const val of this._elementStores) {
|
|
55
|
+
this._last = val;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
37
58
|
},
|
|
38
59
|
lock() {
|
|
39
60
|
this._isLocked = true;
|
|
40
61
|
},
|
|
41
62
|
flush() {
|
|
42
63
|
this._isLocked = false;
|
|
43
|
-
if (this.
|
|
64
|
+
if (this._elementStores.size === 0) {
|
|
44
65
|
return;
|
|
45
66
|
}
|
|
46
|
-
for (const
|
|
47
|
-
this._untrack(
|
|
48
|
-
rerender(
|
|
67
|
+
for (const store of this._elementStores) {
|
|
68
|
+
this._untrack(store);
|
|
69
|
+
rerender(store.latestElement);
|
|
49
70
|
}
|
|
50
71
|
},
|
|
51
72
|
};
|
|
52
73
|
export const renderingRerenderLocker = {
|
|
53
74
|
_isLocked: false,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
_elementStores: new Set(),
|
|
76
|
+
_last: undefined,
|
|
77
|
+
_track(store) {
|
|
78
|
+
if (this._elementStores.has(store)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (this._elementStores.size === 0 || store.forceRender) {
|
|
82
|
+
this._elementStores.add(store);
|
|
83
|
+
this._last = store;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (isParentOf(store.latestElement, this._last.latestElement)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (isParentOf(this._last.latestElement, store.latestElement)) {
|
|
90
|
+
this._elementStores.clear();
|
|
91
|
+
this._elementStores.add(store);
|
|
92
|
+
this._last = store;
|
|
93
|
+
}
|
|
57
94
|
},
|
|
58
|
-
_untrack(
|
|
59
|
-
this.
|
|
95
|
+
_untrack(store) {
|
|
96
|
+
if (this._elementStores.delete(store) && store === this._last) {
|
|
97
|
+
this._last = undefined;
|
|
98
|
+
for (const val of this._elementStores) {
|
|
99
|
+
this._last = val;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
60
102
|
},
|
|
61
103
|
lock() {
|
|
62
104
|
this._isLocked = true;
|
|
63
105
|
},
|
|
64
106
|
flush() {
|
|
65
107
|
this._isLocked = false;
|
|
66
|
-
if (this.
|
|
108
|
+
if (this._elementStores.size === 0) {
|
|
67
109
|
return;
|
|
68
110
|
}
|
|
69
111
|
queueMicrotask(() => {
|
|
70
|
-
for (const
|
|
71
|
-
this._untrack(
|
|
72
|
-
rerender(
|
|
112
|
+
for (const store of this._elementStores) {
|
|
113
|
+
this._untrack(store);
|
|
114
|
+
rerender(store.latestElement);
|
|
73
115
|
}
|
|
74
116
|
});
|
|
75
117
|
},
|
|
76
118
|
};
|
|
119
|
+
function isParentOf(element, parent) {
|
|
120
|
+
let current = element.parent;
|
|
121
|
+
while (current) {
|
|
122
|
+
if (current.store === parent.store) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
current = current.parent;
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
}
|
package/core/unmounting.js
CHANGED
|
@@ -28,7 +28,7 @@ export function unmount(element) {
|
|
|
28
28
|
remove(element.children, element.ref);
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
|
-
// Only FRAGMENT
|
|
31
|
+
// Only FRAGMENT and HOST elements remain,
|
|
32
32
|
// with Maybe<Many<SimpElement>> children due to normalization.
|
|
33
33
|
if (element.children) {
|
|
34
34
|
unmount(element.children);
|
|
@@ -45,11 +45,11 @@ export function clearElementHostReference(element, parentHostReference) {
|
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
const children = element.children;
|
|
48
|
-
if (element.flag === 'FC'
|
|
48
|
+
if (element.flag === 'FC') {
|
|
49
49
|
element = children;
|
|
50
50
|
continue;
|
|
51
51
|
}
|
|
52
|
-
if (element.flag === 'FRAGMENT'
|
|
52
|
+
if (element.flag === 'FRAGMENT') {
|
|
53
53
|
if (Array.isArray(children)) {
|
|
54
54
|
for (let i = 0, len = children.length; i < len; ++i) {
|
|
55
55
|
clearElementHostReference(children[i], parentHostReference);
|
|
@@ -5,5 +5,14 @@ export function attachElementToDom(element, dom) {
|
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
export function getElementFromDom(target) {
|
|
8
|
-
|
|
8
|
+
if (!target) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
while (target && !(elementPropertyName in target)) {
|
|
12
|
+
target = target.parentElement;
|
|
13
|
+
}
|
|
14
|
+
if (!target) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return target[elementPropertyName];
|
|
9
18
|
}
|
package/dom/events.d.ts
CHANGED
|
@@ -4,15 +4,20 @@ export declare class SyntheticEvent {
|
|
|
4
4
|
nativeEvent: Event;
|
|
5
5
|
currentTarget: Nullable<EventTarget>;
|
|
6
6
|
isPropagationStopped: boolean;
|
|
7
|
-
|
|
7
|
+
_isDefaultPrevented: boolean;
|
|
8
8
|
button?: number;
|
|
9
9
|
buttons?: number;
|
|
10
10
|
pointerId?: number;
|
|
11
|
+
altKey?: boolean;
|
|
12
|
+
ctrlKey?: boolean;
|
|
13
|
+
shiftKey?: boolean;
|
|
14
|
+
metaKey?: boolean;
|
|
11
15
|
constructor(event: Event);
|
|
12
16
|
get target(): EventTarget | null;
|
|
13
17
|
get type(): string;
|
|
14
18
|
stopPropagation(): void;
|
|
15
19
|
preventDefault(): void;
|
|
20
|
+
isDefaultPrevented(): boolean;
|
|
16
21
|
}
|
|
17
22
|
export declare function dispatchDelegatedEvent(event: Event): void;
|
|
18
23
|
export declare function patchEvent(name: string, prevValue: any, nextValue: any, dom: Element): void;
|
package/dom/events.js
CHANGED
|
@@ -39,15 +39,22 @@ export class SyntheticEvent {
|
|
|
39
39
|
nativeEvent;
|
|
40
40
|
currentTarget = null;
|
|
41
41
|
isPropagationStopped = false;
|
|
42
|
-
|
|
42
|
+
_isDefaultPrevented = false;
|
|
43
43
|
button;
|
|
44
44
|
buttons;
|
|
45
45
|
pointerId;
|
|
46
|
+
altKey;
|
|
47
|
+
ctrlKey;
|
|
48
|
+
shiftKey;
|
|
49
|
+
metaKey;
|
|
46
50
|
constructor(event) {
|
|
47
51
|
this.nativeEvent = event;
|
|
48
52
|
this.button = event.button;
|
|
49
53
|
this.buttons = event.buttons;
|
|
50
54
|
this.pointerId = event.pointerId;
|
|
55
|
+
this.altKey = event.altKey;
|
|
56
|
+
this.ctrlKey = event.ctrlKey;
|
|
57
|
+
this.metaKey = event.metaKey;
|
|
51
58
|
}
|
|
52
59
|
get target() {
|
|
53
60
|
return this.nativeEvent.target;
|
|
@@ -60,9 +67,12 @@ export class SyntheticEvent {
|
|
|
60
67
|
this.nativeEvent.stopPropagation();
|
|
61
68
|
}
|
|
62
69
|
preventDefault() {
|
|
63
|
-
this.
|
|
70
|
+
this._isDefaultPrevented = true;
|
|
64
71
|
this.nativeEvent.preventDefault();
|
|
65
72
|
}
|
|
73
|
+
isDefaultPrevented() {
|
|
74
|
+
return this._isDefaultPrevented;
|
|
75
|
+
}
|
|
66
76
|
}
|
|
67
77
|
export function dispatchDelegatedEvent(event) {
|
|
68
78
|
batchingRerenderLocker.lock();
|
package/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RefObject
|
|
1
|
+
import type { RefObject } from '../core/index.js';
|
|
2
2
|
|
|
3
3
|
export type Cleanup = () => void;
|
|
4
4
|
export type Effect = () => void | Cleanup;
|
|
@@ -22,8 +22,6 @@ declare function useMounted(effect: Effect): void;
|
|
|
22
22
|
|
|
23
23
|
declare function useUnmounted(cleanup: Cleanup): void;
|
|
24
24
|
|
|
25
|
-
declare function useContext<T>(context: SimpContext<T>): T;
|
|
26
|
-
|
|
27
25
|
declare function useCatch(cb: (error: any) => void): void;
|
|
28
26
|
|
|
29
27
|
declare function areDepsEqual(nextDeps: DependencyList | undefined, prevDeps: DependencyList | undefined): boolean;
|