@fictjs/runtime 0.2.3 → 0.4.0
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/dist/advanced.cjs +10 -8
- package/dist/advanced.cjs.map +1 -1
- package/dist/advanced.d.cts +8 -16
- package/dist/advanced.d.ts +8 -16
- package/dist/advanced.js +5 -3
- package/dist/advanced.js.map +1 -1
- package/dist/{chunk-2U6M3LKS.cjs → chunk-ID3WBWNO.cjs} +452 -219
- package/dist/chunk-ID3WBWNO.cjs.map +1 -0
- package/dist/{chunk-5YTFFAVU.cjs → chunk-L4DIV3RC.cjs} +7 -7
- package/dist/{chunk-5YTFFAVU.cjs.map → chunk-L4DIV3RC.cjs.map} +1 -1
- package/dist/{chunk-W525IQWC.cjs → chunk-M2TSXZ4C.cjs} +16 -16
- package/dist/{chunk-W525IQWC.cjs.map → chunk-M2TSXZ4C.cjs.map} +1 -1
- package/dist/{chunk-YVDWXY44.js → chunk-SO6X7G5S.js} +450 -217
- package/dist/chunk-SO6X7G5S.js.map +1 -0
- package/dist/{chunk-UHXUEGQH.js → chunk-TWELIZRY.js} +2 -2
- package/dist/{chunk-3WD7QD5G.js → chunk-XLIZJMMJ.js} +2 -2
- package/dist/{context-9gFXOdJl.d.cts → context-B25xyQrJ.d.cts} +36 -2
- package/dist/{context-4woHo7-L.d.ts → context-CGdP7_Jb.d.ts} +36 -2
- package/dist/{effect-ClARNUCc.d.cts → effect-D6kaLM2-.d.cts} +80 -1
- package/dist/{effect-ClARNUCc.d.ts → effect-D6kaLM2-.d.ts} +80 -1
- package/dist/index.cjs +40 -38
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.dev.js +322 -145
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/internal.cjs +39 -35
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +8 -6
- package/dist/internal.d.ts +8 -6
- package/dist/internal.js +7 -3
- package/dist/internal.js.map +1 -1
- package/dist/{props-DAyeRPwH.d.ts → props-BEgIVMRx.d.ts} +8 -15
- package/dist/{props-CBwuh35e.d.cts → props-BIfromL0.d.cts} +8 -15
- package/dist/scope-Cx_3CjIZ.d.cts +18 -0
- package/dist/scope-CzNkn587.d.ts +18 -0
- package/package.json +3 -3
- package/src/advanced.ts +1 -0
- package/src/binding.ts +30 -4
- package/src/constants.ts +5 -0
- package/src/cycle-guard.ts +59 -7
- package/src/devtools.ts +22 -2
- package/src/dom.ts +84 -10
- package/src/hooks.ts +60 -13
- package/src/index.ts +3 -1
- package/src/internal.ts +2 -2
- package/src/lifecycle.ts +13 -5
- package/src/memo.ts +3 -4
- package/src/props.ts +16 -0
- package/src/signal.ts +204 -36
- package/dist/chunk-2U6M3LKS.cjs.map +0 -1
- package/dist/chunk-YVDWXY44.js.map +0 -1
- package/dist/scope-DvgMquEy.d.ts +0 -55
- package/dist/scope-xmdo6lVU.d.cts +0 -55
- /package/dist/{chunk-UHXUEGQH.js.map → chunk-TWELIZRY.js.map} +0 -0
- /package/dist/{chunk-3WD7QD5G.js.map → chunk-XLIZJMMJ.js.map} +0 -0
package/dist/index.dev.js
CHANGED
|
@@ -22,14 +22,17 @@ var enterRootGuard = () => true;
|
|
|
22
22
|
var exitRootGuard = () => {
|
|
23
23
|
};
|
|
24
24
|
var defaultOptions = {
|
|
25
|
-
enabled:
|
|
25
|
+
enabled: true,
|
|
26
26
|
maxFlushCyclesPerMicrotask: 1e4,
|
|
27
27
|
maxEffectRunsPerFlush: 2e4,
|
|
28
28
|
windowSize: 5,
|
|
29
29
|
highUsageRatio: 0.8,
|
|
30
30
|
maxRootReentrantDepth: 10,
|
|
31
31
|
enableWindowWarning: true,
|
|
32
|
-
devMode:
|
|
32
|
+
devMode: isDev,
|
|
33
|
+
// Backoff warning options
|
|
34
|
+
enableBackoffWarning: isDev,
|
|
35
|
+
backoffWarningRatio: 0.5
|
|
33
36
|
};
|
|
34
37
|
var enabled = defaultOptions.enabled;
|
|
35
38
|
var options = {
|
|
@@ -41,6 +44,8 @@ var rootDepth = /* @__PURE__ */ new WeakMap();
|
|
|
41
44
|
var flushWarned = false;
|
|
42
45
|
var rootWarned = false;
|
|
43
46
|
var windowWarned = false;
|
|
47
|
+
var backoffWarned50 = false;
|
|
48
|
+
var backoffWarned75 = false;
|
|
44
49
|
setCycleProtectionOptions = (opts) => {
|
|
45
50
|
if (typeof opts.enabled === "boolean") {
|
|
46
51
|
enabled = opts.enabled;
|
|
@@ -56,24 +61,55 @@ resetCycleProtectionStateForTests = () => {
|
|
|
56
61
|
flushWarned = false;
|
|
57
62
|
rootWarned = false;
|
|
58
63
|
windowWarned = false;
|
|
64
|
+
backoffWarned50 = false;
|
|
65
|
+
backoffWarned75 = false;
|
|
59
66
|
};
|
|
60
67
|
beginFlushGuard = () => {
|
|
61
68
|
if (!enabled) return;
|
|
62
69
|
effectRunsThisFlush = 0;
|
|
63
70
|
flushWarned = false;
|
|
64
71
|
windowWarned = false;
|
|
72
|
+
backoffWarned50 = false;
|
|
73
|
+
backoffWarned75 = false;
|
|
65
74
|
};
|
|
66
75
|
beforeEffectRunGuard = () => {
|
|
67
76
|
if (!enabled) return true;
|
|
68
77
|
const next = ++effectRunsThisFlush;
|
|
69
|
-
|
|
78
|
+
const limit = Math.min(options.maxFlushCyclesPerMicrotask, options.maxEffectRunsPerFlush);
|
|
79
|
+
if (options.enableBackoffWarning && isDev) {
|
|
80
|
+
const ratio = next / limit;
|
|
81
|
+
const backoffRatio = options.backoffWarningRatio ?? 0.5;
|
|
82
|
+
if (!backoffWarned50 && ratio >= backoffRatio && ratio < backoffRatio + 0.25) {
|
|
83
|
+
backoffWarned50 = true;
|
|
84
|
+
console.warn(
|
|
85
|
+
`[fict] cycle guard: approaching effect limit (${Math.round(ratio * 100)}% of budget used)
|
|
86
|
+
- Current: ${next} effects, Limit: ${limit}
|
|
87
|
+
- Tip: Check for effects that trigger other effects in a loop.
|
|
88
|
+
- Common causes: signal updates inside effects that read and write the same signal.`
|
|
89
|
+
);
|
|
90
|
+
} else if (!backoffWarned75 && ratio >= backoffRatio + 0.25 && ratio < 1) {
|
|
91
|
+
backoffWarned75 = true;
|
|
92
|
+
console.warn(
|
|
93
|
+
`[fict] cycle guard: nearing effect limit (${Math.round(ratio * 100)}% of budget used)
|
|
94
|
+
- Current: ${next} effects, Limit: ${limit}
|
|
95
|
+
- Warning: Consider breaking the reactive dependency cycle.
|
|
96
|
+
- Debug: Use browser devtools to identify the recursive effect chain.`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (next > limit) {
|
|
70
101
|
const message = `[fict] cycle protection triggered: flush-budget-exceeded`;
|
|
71
102
|
if (options.devMode) {
|
|
72
|
-
throw new Error(
|
|
103
|
+
throw new Error(
|
|
104
|
+
message + `
|
|
105
|
+
- Effect runs: ${next}, Limit: ${limit}
|
|
106
|
+
- This indicates a reactive cycle where effects keep triggering each other.
|
|
107
|
+
- Check for patterns like: createEffect(() => { signal(); signal(newValue); })`
|
|
108
|
+
);
|
|
73
109
|
}
|
|
74
110
|
if (!flushWarned) {
|
|
75
111
|
flushWarned = true;
|
|
76
|
-
console.warn(message, { effectRuns: next });
|
|
112
|
+
console.warn(message, { effectRuns: next, limit });
|
|
77
113
|
}
|
|
78
114
|
return false;
|
|
79
115
|
}
|
|
@@ -90,11 +126,16 @@ enterRootGuard = (root) => {
|
|
|
90
126
|
if (depth > options.maxRootReentrantDepth) {
|
|
91
127
|
const message = `[fict] cycle protection triggered: root-reentry`;
|
|
92
128
|
if (options.devMode) {
|
|
93
|
-
throw new Error(
|
|
129
|
+
throw new Error(
|
|
130
|
+
message + `
|
|
131
|
+
- Re-entry depth: ${depth}, Max allowed: ${options.maxRootReentrantDepth}
|
|
132
|
+
- This indicates recursive render() or component initialization.
|
|
133
|
+
- Check for components that trigger re-renders during their own render phase.`
|
|
134
|
+
);
|
|
94
135
|
}
|
|
95
136
|
if (!rootWarned) {
|
|
96
137
|
rootWarned = true;
|
|
97
|
-
console.warn(message, { depth });
|
|
138
|
+
console.warn(message, { depth, maxAllowed: options.maxRootReentrantDepth });
|
|
98
139
|
}
|
|
99
140
|
return false;
|
|
100
141
|
}
|
|
@@ -180,13 +221,19 @@ function onCleanup(fn) {
|
|
|
180
221
|
function flushOnMount(root) {
|
|
181
222
|
const cbs = root.onMountCallbacks;
|
|
182
223
|
if (!cbs || cbs.length === 0) return;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
224
|
+
const prevRoot = currentRoot;
|
|
225
|
+
currentRoot = root;
|
|
226
|
+
try {
|
|
227
|
+
for (let i = 0; i < cbs.length; i++) {
|
|
228
|
+
const cleanup = cbs[i]();
|
|
229
|
+
if (typeof cleanup === "function") {
|
|
230
|
+
root.cleanups.push(cleanup);
|
|
231
|
+
}
|
|
187
232
|
}
|
|
233
|
+
} finally {
|
|
234
|
+
currentRoot = prevRoot;
|
|
235
|
+
cbs.length = 0;
|
|
188
236
|
}
|
|
189
|
-
cbs.length = 0;
|
|
190
237
|
}
|
|
191
238
|
function registerRootCleanup(fn) {
|
|
192
239
|
if (currentRoot) {
|
|
@@ -371,8 +418,98 @@ function handleSuspend(token, startRoot) {
|
|
|
371
418
|
return false;
|
|
372
419
|
}
|
|
373
420
|
|
|
374
|
-
// src/
|
|
421
|
+
// src/effect.ts
|
|
422
|
+
function createEffect(fn) {
|
|
423
|
+
let cleanups = [];
|
|
424
|
+
const rootForError = getCurrentRoot();
|
|
425
|
+
const doCleanup = () => {
|
|
426
|
+
runCleanupList(cleanups);
|
|
427
|
+
cleanups = [];
|
|
428
|
+
};
|
|
429
|
+
const run = () => {
|
|
430
|
+
const bucket = [];
|
|
431
|
+
withEffectCleanups(bucket, () => {
|
|
432
|
+
try {
|
|
433
|
+
const maybeCleanup = fn();
|
|
434
|
+
if (typeof maybeCleanup === "function") {
|
|
435
|
+
bucket.push(maybeCleanup);
|
|
436
|
+
}
|
|
437
|
+
} catch (err) {
|
|
438
|
+
if (handleSuspend(err, rootForError)) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
if (handleError(err, { source: "effect" }, rootForError)) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
throw err;
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
cleanups = bucket;
|
|
448
|
+
};
|
|
449
|
+
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
450
|
+
const teardown = () => {
|
|
451
|
+
runCleanupList(cleanups);
|
|
452
|
+
disposeEffect();
|
|
453
|
+
};
|
|
454
|
+
registerRootCleanup(teardown);
|
|
455
|
+
return teardown;
|
|
456
|
+
}
|
|
457
|
+
function createRenderEffect(fn) {
|
|
458
|
+
let cleanup;
|
|
459
|
+
const rootForError = getCurrentRoot();
|
|
460
|
+
const doCleanup = () => {
|
|
461
|
+
if (cleanup) {
|
|
462
|
+
cleanup();
|
|
463
|
+
cleanup = void 0;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
const run = () => {
|
|
467
|
+
try {
|
|
468
|
+
const maybeCleanup = fn();
|
|
469
|
+
if (typeof maybeCleanup === "function") {
|
|
470
|
+
cleanup = maybeCleanup;
|
|
471
|
+
}
|
|
472
|
+
} catch (err) {
|
|
473
|
+
if (handleSuspend(err, rootForError)) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
477
|
+
if (handled) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
throw err;
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
484
|
+
const teardown = () => {
|
|
485
|
+
if (cleanup) {
|
|
486
|
+
cleanup();
|
|
487
|
+
cleanup = void 0;
|
|
488
|
+
}
|
|
489
|
+
disposeEffect();
|
|
490
|
+
};
|
|
491
|
+
registerRootCleanup(teardown);
|
|
492
|
+
return teardown;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/hooks.ts
|
|
375
496
|
var isDev3 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
497
|
+
var ctxStack = [];
|
|
498
|
+
function __fictPushContext() {
|
|
499
|
+
const ctx = { slots: [], cursor: 0 };
|
|
500
|
+
ctxStack.push(ctx);
|
|
501
|
+
return ctx;
|
|
502
|
+
}
|
|
503
|
+
function __fictGetCurrentComponentId() {
|
|
504
|
+
return ctxStack[ctxStack.length - 1]?.componentId;
|
|
505
|
+
}
|
|
506
|
+
function __fictPopContext() {
|
|
507
|
+
const ctx = ctxStack.pop();
|
|
508
|
+
if (ctx) ctx.rendering = false;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// src/signal.ts
|
|
512
|
+
var isDev4 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
376
513
|
var Mutable = 1;
|
|
377
514
|
var Watching = 2;
|
|
378
515
|
var Running = 4;
|
|
@@ -417,6 +554,7 @@ function link(dep, sub, version) {
|
|
|
417
554
|
else sub.deps = newLink;
|
|
418
555
|
if (prevSub !== void 0) prevSub.nextSub = newLink;
|
|
419
556
|
else dep.subs = newLink;
|
|
557
|
+
if (isDev4) trackDependencyDevtools(dep, sub);
|
|
420
558
|
}
|
|
421
559
|
function unlink(lnk, sub = lnk.sub) {
|
|
422
560
|
const dep = lnk.dep;
|
|
@@ -432,6 +570,7 @@ function unlink(lnk, sub = lnk.sub) {
|
|
|
432
570
|
else dep.subsTail = prevSub;
|
|
433
571
|
if (prevSub !== void 0) prevSub.nextSub = nextSub;
|
|
434
572
|
else if ((dep.subs = nextSub) === void 0) unwatched(dep);
|
|
573
|
+
if (isDev4) untrackDependencyDevtools(dep, sub);
|
|
435
574
|
return nextDep;
|
|
436
575
|
}
|
|
437
576
|
function unwatched(dep) {
|
|
@@ -588,6 +727,11 @@ function shallowPropagate(firstLink) {
|
|
|
588
727
|
function update(node) {
|
|
589
728
|
return "getter" in node && node.getter !== void 0 ? updateComputed(node) : updateSignal(node);
|
|
590
729
|
}
|
|
730
|
+
function valuesDiffer(node, prev, next) {
|
|
731
|
+
if (node.equals === false) return true;
|
|
732
|
+
if (typeof node.equals === "function") return !node.equals(prev, next);
|
|
733
|
+
return prev !== next;
|
|
734
|
+
}
|
|
591
735
|
function notify(effect) {
|
|
592
736
|
effect.flags &= ~Watching;
|
|
593
737
|
const effects = [];
|
|
@@ -624,7 +768,7 @@ function updateSignal(s) {
|
|
|
624
768
|
s.flags = Mutable;
|
|
625
769
|
const current = s.currentValue;
|
|
626
770
|
const pending = s.pendingValue;
|
|
627
|
-
if (current
|
|
771
|
+
if (valuesDiffer(s, current, pending)) {
|
|
628
772
|
s.currentValue = pending;
|
|
629
773
|
return true;
|
|
630
774
|
}
|
|
@@ -642,8 +786,9 @@ function updateComputed(c) {
|
|
|
642
786
|
activeSub = prevSub;
|
|
643
787
|
c.flags &= ~Running;
|
|
644
788
|
purgeDeps(c);
|
|
645
|
-
if (oldValue
|
|
789
|
+
if (valuesDiffer(c, oldValue, newValue)) {
|
|
646
790
|
c.value = newValue;
|
|
791
|
+
if (isDev4) updateComputedDevtools(c, newValue);
|
|
647
792
|
return true;
|
|
648
793
|
}
|
|
649
794
|
return false;
|
|
@@ -665,7 +810,7 @@ function runEffect(e) {
|
|
|
665
810
|
}
|
|
666
811
|
}
|
|
667
812
|
++cycle;
|
|
668
|
-
effectRunDevtools(e);
|
|
813
|
+
if (isDev4) effectRunDevtools(e);
|
|
669
814
|
e.depsTail = void 0;
|
|
670
815
|
e.flags = WatchingRunning;
|
|
671
816
|
const prevSub = activeSub;
|
|
@@ -709,7 +854,7 @@ function runEffect(e) {
|
|
|
709
854
|
}
|
|
710
855
|
if (isDirty) {
|
|
711
856
|
++cycle;
|
|
712
|
-
effectRunDevtools(e);
|
|
857
|
+
if (isDev4) effectRunDevtools(e);
|
|
713
858
|
e.depsTail = void 0;
|
|
714
859
|
e.flags = WatchingRunning;
|
|
715
860
|
const prevSub = activeSub;
|
|
@@ -758,10 +903,21 @@ function flush() {
|
|
|
758
903
|
while (highIndex < highPriorityQueue.length) {
|
|
759
904
|
const e = highPriorityQueue[highIndex];
|
|
760
905
|
if (!beforeEffectRunGuard()) {
|
|
761
|
-
|
|
762
|
-
highPriorityQueue
|
|
763
|
-
|
|
906
|
+
for (let i = 0; i < highPriorityQueue.length; i++) {
|
|
907
|
+
const queued = highPriorityQueue[i];
|
|
908
|
+
if (queued && queued.flags !== 0) {
|
|
909
|
+
queued.flags = Watching;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
for (let i = 0; i < lowPriorityQueue.length; i++) {
|
|
913
|
+
const queued = lowPriorityQueue[i];
|
|
914
|
+
if (queued && queued.flags !== 0) {
|
|
915
|
+
queued.flags = Watching;
|
|
916
|
+
}
|
|
764
917
|
}
|
|
918
|
+
highPriorityQueue.length = 0;
|
|
919
|
+
lowPriorityQueue.length = 0;
|
|
920
|
+
flushScheduled = false;
|
|
765
921
|
endFlushGuard();
|
|
766
922
|
return;
|
|
767
923
|
}
|
|
@@ -782,10 +938,21 @@ function flush() {
|
|
|
782
938
|
}
|
|
783
939
|
const e = lowPriorityQueue[lowIndex];
|
|
784
940
|
if (!beforeEffectRunGuard()) {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
941
|
+
for (let i = 0; i < highPriorityQueue.length; i++) {
|
|
942
|
+
const queued = highPriorityQueue[i];
|
|
943
|
+
if (queued && queued.flags !== 0) {
|
|
944
|
+
queued.flags = Watching;
|
|
945
|
+
}
|
|
788
946
|
}
|
|
947
|
+
for (let i = 0; i < lowPriorityQueue.length; i++) {
|
|
948
|
+
const queued = lowPriorityQueue[i];
|
|
949
|
+
if (queued && queued.flags !== 0) {
|
|
950
|
+
queued.flags = Watching;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
highPriorityQueue.length = 0;
|
|
954
|
+
lowPriorityQueue.length = 0;
|
|
955
|
+
flushScheduled = false;
|
|
789
956
|
endFlushGuard();
|
|
790
957
|
return;
|
|
791
958
|
}
|
|
@@ -795,26 +962,31 @@ function flush() {
|
|
|
795
962
|
lowPriorityQueue.length = 0;
|
|
796
963
|
endFlushGuard();
|
|
797
964
|
}
|
|
798
|
-
function signal(initialValue) {
|
|
965
|
+
function signal(initialValue, options2) {
|
|
799
966
|
const s = {
|
|
800
967
|
currentValue: initialValue,
|
|
801
968
|
pendingValue: initialValue,
|
|
802
969
|
subs: void 0,
|
|
803
970
|
subsTail: void 0,
|
|
804
971
|
flags: Mutable,
|
|
805
|
-
__id: void 0
|
|
972
|
+
__id: void 0,
|
|
973
|
+
...options2?.equals !== void 0 ? { equals: options2.equals } : {},
|
|
974
|
+
...options2?.name !== void 0 ? { name: options2.name } : {},
|
|
975
|
+
...options2?.devToolsSource !== void 0 ? { devToolsSource: options2.devToolsSource } : {}
|
|
806
976
|
};
|
|
807
|
-
registerSignalDevtools(
|
|
977
|
+
if (isDev4) registerSignalDevtools(s);
|
|
808
978
|
const accessor = signalOper.bind(s);
|
|
809
979
|
accessor[SIGNAL_MARKER] = true;
|
|
810
980
|
return accessor;
|
|
811
981
|
}
|
|
812
982
|
function signalOper(value) {
|
|
813
983
|
if (arguments.length > 0) {
|
|
814
|
-
|
|
815
|
-
|
|
984
|
+
const next = value;
|
|
985
|
+
const prev = this.pendingValue;
|
|
986
|
+
if (valuesDiffer(this, prev, next)) {
|
|
987
|
+
this.pendingValue = next;
|
|
816
988
|
this.flags = MutableDirty;
|
|
817
|
-
updateSignalDevtools(this,
|
|
989
|
+
if (isDev4) updateSignalDevtools(this, next);
|
|
818
990
|
const subs = this.subs;
|
|
819
991
|
if (subs !== void 0) {
|
|
820
992
|
propagate(subs);
|
|
@@ -841,7 +1013,7 @@ function signalOper(value) {
|
|
|
841
1013
|
}
|
|
842
1014
|
return this.currentValue;
|
|
843
1015
|
}
|
|
844
|
-
function computed(getter) {
|
|
1016
|
+
function computed(getter, options2) {
|
|
845
1017
|
const c = {
|
|
846
1018
|
value: void 0,
|
|
847
1019
|
subs: void 0,
|
|
@@ -849,13 +1021,21 @@ function computed(getter) {
|
|
|
849
1021
|
deps: void 0,
|
|
850
1022
|
depsTail: void 0,
|
|
851
1023
|
flags: 0,
|
|
852
|
-
getter
|
|
1024
|
+
getter,
|
|
1025
|
+
__id: void 0,
|
|
1026
|
+
...options2?.equals !== void 0 ? { equals: options2.equals } : {},
|
|
1027
|
+
...options2?.name !== void 0 ? { name: options2.name } : {},
|
|
1028
|
+
...options2?.devToolsSource !== void 0 ? { devToolsSource: options2.devToolsSource } : {}
|
|
853
1029
|
};
|
|
854
|
-
|
|
1030
|
+
if (isDev4) registerComputedDevtools(c);
|
|
1031
|
+
const bound = computedOper.bind(
|
|
1032
|
+
c
|
|
1033
|
+
);
|
|
855
1034
|
bound[COMPUTED_MARKER] = true;
|
|
856
1035
|
return bound;
|
|
857
1036
|
}
|
|
858
1037
|
function computedOper() {
|
|
1038
|
+
if (inCleanup) return this.value;
|
|
859
1039
|
const flags = this.flags;
|
|
860
1040
|
if (flags & Dirty) {
|
|
861
1041
|
if (updateComputed(this)) {
|
|
@@ -876,6 +1056,7 @@ function computedOper() {
|
|
|
876
1056
|
const prevSub = setActiveSub(this);
|
|
877
1057
|
try {
|
|
878
1058
|
this.value = this.getter(void 0);
|
|
1059
|
+
if (isDev4) updateComputedDevtools(this, this.value);
|
|
879
1060
|
} finally {
|
|
880
1061
|
setActiveSub(prevSub);
|
|
881
1062
|
this.flags &= ~Running;
|
|
@@ -899,12 +1080,12 @@ function effectWithCleanup(fn, cleanupRunner, root) {
|
|
|
899
1080
|
if (resolvedRoot) {
|
|
900
1081
|
e.root = resolvedRoot;
|
|
901
1082
|
}
|
|
902
|
-
registerEffectDevtools(e);
|
|
1083
|
+
if (isDev4) registerEffectDevtools(e);
|
|
903
1084
|
const prevSub = activeSub;
|
|
904
1085
|
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
905
1086
|
activeSub = e;
|
|
906
1087
|
try {
|
|
907
|
-
effectRunDevtools(e);
|
|
1088
|
+
if (isDev4) effectRunDevtools(e);
|
|
908
1089
|
fn();
|
|
909
1090
|
} finally {
|
|
910
1091
|
activeSub = prevSub;
|
|
@@ -976,17 +1157,28 @@ function setTransitionContext(value) {
|
|
|
976
1157
|
var registerSignalDevtools = () => void 0;
|
|
977
1158
|
var updateSignalDevtools = () => {
|
|
978
1159
|
};
|
|
1160
|
+
var registerComputedDevtools = () => void 0;
|
|
1161
|
+
var updateComputedDevtools = () => {
|
|
1162
|
+
};
|
|
979
1163
|
var registerEffectDevtools = () => void 0;
|
|
980
1164
|
var effectRunDevtools = () => {
|
|
981
1165
|
};
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1166
|
+
var trackDependencyDevtools = () => {
|
|
1167
|
+
};
|
|
1168
|
+
var untrackDependencyDevtools = () => {
|
|
1169
|
+
};
|
|
1170
|
+
if (isDev4) {
|
|
1171
|
+
let nextDevtoolsId = 0;
|
|
1172
|
+
registerSignalDevtools = (node) => {
|
|
986
1173
|
const hook = getDevtoolsHook();
|
|
987
1174
|
if (!hook) return void 0;
|
|
988
|
-
const id = ++
|
|
989
|
-
|
|
1175
|
+
const id = ++nextDevtoolsId;
|
|
1176
|
+
const options2 = {};
|
|
1177
|
+
if (node.name !== void 0) options2.name = node.name;
|
|
1178
|
+
if (node.devToolsSource !== void 0) options2.source = node.devToolsSource;
|
|
1179
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1180
|
+
if (ownerId !== void 0) options2.ownerId = ownerId;
|
|
1181
|
+
hook.registerSignal(id, node.currentValue, options2);
|
|
990
1182
|
node.__id = id;
|
|
991
1183
|
return id;
|
|
992
1184
|
};
|
|
@@ -996,11 +1188,32 @@ if (isDev3) {
|
|
|
996
1188
|
const id = node.__id;
|
|
997
1189
|
if (id) hook.updateSignal(id, value);
|
|
998
1190
|
};
|
|
1191
|
+
registerComputedDevtools = (node) => {
|
|
1192
|
+
const hook = getDevtoolsHook();
|
|
1193
|
+
if (!hook) return void 0;
|
|
1194
|
+
const id = ++nextDevtoolsId;
|
|
1195
|
+
const options2 = {};
|
|
1196
|
+
if (node.name !== void 0) options2.name = node.name;
|
|
1197
|
+
if (node.devToolsSource !== void 0) options2.source = node.devToolsSource;
|
|
1198
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1199
|
+
if (ownerId !== void 0) options2.ownerId = ownerId;
|
|
1200
|
+
options2.hasValue = false;
|
|
1201
|
+
hook.registerComputed(id, node.value, options2);
|
|
1202
|
+
node.__id = id;
|
|
1203
|
+
return id;
|
|
1204
|
+
};
|
|
1205
|
+
updateComputedDevtools = (node, value) => {
|
|
1206
|
+
const hook = getDevtoolsHook();
|
|
1207
|
+
if (!hook) return;
|
|
1208
|
+
const id = node.__id;
|
|
1209
|
+
if (id) hook.updateComputed(id, value);
|
|
1210
|
+
};
|
|
999
1211
|
registerEffectDevtools = (node) => {
|
|
1000
1212
|
const hook = getDevtoolsHook();
|
|
1001
1213
|
if (!hook) return void 0;
|
|
1002
|
-
const id = ++
|
|
1003
|
-
|
|
1214
|
+
const id = ++nextDevtoolsId;
|
|
1215
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1216
|
+
hook.registerEffect(id, ownerId !== void 0 ? { ownerId } : void 0);
|
|
1004
1217
|
node.__id = id;
|
|
1005
1218
|
return id;
|
|
1006
1219
|
};
|
|
@@ -1010,85 +1223,25 @@ if (isDev3) {
|
|
|
1010
1223
|
const id = node.__id;
|
|
1011
1224
|
if (id) hook.effectRun(id);
|
|
1012
1225
|
};
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
// src/effect.ts
|
|
1021
|
-
function createEffect(fn) {
|
|
1022
|
-
let cleanups = [];
|
|
1023
|
-
const rootForError = getCurrentRoot();
|
|
1024
|
-
const doCleanup = () => {
|
|
1025
|
-
runCleanupList(cleanups);
|
|
1026
|
-
cleanups = [];
|
|
1027
|
-
};
|
|
1028
|
-
const run = () => {
|
|
1029
|
-
const bucket = [];
|
|
1030
|
-
withEffectCleanups(bucket, () => {
|
|
1031
|
-
try {
|
|
1032
|
-
const maybeCleanup = fn();
|
|
1033
|
-
if (typeof maybeCleanup === "function") {
|
|
1034
|
-
bucket.push(maybeCleanup);
|
|
1035
|
-
}
|
|
1036
|
-
} catch (err) {
|
|
1037
|
-
if (handleSuspend(err, rootForError)) {
|
|
1038
|
-
return;
|
|
1039
|
-
}
|
|
1040
|
-
if (handleError(err, { source: "effect" }, rootForError)) {
|
|
1041
|
-
return;
|
|
1042
|
-
}
|
|
1043
|
-
throw err;
|
|
1044
|
-
}
|
|
1045
|
-
});
|
|
1046
|
-
cleanups = bucket;
|
|
1226
|
+
trackDependencyDevtools = (dep, sub) => {
|
|
1227
|
+
const hook = getDevtoolsHook();
|
|
1228
|
+
if (!hook?.trackDependency) return;
|
|
1229
|
+
const depId = dep.__id;
|
|
1230
|
+
const subId = sub.__id;
|
|
1231
|
+
if (depId && subId) hook.trackDependency(subId, depId);
|
|
1047
1232
|
};
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1233
|
+
untrackDependencyDevtools = (dep, sub) => {
|
|
1234
|
+
const hook = getDevtoolsHook();
|
|
1235
|
+
if (!hook?.untrackDependency) return;
|
|
1236
|
+
const depId = dep.__id;
|
|
1237
|
+
const subId = sub.__id;
|
|
1238
|
+
if (depId && subId) hook.untrackDependency(subId, depId);
|
|
1052
1239
|
};
|
|
1053
|
-
registerRootCleanup(teardown);
|
|
1054
|
-
return teardown;
|
|
1055
1240
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
if (cleanup) {
|
|
1061
|
-
cleanup();
|
|
1062
|
-
cleanup = void 0;
|
|
1063
|
-
}
|
|
1064
|
-
};
|
|
1065
|
-
const run = () => {
|
|
1066
|
-
try {
|
|
1067
|
-
const maybeCleanup = fn();
|
|
1068
|
-
if (typeof maybeCleanup === "function") {
|
|
1069
|
-
cleanup = maybeCleanup;
|
|
1070
|
-
}
|
|
1071
|
-
} catch (err) {
|
|
1072
|
-
if (handleSuspend(err, rootForError)) {
|
|
1073
|
-
return;
|
|
1074
|
-
}
|
|
1075
|
-
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1076
|
-
if (handled) {
|
|
1077
|
-
return;
|
|
1078
|
-
}
|
|
1079
|
-
throw err;
|
|
1080
|
-
}
|
|
1081
|
-
};
|
|
1082
|
-
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
1083
|
-
const teardown = () => {
|
|
1084
|
-
if (cleanup) {
|
|
1085
|
-
cleanup();
|
|
1086
|
-
cleanup = void 0;
|
|
1087
|
-
}
|
|
1088
|
-
disposeEffect();
|
|
1089
|
-
};
|
|
1090
|
-
registerRootCleanup(teardown);
|
|
1091
|
-
return teardown;
|
|
1241
|
+
|
|
1242
|
+
// src/memo.ts
|
|
1243
|
+
function createMemo(fn, options2) {
|
|
1244
|
+
return computed(fn, options2);
|
|
1092
1245
|
}
|
|
1093
1246
|
|
|
1094
1247
|
// src/ref.ts
|
|
@@ -1172,8 +1325,8 @@ var DelegatedEventNames = [
|
|
|
1172
1325
|
];
|
|
1173
1326
|
|
|
1174
1327
|
// src/constants.ts
|
|
1175
|
-
var
|
|
1176
|
-
var booleans =
|
|
1328
|
+
var isDev5 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
1329
|
+
var booleans = isDev5 ? [
|
|
1177
1330
|
"allowfullscreen",
|
|
1178
1331
|
"async",
|
|
1179
1332
|
"alpha",
|
|
@@ -1223,7 +1376,7 @@ var booleans = isDev4 ? [
|
|
|
1223
1376
|
"sharedstoragewritable"
|
|
1224
1377
|
] : [];
|
|
1225
1378
|
var BooleanAttributes = new Set(booleans);
|
|
1226
|
-
var properties =
|
|
1379
|
+
var properties = isDev5 ? [
|
|
1227
1380
|
// Core properties
|
|
1228
1381
|
"className",
|
|
1229
1382
|
"value",
|
|
@@ -1259,7 +1412,7 @@ var ChildProperties = /* @__PURE__ */ new Set([
|
|
|
1259
1412
|
"innerText",
|
|
1260
1413
|
"children"
|
|
1261
1414
|
]);
|
|
1262
|
-
var PropAliases =
|
|
1415
|
+
var PropAliases = isDev5 ? {
|
|
1263
1416
|
// Direct mapping
|
|
1264
1417
|
class: "className",
|
|
1265
1418
|
// Element-specific mappings
|
|
@@ -1348,7 +1501,7 @@ var PropAliases = isDev4 ? {
|
|
|
1348
1501
|
}
|
|
1349
1502
|
} : {};
|
|
1350
1503
|
function getPropAlias(prop2, tagName) {
|
|
1351
|
-
if (!
|
|
1504
|
+
if (!isDev5) return void 0;
|
|
1352
1505
|
const a = PropAliases[prop2];
|
|
1353
1506
|
if (typeof a === "object") {
|
|
1354
1507
|
return a[tagName] ? a["$"] : void 0;
|
|
@@ -1357,7 +1510,7 @@ function getPropAlias(prop2, tagName) {
|
|
|
1357
1510
|
}
|
|
1358
1511
|
var $$EVENTS = "_$FICT_DELEGATE";
|
|
1359
1512
|
var DelegatedEvents = new Set(DelegatedEventNames);
|
|
1360
|
-
var svgElements =
|
|
1513
|
+
var svgElements = isDev5 ? [
|
|
1361
1514
|
"altGlyph",
|
|
1362
1515
|
"altGlyphDef",
|
|
1363
1516
|
"altGlyphItem",
|
|
@@ -1441,7 +1594,7 @@ var SVGNamespace = {
|
|
|
1441
1594
|
xlink: "http://www.w3.org/1999/xlink",
|
|
1442
1595
|
xml: "http://www.w3.org/XML/1998/namespace"
|
|
1443
1596
|
};
|
|
1444
|
-
var unitlessList =
|
|
1597
|
+
var unitlessList = isDev5 ? [
|
|
1445
1598
|
"animationIterationCount",
|
|
1446
1599
|
"animation-iteration-count",
|
|
1447
1600
|
"borderImageOutset",
|
|
@@ -1664,13 +1817,22 @@ function removeNodes(nodes) {
|
|
|
1664
1817
|
}
|
|
1665
1818
|
|
|
1666
1819
|
// src/binding.ts
|
|
1667
|
-
var
|
|
1820
|
+
var isDev6 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
1668
1821
|
function isReactive(value) {
|
|
1669
1822
|
if (typeof value !== "function") return false;
|
|
1670
1823
|
if (isSignal(value) || isComputed(value)) return true;
|
|
1671
1824
|
if (isEffect(value) || isEffectScope(value)) return false;
|
|
1672
1825
|
return value.length === 0;
|
|
1673
1826
|
}
|
|
1827
|
+
function isStrictlyReactive(value) {
|
|
1828
|
+
if (typeof value !== "function") return false;
|
|
1829
|
+
return isSignal(value) || isComputed(value) || isPropGetterFn(value);
|
|
1830
|
+
}
|
|
1831
|
+
var PROP_GETTER_MARKER = Symbol.for("fict:prop-getter");
|
|
1832
|
+
function isPropGetterFn(value) {
|
|
1833
|
+
if (typeof value !== "function") return false;
|
|
1834
|
+
return value[PROP_GETTER_MARKER] === true;
|
|
1835
|
+
}
|
|
1674
1836
|
function callEventHandler(handler, event, node, data) {
|
|
1675
1837
|
if (!handler) return;
|
|
1676
1838
|
const context = node ?? event.currentTarget ?? void 0;
|
|
@@ -1757,7 +1919,7 @@ function applyStyle(el, value, prev) {
|
|
|
1757
1919
|
}
|
|
1758
1920
|
}
|
|
1759
1921
|
}
|
|
1760
|
-
var isUnitlessStyleProperty =
|
|
1922
|
+
var isUnitlessStyleProperty = isDev6 ? (prop2) => UnitlessStyles.has(prop2) : (prop2) => prop2 === "opacity" || prop2 === "zIndex";
|
|
1761
1923
|
function createClassBinding(el, value) {
|
|
1762
1924
|
if (isReactive(value)) {
|
|
1763
1925
|
let prev = {};
|
|
@@ -1968,7 +2130,7 @@ function bindEvent(el, eventName, handler, options2) {
|
|
|
1968
2130
|
if (shouldDelegate) {
|
|
1969
2131
|
const key = `$$${eventName}`;
|
|
1970
2132
|
delegateEvents([eventName]);
|
|
1971
|
-
const resolveHandler =
|
|
2133
|
+
const resolveHandler = isStrictlyReactive(handler) ? handler : () => handler;
|
|
1972
2134
|
el[key] = function(...args) {
|
|
1973
2135
|
try {
|
|
1974
2136
|
const fn = resolveHandler();
|
|
@@ -1983,7 +2145,7 @@ function bindEvent(el, eventName, handler, options2) {
|
|
|
1983
2145
|
el[key] = void 0;
|
|
1984
2146
|
};
|
|
1985
2147
|
}
|
|
1986
|
-
const getHandler =
|
|
2148
|
+
const getHandler = isStrictlyReactive(handler) ? handler : () => handler;
|
|
1987
2149
|
const wrapped = (event) => {
|
|
1988
2150
|
try {
|
|
1989
2151
|
const resolved = getHandler();
|
|
@@ -2071,20 +2233,8 @@ function createPortal(container, render2, createElementFn) {
|
|
|
2071
2233
|
};
|
|
2072
2234
|
}
|
|
2073
2235
|
|
|
2074
|
-
// src/hooks.ts
|
|
2075
|
-
var isDev6 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
2076
|
-
var ctxStack = [];
|
|
2077
|
-
function __fictPushContext() {
|
|
2078
|
-
const ctx = { slots: [], cursor: 0 };
|
|
2079
|
-
ctxStack.push(ctx);
|
|
2080
|
-
return ctx;
|
|
2081
|
-
}
|
|
2082
|
-
function __fictPopContext() {
|
|
2083
|
-
ctxStack.pop();
|
|
2084
|
-
}
|
|
2085
|
-
|
|
2086
2236
|
// src/props.ts
|
|
2087
|
-
var
|
|
2237
|
+
var PROP_GETTER_MARKER2 = Symbol.for("fict:prop-getter");
|
|
2088
2238
|
var propGetters = /* @__PURE__ */ new WeakSet();
|
|
2089
2239
|
var rawToProxy = /* @__PURE__ */ new WeakMap();
|
|
2090
2240
|
var proxyToRaw = /* @__PURE__ */ new WeakMap();
|
|
@@ -2094,7 +2244,7 @@ function __fictProp(getter) {
|
|
|
2094
2244
|
if (Object.isExtensible(getter)) {
|
|
2095
2245
|
try {
|
|
2096
2246
|
;
|
|
2097
|
-
getter[
|
|
2247
|
+
getter[PROP_GETTER_MARKER2] = true;
|
|
2098
2248
|
} catch {
|
|
2099
2249
|
}
|
|
2100
2250
|
}
|
|
@@ -2104,7 +2254,7 @@ function __fictProp(getter) {
|
|
|
2104
2254
|
function isPropGetter(value) {
|
|
2105
2255
|
if (typeof value !== "function") return false;
|
|
2106
2256
|
const fn = value;
|
|
2107
|
-
return propGetters.has(fn) || fn[
|
|
2257
|
+
return propGetters.has(fn) || fn[PROP_GETTER_MARKER2] === true;
|
|
2108
2258
|
}
|
|
2109
2259
|
function createPropsProxy(props) {
|
|
2110
2260
|
if (!props || typeof props !== "object") {
|
|
@@ -2218,6 +2368,13 @@ function mergeProps(...sources) {
|
|
|
2218
2368
|
}
|
|
2219
2369
|
});
|
|
2220
2370
|
}
|
|
2371
|
+
function keyed(target, key, options2) {
|
|
2372
|
+
return prop(() => {
|
|
2373
|
+
const resolvedTarget = isPropGetter(target) ? target() : target;
|
|
2374
|
+
const resolvedKey = typeof key === "function" ? key() : key;
|
|
2375
|
+
return resolvedTarget[resolvedKey];
|
|
2376
|
+
}, options2);
|
|
2377
|
+
}
|
|
2221
2378
|
function prop(getter, options2) {
|
|
2222
2379
|
if (isPropGetter(getter)) {
|
|
2223
2380
|
return getter;
|
|
@@ -2239,6 +2396,7 @@ function prop(getter, options2) {
|
|
|
2239
2396
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
2240
2397
|
var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
|
|
2241
2398
|
var isDev7 = true ? true : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
2399
|
+
var nextComponentId = 1;
|
|
2242
2400
|
function render(view, container) {
|
|
2243
2401
|
const root = createRootContext();
|
|
2244
2402
|
const prev = pushRoot(root);
|
|
@@ -2331,9 +2489,27 @@ function createElementWithContext(node, namespace) {
|
|
|
2331
2489
|
}
|
|
2332
2490
|
});
|
|
2333
2491
|
const props = createPropsProxy(baseProps);
|
|
2334
|
-
|
|
2492
|
+
const hook = isDev7 ? getDevtoolsHook() : void 0;
|
|
2493
|
+
const parentId = hook ? __fictGetCurrentComponentId() : void 0;
|
|
2494
|
+
const componentId = hook ? nextComponentId++ : void 0;
|
|
2495
|
+
if (hook?.registerComponent && componentId !== void 0) {
|
|
2496
|
+
hook.registerComponent(componentId, vnode.type.name || "Anonymous", parentId);
|
|
2497
|
+
}
|
|
2498
|
+
const ctx = __fictPushContext();
|
|
2499
|
+
if (componentId !== void 0) {
|
|
2500
|
+
ctx.componentId = componentId;
|
|
2501
|
+
if (parentId !== void 0) {
|
|
2502
|
+
ctx.parentId = parentId;
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2335
2505
|
try {
|
|
2336
2506
|
const rendered = vnode.type(props);
|
|
2507
|
+
if (hook && componentId !== void 0) {
|
|
2508
|
+
onMount(() => {
|
|
2509
|
+
hook.componentMount?.(componentId);
|
|
2510
|
+
});
|
|
2511
|
+
onCleanup(() => hook.componentUnmount?.(componentId));
|
|
2512
|
+
}
|
|
2337
2513
|
return createElementWithContext(rendered, namespace);
|
|
2338
2514
|
} catch (err) {
|
|
2339
2515
|
if (handleSuspend(err)) {
|
|
@@ -2955,6 +3131,7 @@ export {
|
|
|
2955
3131
|
createRoot,
|
|
2956
3132
|
createSuspenseToken,
|
|
2957
3133
|
hasContext,
|
|
3134
|
+
keyed,
|
|
2958
3135
|
mergeProps,
|
|
2959
3136
|
onCleanup,
|
|
2960
3137
|
onDestroy,
|