round-core 0.0.2 → 0.0.3
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/LICENSE +21 -0
- package/Round.png +0 -0
- package/logo.svg +9 -72
- package/package.json +1 -1
- package/src/compiler/transformer.js +61 -2
- package/src/runtime/context.js +17 -1
- package/src/runtime/dom.js +76 -42
- package/src/runtime/suspense.js +39 -17
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 ZtaMDev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/Round.png
CHANGED
|
Binary file
|
package/logo.svg
CHANGED
|
@@ -1,73 +1,10 @@
|
|
|
1
|
-
<svg width="
|
|
2
|
-
<defs>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<stop offset="
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<!-- Efecto de sombra para las órbitas -->
|
|
11
|
-
<filter id="dropShadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
12
|
-
<feDropShadow dx="2" dy="2" stdDeviation="3" flood-color="#000000" flood-opacity="0.2"/>
|
|
13
|
-
</filter>
|
|
14
|
-
|
|
15
|
-
<!-- Gradiente con brillo para azul -->
|
|
16
|
-
<linearGradient id="blueGlow" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
17
|
-
<stop offset="0%" stop-color="#1a4fd8"/>
|
|
18
|
-
<stop offset="30%" stop-color="#4a7dff"/>
|
|
19
|
-
<stop offset="70%" stop-color="#2962FF"/>
|
|
20
|
-
<stop offset="100%" stop-color="#1a4fd8"/>
|
|
21
|
-
</linearGradient>
|
|
22
|
-
|
|
23
|
-
<!-- Gradiente con brillo para verde -->
|
|
24
|
-
<linearGradient id="greenGlow" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
25
|
-
<stop offset="0%" stop-color="#00b894"/>
|
|
26
|
-
<stop offset="30%" stop-color="#00ffc3"/>
|
|
27
|
-
<stop offset="70%" stop-color="#00D8A7"/>
|
|
28
|
-
<stop offset="100%" stop-color="#00b894"/>
|
|
29
|
-
</linearGradient>
|
|
30
|
-
</defs>
|
|
31
|
-
|
|
32
|
-
<!-- Fondo sutil circular -->
|
|
33
|
-
<circle cx="100" cy="100" r="90" fill="url(#blueGlow)" opacity="0.05"/>
|
|
34
|
-
|
|
35
|
-
<!-- Órbita exterior con efecto de neón -->
|
|
36
|
-
<path d="M40,100 Q100,30 160,100 Q100,170 40,100"
|
|
37
|
-
fill="none"
|
|
38
|
-
stroke="url(#blueGlow)"
|
|
39
|
-
stroke-width="10"
|
|
40
|
-
stroke-linecap="round"
|
|
41
|
-
filter="url(#dropShadow)"
|
|
42
|
-
style="mix-blend-mode: screen"/>
|
|
43
|
-
|
|
44
|
-
<!-- Órbita media con efecto brillante -->
|
|
45
|
-
<path d="M60,100 Q100,50 140,100 Q100,150 60,100"
|
|
46
|
-
fill="none"
|
|
47
|
-
stroke="url(#greenGlow)"
|
|
48
|
-
stroke-width="10"
|
|
49
|
-
stroke-linecap="round"
|
|
50
|
-
filter="url(#dropShadow)"
|
|
51
|
-
style="mix-blend-mode: screen"/>
|
|
52
|
-
|
|
53
|
-
<!-- Núcleo con efecto 3D marcado -->
|
|
54
|
-
<circle cx="100" cy="100" r="22" fill="url(#nucleusGradient)">
|
|
55
|
-
<feDropShadow dx="0" dy="0" stdDeviation="8" flood-color="#00ffaa" flood-opacity="0.4"/>
|
|
56
|
-
</circle>
|
|
57
|
-
|
|
58
|
-
<!-- Reflejo superior en el núcleo -->
|
|
59
|
-
<ellipse cx="95" cy="90" rx="8" ry="5" fill="#ffffff" opacity="0.4"/>
|
|
60
|
-
|
|
61
|
-
<!-- Puntos de energía sutilmente distribuidos -->
|
|
62
|
-
<g opacity="0.6">
|
|
63
|
-
<circle cx="170" cy="100" r="3" fill="#4a7dff"/>
|
|
64
|
-
<circle cx="100" cy="170" r="3" fill="#4a7dff"/>
|
|
65
|
-
<circle cx="30" cy="100" r="3" fill="#4a7dff"/>
|
|
66
|
-
<circle cx="100" cy="30" r="3" fill="#4a7dff"/>
|
|
67
|
-
|
|
68
|
-
<circle cx="140" cy="140" r="2.5" fill="#00ffc3"/>
|
|
69
|
-
<circle cx="60" cy="140" r="2.5" fill="#00ffc3"/>
|
|
70
|
-
<circle cx="140" cy="60" r="2.5" fill="#00ffc3"/>
|
|
71
|
-
<circle cx="60" cy="60" r="2.5" fill="#00ffc3"/>
|
|
72
|
-
</g>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 16 16">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#6d28d9"/>
|
|
5
|
+
<stop offset="1" stop-color="#16a34a"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect x="1" y="1" width="14" height="14" rx="4" fill="#ffffff" stroke="url(#g)" stroke-width="1.25"/>
|
|
9
|
+
<path d="M5.2 11.3V4.7h2.65c.9 0 1.62.2 2.16.62.55.41.82 1.02.82 1.82 0 .56-.14 1.02-.43 1.37-.28.35-.68.6-1.18.73l1.6 2.06H9.58L8.15 9.45H6.45v1.85H5.2zm1.25-2.9h1.3c.55 0 .96-.1 1.22-.32.26-.22.4-.55.4-.99 0-.44-.13-.76-.39-.96-.26-.2-.67-.3-1.23-.3H6.45v2.57z" fill="#111827"/>
|
|
73
10
|
</svg>
|
package/package.json
CHANGED
|
@@ -12,11 +12,70 @@ export function transform(code) {
|
|
|
12
12
|
let startBlockIndex = -1;
|
|
13
13
|
let endBlockIndex = -1;
|
|
14
14
|
|
|
15
|
+
let inSingle = false;
|
|
16
|
+
let inDouble = false;
|
|
17
|
+
let inTemplate = false;
|
|
18
|
+
let inCommentLine = false;
|
|
19
|
+
let inCommentMulti = false;
|
|
20
|
+
|
|
15
21
|
for (let i = startIndex; i < str.length; i++) {
|
|
16
|
-
|
|
22
|
+
const ch = str[i];
|
|
23
|
+
const prev = i > 0 ? str[i - 1] : '';
|
|
24
|
+
const next = i < str.length - 1 ? str[i + 1] : '';
|
|
25
|
+
|
|
26
|
+
// Handle strings and comments
|
|
27
|
+
if (inCommentLine) {
|
|
28
|
+
if (ch === '\n' || ch === '\r') inCommentLine = false;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (inCommentMulti) {
|
|
32
|
+
if (ch === '*' && next === '/') {
|
|
33
|
+
inCommentMulti = false;
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (inTemplate) {
|
|
39
|
+
if (ch === '`' && prev !== '\\') inTemplate = false;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (inSingle) {
|
|
43
|
+
if (ch === '\'' && prev !== '\\') inSingle = false;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (inDouble) {
|
|
47
|
+
if (ch === '"' && prev !== '\\') inDouble = false;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Check for start of strings/comments
|
|
52
|
+
if (ch === '/' && next === '/') {
|
|
53
|
+
inCommentLine = true;
|
|
54
|
+
i++;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (ch === '/' && next === '*') {
|
|
58
|
+
inCommentMulti = true;
|
|
59
|
+
i++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (ch === '`') {
|
|
63
|
+
inTemplate = true;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (ch === '\'') {
|
|
67
|
+
inSingle = true;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (ch === '"') {
|
|
71
|
+
inDouble = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (ch === '{') {
|
|
17
76
|
if (open === 0) startBlockIndex = i;
|
|
18
77
|
open++;
|
|
19
|
-
} else if (
|
|
78
|
+
} else if (ch === '}') {
|
|
20
79
|
open--;
|
|
21
80
|
if (open === 0) {
|
|
22
81
|
endBlockIndex = i;
|
package/src/runtime/context.js
CHANGED
|
@@ -11,7 +11,7 @@ function popContext() {
|
|
|
11
11
|
contextStack.pop();
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
function readContext(ctx) {
|
|
14
|
+
export function readContext(ctx) {
|
|
15
15
|
for (let i = contextStack.length - 1; i >= 0; i--) {
|
|
16
16
|
const layer = contextStack[i];
|
|
17
17
|
if (layer && Object.prototype.hasOwnProperty.call(layer, ctx.id)) {
|
|
@@ -60,3 +60,19 @@ export function bindContext(ctx) {
|
|
|
60
60
|
return provided;
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
export function captureContext() {
|
|
65
|
+
return contextStack.slice();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function runInContext(snapshot, fn) {
|
|
69
|
+
const prev = contextStack.slice();
|
|
70
|
+
contextStack.length = 0;
|
|
71
|
+
contextStack.push(...snapshot);
|
|
72
|
+
try {
|
|
73
|
+
return fn();
|
|
74
|
+
} finally {
|
|
75
|
+
contextStack.length = 0;
|
|
76
|
+
contextStack.push(...prev);
|
|
77
|
+
}
|
|
78
|
+
}
|
package/src/runtime/dom.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { effect, untrack } from './signals.js';
|
|
2
|
-
import { runInContext, createComponentInstance, mountComponent, initLifecycleRoot } from './lifecycle.js';
|
|
2
|
+
import { runInContext as runInLifecycle, createComponentInstance, mountComponent, initLifecycleRoot } from './lifecycle.js';
|
|
3
3
|
import { reportErrorSafe } from './error-reporter.js';
|
|
4
|
+
import { captureContext, runInContext, readContext } from './context.js';
|
|
5
|
+
import { SuspenseContext } from './suspense.js';
|
|
6
|
+
|
|
4
7
|
|
|
5
8
|
let isObserverInitialized = false;
|
|
6
9
|
|
|
@@ -32,14 +35,20 @@ export function createElement(tag, props = {}, ...children) {
|
|
|
32
35
|
const componentName = tag?.name ?? 'Anonymous';
|
|
33
36
|
componentInstance.name = componentName;
|
|
34
37
|
|
|
35
|
-
let node =
|
|
38
|
+
let node = runInLifecycle(componentInstance, () => {
|
|
36
39
|
const componentProps = { ...props, children };
|
|
37
40
|
try {
|
|
38
41
|
const res = untrack(() => tag(componentProps));
|
|
39
42
|
if (isPromiseLike(res)) throw res;
|
|
40
43
|
return res;
|
|
41
44
|
} catch (e) {
|
|
42
|
-
if (isPromiseLike(e))
|
|
45
|
+
if (isPromiseLike(e)) {
|
|
46
|
+
const suspense = readContext(SuspenseContext);
|
|
47
|
+
if (!suspense) {
|
|
48
|
+
throw new Error("cannot instance a lazy component outside a suspense");
|
|
49
|
+
}
|
|
50
|
+
throw e;
|
|
51
|
+
}
|
|
43
52
|
reportErrorSafe(e, { phase: 'component.render', component: componentName });
|
|
44
53
|
return createElement('div', { style: { padding: '16px' } }, `Error in ${componentName}`);
|
|
45
54
|
}
|
|
@@ -65,6 +74,20 @@ export function createElement(tag, props = {}, ...children) {
|
|
|
65
74
|
return node;
|
|
66
75
|
}
|
|
67
76
|
|
|
77
|
+
if (typeof tag === 'string') {
|
|
78
|
+
const isCustomElement = tag.includes('-');
|
|
79
|
+
// Simple check: if it looks like a component (no hyphen, lowercase start)
|
|
80
|
+
// and it's not a standard tag, it's likely an error.
|
|
81
|
+
// We use a small heuristic list or regex.
|
|
82
|
+
// Actually, user requested: "custom components when they start with lowercase... should give error".
|
|
83
|
+
// Using a whitelist of standard tags is robust.
|
|
84
|
+
const isStandard = /^(a|abbr|address|area|article|aside|audio|b|base|bdi|bdo|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|data|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|main|map|mark|meta|meter|nav|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|slot|small|source|span|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|u|ul|var|video|wbr|path|circle|rect|line|g|defs|linearGradient|stop|radialGradient|text|tspan)$/.test(tag);
|
|
85
|
+
|
|
86
|
+
if (!isCustomElement && !isStandard && /^[a-z]/.test(tag)) {
|
|
87
|
+
throw new Error(`Component names must start with an uppercase letter: <${tag} />`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
68
91
|
const element = document.createElement(tag);
|
|
69
92
|
|
|
70
93
|
if (props) {
|
|
@@ -282,54 +305,65 @@ function appendChild(parent, child) {
|
|
|
282
305
|
|
|
283
306
|
let currentNode = placeholder;
|
|
284
307
|
|
|
285
|
-
|
|
286
|
-
let val;
|
|
287
|
-
try {
|
|
288
|
-
val = child();
|
|
289
|
-
if (isPromiseLike(val)) throw val;
|
|
290
|
-
} catch (e) {
|
|
291
|
-
if (isPromiseLike(e)) throw e;
|
|
292
|
-
reportErrorSafe(e, { phase: 'child.dynamic' });
|
|
293
|
-
val = createElement('div', { style: { padding: '16px' } }, 'Error');
|
|
294
|
-
}
|
|
308
|
+
const ctxSnapshot = captureContext();
|
|
295
309
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (
|
|
302
|
-
|
|
303
|
-
|
|
310
|
+
effect(() => {
|
|
311
|
+
runInContext(ctxSnapshot, () => {
|
|
312
|
+
let val;
|
|
313
|
+
try {
|
|
314
|
+
val = child();
|
|
315
|
+
if (isPromiseLike(val)) throw val;
|
|
316
|
+
} catch (e) {
|
|
317
|
+
if (isPromiseLike(e)) {
|
|
318
|
+
const suspense = readContext(SuspenseContext);
|
|
319
|
+
if (suspense && typeof suspense.register === 'function') {
|
|
320
|
+
suspense.register(e);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
throw new Error("cannot instance a lazy component outside a suspense");
|
|
304
324
|
}
|
|
325
|
+
reportErrorSafe(e, { phase: 'child.dynamic' });
|
|
326
|
+
val = createElement('div', { style: { padding: '16px' } }, 'Error');
|
|
305
327
|
}
|
|
306
328
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
329
|
+
if (Array.isArray(val)) {
|
|
330
|
+
if (!(currentNode instanceof Element) || !currentNode._roundArrayWrapper) {
|
|
331
|
+
const wrapper = document.createElement('span');
|
|
332
|
+
wrapper.style.display = 'contents';
|
|
333
|
+
wrapper._roundArrayWrapper = true;
|
|
334
|
+
if (currentNode.parentNode) {
|
|
335
|
+
currentNode.parentNode.replaceChild(wrapper, currentNode);
|
|
336
|
+
currentNode = wrapper;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
311
339
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
340
|
+
while (currentNode.firstChild) currentNode.removeChild(currentNode.firstChild);
|
|
341
|
+
val.forEach(v => appendChild(currentNode, v));
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (val instanceof Node) {
|
|
346
|
+
if (currentNode !== val) {
|
|
347
|
+
if (currentNode.parentNode) {
|
|
348
|
+
currentNode.parentNode.replaceChild(val, currentNode);
|
|
349
|
+
currentNode = val;
|
|
350
|
+
}
|
|
317
351
|
}
|
|
318
352
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
353
|
+
else {
|
|
354
|
+
const textContent = (val === null || val === undefined) ? '' : val;
|
|
355
|
+
|
|
356
|
+
if (currentNode instanceof Element) {
|
|
357
|
+
const newText = document.createTextNode(textContent);
|
|
358
|
+
if (currentNode.parentNode) {
|
|
359
|
+
currentNode.parentNode.replaceChild(newText, currentNode);
|
|
360
|
+
currentNode = newText;
|
|
361
|
+
}
|
|
362
|
+
} else {
|
|
363
|
+
currentNode.textContent = textContent;
|
|
328
364
|
}
|
|
329
|
-
} else {
|
|
330
|
-
currentNode.textContent = textContent;
|
|
331
365
|
}
|
|
332
|
-
}
|
|
366
|
+
});
|
|
333
367
|
}, { onLoad: false });
|
|
334
368
|
return;
|
|
335
369
|
}
|
package/src/runtime/suspense.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { signal } from './signals.js';
|
|
2
2
|
import { createElement, Fragment } from './dom.js';
|
|
3
|
+
import { createContext } from './context.js';
|
|
3
4
|
|
|
4
5
|
function isPromiseLike(v) {
|
|
5
6
|
return v && (typeof v === 'object' || typeof v === 'function') && typeof v.then === 'function';
|
|
6
7
|
}
|
|
7
8
|
|
|
9
|
+
const SuspenseContext = createContext(null);
|
|
10
|
+
export { SuspenseContext };
|
|
11
|
+
|
|
8
12
|
export function lazy(loader) {
|
|
9
13
|
if (typeof loader !== 'function') {
|
|
10
14
|
throw new Error('lazy(loader) expects a function that returns a Promise');
|
|
@@ -67,37 +71,55 @@ export function lazy(loader) {
|
|
|
67
71
|
|
|
68
72
|
export function Suspense(props = {}) {
|
|
69
73
|
const tick = signal(0);
|
|
70
|
-
|
|
74
|
+
const pending = new Set();
|
|
75
|
+
|
|
76
|
+
// Track promises we are currently waiting for to avoid re-adding them or flickering
|
|
77
|
+
const waiting = new Set();
|
|
71
78
|
|
|
72
79
|
const child = Array.isArray(props.children) ? props.children[0] : props.children;
|
|
73
80
|
const childFn = typeof child === 'function' ? child : () => child;
|
|
74
81
|
|
|
75
|
-
|
|
82
|
+
const register = (promise) => {
|
|
83
|
+
if (!waiting.has(promise)) {
|
|
84
|
+
waiting.add(promise);
|
|
85
|
+
pending.add(promise);
|
|
86
|
+
promise.then(
|
|
87
|
+
() => {
|
|
88
|
+
waiting.delete(promise);
|
|
89
|
+
pending.delete(promise);
|
|
90
|
+
tick(tick.peek() + 1);
|
|
91
|
+
},
|
|
92
|
+
() => {
|
|
93
|
+
waiting.delete(promise);
|
|
94
|
+
pending.delete(promise);
|
|
95
|
+
tick(tick.peek() + 1);
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return createElement(SuspenseContext.Provider, {
|
|
102
|
+
value: { register }
|
|
103
|
+
}, () => {
|
|
104
|
+
// Read tick to re-render when promises resolve
|
|
76
105
|
tick();
|
|
77
106
|
|
|
107
|
+
// If pending promises, show fallback depending on strategy.
|
|
108
|
+
|
|
109
|
+
if (pending.size > 0) {
|
|
110
|
+
return props.fallback ?? null;
|
|
111
|
+
}
|
|
112
|
+
|
|
78
113
|
try {
|
|
79
114
|
const res = childFn();
|
|
80
115
|
if (isPromiseLike(res)) {
|
|
81
|
-
|
|
82
|
-
lastPromise = res;
|
|
83
|
-
res.then(
|
|
84
|
-
() => tick(tick.peek() + 1),
|
|
85
|
-
() => tick(tick.peek() + 1)
|
|
86
|
-
);
|
|
87
|
-
}
|
|
116
|
+
register(res);
|
|
88
117
|
return props.fallback ?? null;
|
|
89
118
|
}
|
|
90
|
-
lastPromise = null;
|
|
91
119
|
return res ?? null;
|
|
92
120
|
} catch (e) {
|
|
93
121
|
if (isPromiseLike(e)) {
|
|
94
|
-
|
|
95
|
-
lastPromise = e;
|
|
96
|
-
e.then(
|
|
97
|
-
() => tick(tick.peek() + 1),
|
|
98
|
-
() => tick(tick.peek() + 1)
|
|
99
|
-
);
|
|
100
|
-
}
|
|
122
|
+
register(e);
|
|
101
123
|
return props.fallback ?? null;
|
|
102
124
|
}
|
|
103
125
|
throw e;
|