@fictjs/runtime 0.2.2 → 0.3.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 +10 -16
- package/dist/advanced.d.ts +10 -16
- package/dist/advanced.js +5 -3
- package/dist/advanced.js.map +1 -1
- package/dist/{chunk-3U7EBKEU.cjs → chunk-ID3WBWNO.cjs} +559 -319
- package/dist/chunk-ID3WBWNO.cjs.map +1 -0
- package/dist/{chunk-3A4VW6AK.cjs → chunk-L4DIV3RC.cjs} +7 -7
- package/dist/{chunk-3A4VW6AK.cjs.map → chunk-L4DIV3RC.cjs.map} +1 -1
- package/dist/{chunk-URDFDRHR.cjs → chunk-M2TSXZ4C.cjs} +16 -16
- package/dist/{chunk-URDFDRHR.cjs.map → chunk-M2TSXZ4C.cjs.map} +1 -1
- package/dist/{chunk-YVS4WJ2W.js → chunk-SO6X7G5S.js} +558 -318
- package/dist/chunk-SO6X7G5S.js.map +1 -0
- package/dist/{chunk-LU2LD2WJ.js → chunk-TWELIZRY.js} +2 -2
- package/dist/{chunk-TEYUDPTA.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 +430 -246
- 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 +1 -1
- package/src/advanced.ts +1 -0
- package/src/binding.ts +30 -4
- package/src/constants.ts +5 -0
- package/src/cycle-guard.ts +164 -103
- 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-3U7EBKEU.cjs.map +0 -1
- package/dist/chunk-YVS4WJ2W.js.map +0 -1
- package/dist/scope-DvgMquEy.d.ts +0 -55
- package/dist/scope-xmdo6lVU.d.cts +0 -55
- /package/dist/{chunk-LU2LD2WJ.js.map → chunk-TWELIZRY.js.map} +0 -0
- /package/dist/{chunk-TEYUDPTA.js.map → chunk-XLIZJMMJ.js.map} +0 -0
|
@@ -25,7 +25,7 @@ var DelegatedEventNames = [
|
|
|
25
25
|
];
|
|
26
26
|
|
|
27
27
|
// src/constants.ts
|
|
28
|
-
var isDev =
|
|
28
|
+
var isDev = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
29
29
|
var booleans = isDev ? [
|
|
30
30
|
"allowfullscreen",
|
|
31
31
|
"async",
|
|
@@ -387,7 +387,7 @@ function getDevtoolsHook() {
|
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
// src/cycle-guard.ts
|
|
390
|
-
var isDev2 =
|
|
390
|
+
var isDev2 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
391
391
|
var setCycleProtectionOptions = () => {
|
|
392
392
|
};
|
|
393
393
|
var resetCycleProtectionStateForTests = () => {
|
|
@@ -400,113 +400,161 @@ var endFlushGuard = () => {
|
|
|
400
400
|
var enterRootGuard = () => true;
|
|
401
401
|
var exitRootGuard = () => {
|
|
402
402
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
403
|
+
var defaultOptions = {
|
|
404
|
+
enabled: true,
|
|
405
|
+
maxFlushCyclesPerMicrotask: 1e4,
|
|
406
|
+
maxEffectRunsPerFlush: 2e4,
|
|
407
|
+
windowSize: 5,
|
|
408
|
+
highUsageRatio: 0.8,
|
|
409
|
+
maxRootReentrantDepth: 10,
|
|
410
|
+
enableWindowWarning: true,
|
|
411
|
+
devMode: isDev2,
|
|
412
|
+
// Backoff warning options
|
|
413
|
+
enableBackoffWarning: isDev2,
|
|
414
|
+
backoffWarningRatio: 0.5
|
|
415
|
+
};
|
|
416
|
+
var enabled = defaultOptions.enabled;
|
|
417
|
+
var options = {
|
|
418
|
+
...defaultOptions
|
|
419
|
+
};
|
|
420
|
+
var effectRunsThisFlush = 0;
|
|
421
|
+
var windowUsage = [];
|
|
422
|
+
var rootDepth = /* @__PURE__ */ new WeakMap();
|
|
423
|
+
var flushWarned = false;
|
|
424
|
+
var rootWarned = false;
|
|
425
|
+
var windowWarned = false;
|
|
426
|
+
var backoffWarned50 = false;
|
|
427
|
+
var backoffWarned75 = false;
|
|
428
|
+
setCycleProtectionOptions = (opts) => {
|
|
429
|
+
if (typeof opts.enabled === "boolean") {
|
|
430
|
+
enabled = opts.enabled;
|
|
431
|
+
}
|
|
432
|
+
options = { ...options, ...opts };
|
|
433
|
+
};
|
|
434
|
+
resetCycleProtectionStateForTests = () => {
|
|
435
|
+
options = { ...defaultOptions };
|
|
436
|
+
enabled = defaultOptions.enabled;
|
|
437
|
+
effectRunsThisFlush = 0;
|
|
438
|
+
windowUsage = [];
|
|
439
|
+
rootDepth = /* @__PURE__ */ new WeakMap();
|
|
440
|
+
flushWarned = false;
|
|
441
|
+
rootWarned = false;
|
|
442
|
+
windowWarned = false;
|
|
443
|
+
backoffWarned50 = false;
|
|
444
|
+
backoffWarned75 = false;
|
|
445
|
+
};
|
|
446
|
+
beginFlushGuard = () => {
|
|
447
|
+
if (!enabled) return;
|
|
448
|
+
effectRunsThisFlush = 0;
|
|
449
|
+
flushWarned = false;
|
|
450
|
+
windowWarned = false;
|
|
451
|
+
backoffWarned50 = false;
|
|
452
|
+
backoffWarned75 = false;
|
|
453
|
+
};
|
|
454
|
+
beforeEffectRunGuard = () => {
|
|
455
|
+
if (!enabled) return true;
|
|
456
|
+
const next = ++effectRunsThisFlush;
|
|
457
|
+
const limit = Math.min(options.maxFlushCyclesPerMicrotask, options.maxEffectRunsPerFlush);
|
|
458
|
+
if (options.enableBackoffWarning && isDev2) {
|
|
459
|
+
const ratio = next / limit;
|
|
460
|
+
const backoffRatio = options.backoffWarningRatio ?? 0.5;
|
|
461
|
+
if (!backoffWarned50 && ratio >= backoffRatio && ratio < backoffRatio + 0.25) {
|
|
462
|
+
backoffWarned50 = true;
|
|
463
|
+
console.warn(
|
|
464
|
+
`[fict] cycle guard: approaching effect limit (${Math.round(ratio * 100)}% of budget used)
|
|
465
|
+
- Current: ${next} effects, Limit: ${limit}
|
|
466
|
+
- Tip: Check for effects that trigger other effects in a loop.
|
|
467
|
+
- Common causes: signal updates inside effects that read and write the same signal.`
|
|
468
|
+
);
|
|
469
|
+
} else if (!backoffWarned75 && ratio >= backoffRatio + 0.25 && ratio < 1) {
|
|
470
|
+
backoffWarned75 = true;
|
|
471
|
+
console.warn(
|
|
472
|
+
`[fict] cycle guard: nearing effect limit (${Math.round(ratio * 100)}% of budget used)
|
|
473
|
+
- Current: ${next} effects, Limit: ${limit}
|
|
474
|
+
- Warning: Consider breaking the reactive dependency cycle.
|
|
475
|
+
- Debug: Use browser devtools to identify the recursive effect chain.`
|
|
476
|
+
);
|
|
451
477
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
if (options.devMode) {
|
|
463
|
-
throw new Error(message);
|
|
464
|
-
}
|
|
465
|
-
if (!rootWarned) {
|
|
466
|
-
rootWarned = true;
|
|
467
|
-
console.warn(message, { depth });
|
|
468
|
-
}
|
|
469
|
-
return false;
|
|
478
|
+
}
|
|
479
|
+
if (next > limit) {
|
|
480
|
+
const message = `[fict] cycle protection triggered: flush-budget-exceeded`;
|
|
481
|
+
if (options.devMode) {
|
|
482
|
+
throw new Error(
|
|
483
|
+
message + `
|
|
484
|
+
- Effect runs: ${next}, Limit: ${limit}
|
|
485
|
+
- This indicates a reactive cycle where effects keep triggering each other.
|
|
486
|
+
- Check for patterns like: createEffect(() => { signal(); signal(newValue); })`
|
|
487
|
+
);
|
|
470
488
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
exitRootGuard = (root) => {
|
|
475
|
-
const depth = rootDepth.get(root);
|
|
476
|
-
if (depth === void 0) return;
|
|
477
|
-
if (depth <= 1) {
|
|
478
|
-
rootDepth.delete(root);
|
|
479
|
-
} else {
|
|
480
|
-
rootDepth.set(root, depth - 1);
|
|
489
|
+
if (!flushWarned) {
|
|
490
|
+
flushWarned = true;
|
|
491
|
+
console.warn(message, { effectRuns: next, limit });
|
|
481
492
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
return true;
|
|
496
|
+
};
|
|
497
|
+
endFlushGuard = () => {
|
|
498
|
+
if (!enabled) return;
|
|
499
|
+
recordWindowUsage(effectRunsThisFlush, options.maxFlushCyclesPerMicrotask);
|
|
500
|
+
effectRunsThisFlush = 0;
|
|
501
|
+
};
|
|
502
|
+
enterRootGuard = (root) => {
|
|
503
|
+
if (!enabled) return true;
|
|
504
|
+
const depth = (rootDepth.get(root) ?? 0) + 1;
|
|
505
|
+
if (depth > options.maxRootReentrantDepth) {
|
|
506
|
+
const message = `[fict] cycle protection triggered: root-reentry`;
|
|
507
|
+
if (options.devMode) {
|
|
508
|
+
throw new Error(
|
|
509
|
+
message + `
|
|
510
|
+
- Re-entry depth: ${depth}, Max allowed: ${options.maxRootReentrantDepth}
|
|
511
|
+
- This indicates recursive render() or component initialization.
|
|
512
|
+
- Check for components that trigger re-renders during their own render phase.`
|
|
513
|
+
);
|
|
499
514
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
|
|
515
|
+
if (!rootWarned) {
|
|
516
|
+
rootWarned = true;
|
|
517
|
+
console.warn(message, { depth, maxAllowed: options.maxRootReentrantDepth });
|
|
518
|
+
}
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
rootDepth.set(root, depth);
|
|
522
|
+
return true;
|
|
523
|
+
};
|
|
524
|
+
exitRootGuard = (root) => {
|
|
525
|
+
if (!enabled) return;
|
|
526
|
+
const depth = rootDepth.get(root);
|
|
527
|
+
if (depth === void 0) return;
|
|
528
|
+
if (depth <= 1) {
|
|
529
|
+
rootDepth.delete(root);
|
|
530
|
+
} else {
|
|
531
|
+
rootDepth.set(root, depth - 1);
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
var recordWindowUsage = (used, budget) => {
|
|
535
|
+
if (!options.enableWindowWarning) return;
|
|
536
|
+
const entry = { used, budget };
|
|
537
|
+
windowUsage.push(entry);
|
|
538
|
+
if (windowUsage.length > options.windowSize) {
|
|
539
|
+
windowUsage.shift();
|
|
540
|
+
}
|
|
541
|
+
if (windowWarned) return;
|
|
542
|
+
if (windowUsage.length >= options.windowSize && windowUsage.every((item) => item.budget > 0 && item.used / item.budget >= options.highUsageRatio)) {
|
|
543
|
+
windowWarned = true;
|
|
544
|
+
reportCycle("high-usage-window", {
|
|
545
|
+
windowSize: options.windowSize,
|
|
546
|
+
ratio: options.highUsageRatio
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
var reportCycle = (reason, detail = void 0) => {
|
|
551
|
+
const hook = getDevtoolsHook();
|
|
552
|
+
hook?.cycleDetected?.(detail ? { reason, detail } : { reason });
|
|
553
|
+
console.warn(`[fict] cycle protection triggered: ${reason}`, detail ?? "");
|
|
554
|
+
};
|
|
507
555
|
|
|
508
556
|
// src/lifecycle.ts
|
|
509
|
-
var isDev3 =
|
|
557
|
+
var isDev3 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
510
558
|
var currentRoot;
|
|
511
559
|
var currentEffectCleanups;
|
|
512
560
|
var globalErrorHandlers = /* @__PURE__ */ new WeakMap();
|
|
@@ -552,13 +600,19 @@ function onCleanup(fn) {
|
|
|
552
600
|
function flushOnMount(root) {
|
|
553
601
|
const cbs = root.onMountCallbacks;
|
|
554
602
|
if (!cbs || cbs.length === 0) return;
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
603
|
+
const prevRoot = currentRoot;
|
|
604
|
+
currentRoot = root;
|
|
605
|
+
try {
|
|
606
|
+
for (let i = 0; i < cbs.length; i++) {
|
|
607
|
+
const cleanup = cbs[i]();
|
|
608
|
+
if (typeof cleanup === "function") {
|
|
609
|
+
root.cleanups.push(cleanup);
|
|
610
|
+
}
|
|
559
611
|
}
|
|
612
|
+
} finally {
|
|
613
|
+
currentRoot = prevRoot;
|
|
614
|
+
cbs.length = 0;
|
|
560
615
|
}
|
|
561
|
-
cbs.length = 0;
|
|
562
616
|
}
|
|
563
617
|
function registerRootCleanup(fn) {
|
|
564
618
|
if (currentRoot) {
|
|
@@ -587,8 +641,8 @@ function destroyRoot(root) {
|
|
|
587
641
|
globalSuspenseHandlers.delete(root);
|
|
588
642
|
}
|
|
589
643
|
}
|
|
590
|
-
function createRoot(fn,
|
|
591
|
-
const parent =
|
|
644
|
+
function createRoot(fn, options2) {
|
|
645
|
+
const parent = options2?.inherit ? currentRoot : void 0;
|
|
592
646
|
const root = createRootContext(parent);
|
|
593
647
|
const prev = pushRoot(root);
|
|
594
648
|
let value;
|
|
@@ -743,8 +797,164 @@ function handleSuspend(token, startRoot) {
|
|
|
743
797
|
return false;
|
|
744
798
|
}
|
|
745
799
|
|
|
800
|
+
// src/effect.ts
|
|
801
|
+
function createEffect(fn) {
|
|
802
|
+
let cleanups = [];
|
|
803
|
+
const rootForError = getCurrentRoot();
|
|
804
|
+
const doCleanup = () => {
|
|
805
|
+
runCleanupList(cleanups);
|
|
806
|
+
cleanups = [];
|
|
807
|
+
};
|
|
808
|
+
const run = () => {
|
|
809
|
+
const bucket = [];
|
|
810
|
+
withEffectCleanups(bucket, () => {
|
|
811
|
+
try {
|
|
812
|
+
const maybeCleanup = fn();
|
|
813
|
+
if (typeof maybeCleanup === "function") {
|
|
814
|
+
bucket.push(maybeCleanup);
|
|
815
|
+
}
|
|
816
|
+
} catch (err) {
|
|
817
|
+
if (handleSuspend(err, rootForError)) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
if (handleError(err, { source: "effect" }, rootForError)) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
throw err;
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
cleanups = bucket;
|
|
827
|
+
};
|
|
828
|
+
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
829
|
+
const teardown = () => {
|
|
830
|
+
runCleanupList(cleanups);
|
|
831
|
+
disposeEffect();
|
|
832
|
+
};
|
|
833
|
+
registerRootCleanup(teardown);
|
|
834
|
+
return teardown;
|
|
835
|
+
}
|
|
836
|
+
function createRenderEffect(fn) {
|
|
837
|
+
let cleanup;
|
|
838
|
+
const rootForError = getCurrentRoot();
|
|
839
|
+
const doCleanup = () => {
|
|
840
|
+
if (cleanup) {
|
|
841
|
+
cleanup();
|
|
842
|
+
cleanup = void 0;
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
const run = () => {
|
|
846
|
+
try {
|
|
847
|
+
const maybeCleanup = fn();
|
|
848
|
+
if (typeof maybeCleanup === "function") {
|
|
849
|
+
cleanup = maybeCleanup;
|
|
850
|
+
}
|
|
851
|
+
} catch (err) {
|
|
852
|
+
if (handleSuspend(err, rootForError)) {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
856
|
+
if (handled) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
throw err;
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
863
|
+
const teardown = () => {
|
|
864
|
+
if (cleanup) {
|
|
865
|
+
cleanup();
|
|
866
|
+
cleanup = void 0;
|
|
867
|
+
}
|
|
868
|
+
disposeEffect();
|
|
869
|
+
};
|
|
870
|
+
registerRootCleanup(teardown);
|
|
871
|
+
return teardown;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// src/hooks.ts
|
|
875
|
+
var isDev4 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
876
|
+
var ctxStack = [];
|
|
877
|
+
function assertRenderContext(ctx, hookName) {
|
|
878
|
+
if (!ctx.rendering) {
|
|
879
|
+
const message = isDev4 ? `${hookName} can only be used during render execution` : "FICT:E_HOOK_RENDER";
|
|
880
|
+
throw new Error(message);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
function __fictUseContext() {
|
|
884
|
+
if (ctxStack.length === 0) {
|
|
885
|
+
const message = isDev4 ? "Invalid hook call: hooks can only be used while rendering a component. Make sure you are not calling hooks in event handlers or outside of components." : "FICT:E_HOOK_OUTSIDE_RENDER";
|
|
886
|
+
throw new Error(message);
|
|
887
|
+
}
|
|
888
|
+
const ctx = ctxStack[ctxStack.length - 1];
|
|
889
|
+
if (!ctx.rendering) {
|
|
890
|
+
ctx.cursor = 0;
|
|
891
|
+
ctx.rendering = true;
|
|
892
|
+
}
|
|
893
|
+
return ctx;
|
|
894
|
+
}
|
|
895
|
+
function __fictPushContext() {
|
|
896
|
+
const ctx = { slots: [], cursor: 0 };
|
|
897
|
+
ctxStack.push(ctx);
|
|
898
|
+
return ctx;
|
|
899
|
+
}
|
|
900
|
+
function __fictGetCurrentComponentId() {
|
|
901
|
+
return ctxStack[ctxStack.length - 1]?.componentId;
|
|
902
|
+
}
|
|
903
|
+
function __fictPopContext() {
|
|
904
|
+
const ctx = ctxStack.pop();
|
|
905
|
+
if (ctx) ctx.rendering = false;
|
|
906
|
+
}
|
|
907
|
+
function __fictResetContext() {
|
|
908
|
+
ctxStack.length = 0;
|
|
909
|
+
}
|
|
910
|
+
function __fictUseSignal(ctx, initial, optionsOrSlot, slot) {
|
|
911
|
+
assertRenderContext(ctx, "__fictUseSignal");
|
|
912
|
+
const options2 = typeof optionsOrSlot === "number" ? void 0 : optionsOrSlot;
|
|
913
|
+
const resolvedSlot = typeof optionsOrSlot === "number" ? optionsOrSlot : slot;
|
|
914
|
+
const index = resolvedSlot ?? ctx.cursor++;
|
|
915
|
+
if (!ctx.slots[index]) {
|
|
916
|
+
ctx.slots[index] = signal(initial, options2);
|
|
917
|
+
}
|
|
918
|
+
return ctx.slots[index];
|
|
919
|
+
}
|
|
920
|
+
function __fictUseMemo(ctx, fn, optionsOrSlot, slot) {
|
|
921
|
+
assertRenderContext(ctx, "__fictUseMemo");
|
|
922
|
+
const options2 = typeof optionsOrSlot === "number" ? void 0 : optionsOrSlot;
|
|
923
|
+
const resolvedSlot = typeof optionsOrSlot === "number" ? optionsOrSlot : slot;
|
|
924
|
+
const index = resolvedSlot ?? ctx.cursor++;
|
|
925
|
+
if (!ctx.slots[index]) {
|
|
926
|
+
ctx.slots[index] = createMemo(fn, options2);
|
|
927
|
+
}
|
|
928
|
+
return ctx.slots[index];
|
|
929
|
+
}
|
|
930
|
+
function __fictUseEffect(ctx, fn, slot) {
|
|
931
|
+
if (slot !== void 0) {
|
|
932
|
+
if (ctx.slots[slot]) {
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
ctx.slots[slot] = createEffect(fn);
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
assertRenderContext(ctx, "__fictUseEffect");
|
|
939
|
+
const index = ctx.cursor++;
|
|
940
|
+
if (!ctx.slots[index]) {
|
|
941
|
+
ctx.slots[index] = createEffect(fn);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function __fictRender(ctx, fn) {
|
|
945
|
+
ctxStack.push(ctx);
|
|
946
|
+
ctx.cursor = 0;
|
|
947
|
+
ctx.rendering = true;
|
|
948
|
+
try {
|
|
949
|
+
return fn();
|
|
950
|
+
} finally {
|
|
951
|
+
ctx.rendering = false;
|
|
952
|
+
ctxStack.pop();
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
|
|
746
956
|
// src/signal.ts
|
|
747
|
-
var
|
|
957
|
+
var isDev5 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
748
958
|
var Mutable = 1;
|
|
749
959
|
var Watching = 2;
|
|
750
960
|
var Running = 4;
|
|
@@ -789,6 +999,7 @@ function link(dep, sub, version) {
|
|
|
789
999
|
else sub.deps = newLink;
|
|
790
1000
|
if (prevSub !== void 0) prevSub.nextSub = newLink;
|
|
791
1001
|
else dep.subs = newLink;
|
|
1002
|
+
if (isDev5) trackDependencyDevtools(dep, sub);
|
|
792
1003
|
}
|
|
793
1004
|
function unlink(lnk, sub = lnk.sub) {
|
|
794
1005
|
const dep = lnk.dep;
|
|
@@ -804,6 +1015,7 @@ function unlink(lnk, sub = lnk.sub) {
|
|
|
804
1015
|
else dep.subsTail = prevSub;
|
|
805
1016
|
if (prevSub !== void 0) prevSub.nextSub = nextSub;
|
|
806
1017
|
else if ((dep.subs = nextSub) === void 0) unwatched(dep);
|
|
1018
|
+
if (isDev5) untrackDependencyDevtools(dep, sub);
|
|
807
1019
|
return nextDep;
|
|
808
1020
|
}
|
|
809
1021
|
function unwatched(dep) {
|
|
@@ -960,6 +1172,11 @@ function shallowPropagate(firstLink) {
|
|
|
960
1172
|
function update(node) {
|
|
961
1173
|
return "getter" in node && node.getter !== void 0 ? updateComputed(node) : updateSignal(node);
|
|
962
1174
|
}
|
|
1175
|
+
function valuesDiffer(node, prev, next) {
|
|
1176
|
+
if (node.equals === false) return true;
|
|
1177
|
+
if (typeof node.equals === "function") return !node.equals(prev, next);
|
|
1178
|
+
return prev !== next;
|
|
1179
|
+
}
|
|
963
1180
|
function notify(effect2) {
|
|
964
1181
|
effect2.flags &= ~Watching;
|
|
965
1182
|
const effects = [];
|
|
@@ -996,7 +1213,7 @@ function updateSignal(s) {
|
|
|
996
1213
|
s.flags = Mutable;
|
|
997
1214
|
const current = s.currentValue;
|
|
998
1215
|
const pending = s.pendingValue;
|
|
999
|
-
if (current
|
|
1216
|
+
if (valuesDiffer(s, current, pending)) {
|
|
1000
1217
|
s.currentValue = pending;
|
|
1001
1218
|
return true;
|
|
1002
1219
|
}
|
|
@@ -1014,8 +1231,9 @@ function updateComputed(c) {
|
|
|
1014
1231
|
activeSub = prevSub;
|
|
1015
1232
|
c.flags &= ~Running;
|
|
1016
1233
|
purgeDeps(c);
|
|
1017
|
-
if (oldValue
|
|
1234
|
+
if (valuesDiffer(c, oldValue, newValue)) {
|
|
1018
1235
|
c.value = newValue;
|
|
1236
|
+
if (isDev5) updateComputedDevtools(c, newValue);
|
|
1019
1237
|
return true;
|
|
1020
1238
|
}
|
|
1021
1239
|
return false;
|
|
@@ -1037,7 +1255,7 @@ function runEffect(e) {
|
|
|
1037
1255
|
}
|
|
1038
1256
|
}
|
|
1039
1257
|
++cycle;
|
|
1040
|
-
effectRunDevtools(e);
|
|
1258
|
+
if (isDev5) effectRunDevtools(e);
|
|
1041
1259
|
e.depsTail = void 0;
|
|
1042
1260
|
e.flags = WatchingRunning;
|
|
1043
1261
|
const prevSub = activeSub;
|
|
@@ -1081,7 +1299,7 @@ function runEffect(e) {
|
|
|
1081
1299
|
}
|
|
1082
1300
|
if (isDirty) {
|
|
1083
1301
|
++cycle;
|
|
1084
|
-
effectRunDevtools(e);
|
|
1302
|
+
if (isDev5) effectRunDevtools(e);
|
|
1085
1303
|
e.depsTail = void 0;
|
|
1086
1304
|
e.flags = WatchingRunning;
|
|
1087
1305
|
const prevSub = activeSub;
|
|
@@ -1130,10 +1348,21 @@ function flush() {
|
|
|
1130
1348
|
while (highIndex < highPriorityQueue.length) {
|
|
1131
1349
|
const e = highPriorityQueue[highIndex];
|
|
1132
1350
|
if (!beforeEffectRunGuard()) {
|
|
1133
|
-
|
|
1134
|
-
highPriorityQueue
|
|
1135
|
-
|
|
1351
|
+
for (let i = 0; i < highPriorityQueue.length; i++) {
|
|
1352
|
+
const queued = highPriorityQueue[i];
|
|
1353
|
+
if (queued && queued.flags !== 0) {
|
|
1354
|
+
queued.flags = Watching;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
for (let i = 0; i < lowPriorityQueue.length; i++) {
|
|
1358
|
+
const queued = lowPriorityQueue[i];
|
|
1359
|
+
if (queued && queued.flags !== 0) {
|
|
1360
|
+
queued.flags = Watching;
|
|
1361
|
+
}
|
|
1136
1362
|
}
|
|
1363
|
+
highPriorityQueue.length = 0;
|
|
1364
|
+
lowPriorityQueue.length = 0;
|
|
1365
|
+
flushScheduled = false;
|
|
1137
1366
|
endFlushGuard();
|
|
1138
1367
|
return;
|
|
1139
1368
|
}
|
|
@@ -1154,10 +1383,21 @@ function flush() {
|
|
|
1154
1383
|
}
|
|
1155
1384
|
const e = lowPriorityQueue[lowIndex];
|
|
1156
1385
|
if (!beforeEffectRunGuard()) {
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1386
|
+
for (let i = 0; i < highPriorityQueue.length; i++) {
|
|
1387
|
+
const queued = highPriorityQueue[i];
|
|
1388
|
+
if (queued && queued.flags !== 0) {
|
|
1389
|
+
queued.flags = Watching;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
for (let i = 0; i < lowPriorityQueue.length; i++) {
|
|
1393
|
+
const queued = lowPriorityQueue[i];
|
|
1394
|
+
if (queued && queued.flags !== 0) {
|
|
1395
|
+
queued.flags = Watching;
|
|
1396
|
+
}
|
|
1160
1397
|
}
|
|
1398
|
+
highPriorityQueue.length = 0;
|
|
1399
|
+
lowPriorityQueue.length = 0;
|
|
1400
|
+
flushScheduled = false;
|
|
1161
1401
|
endFlushGuard();
|
|
1162
1402
|
return;
|
|
1163
1403
|
}
|
|
@@ -1167,26 +1407,31 @@ function flush() {
|
|
|
1167
1407
|
lowPriorityQueue.length = 0;
|
|
1168
1408
|
endFlushGuard();
|
|
1169
1409
|
}
|
|
1170
|
-
function signal(initialValue) {
|
|
1410
|
+
function signal(initialValue, options2) {
|
|
1171
1411
|
const s = {
|
|
1172
1412
|
currentValue: initialValue,
|
|
1173
1413
|
pendingValue: initialValue,
|
|
1174
1414
|
subs: void 0,
|
|
1175
1415
|
subsTail: void 0,
|
|
1176
1416
|
flags: Mutable,
|
|
1177
|
-
__id: void 0
|
|
1417
|
+
__id: void 0,
|
|
1418
|
+
...options2?.equals !== void 0 ? { equals: options2.equals } : {},
|
|
1419
|
+
...options2?.name !== void 0 ? { name: options2.name } : {},
|
|
1420
|
+
...options2?.devToolsSource !== void 0 ? { devToolsSource: options2.devToolsSource } : {}
|
|
1178
1421
|
};
|
|
1179
|
-
registerSignalDevtools(
|
|
1422
|
+
if (isDev5) registerSignalDevtools(s);
|
|
1180
1423
|
const accessor = signalOper.bind(s);
|
|
1181
1424
|
accessor[SIGNAL_MARKER] = true;
|
|
1182
1425
|
return accessor;
|
|
1183
1426
|
}
|
|
1184
1427
|
function signalOper(value) {
|
|
1185
1428
|
if (arguments.length > 0) {
|
|
1186
|
-
|
|
1187
|
-
|
|
1429
|
+
const next = value;
|
|
1430
|
+
const prev = this.pendingValue;
|
|
1431
|
+
if (valuesDiffer(this, prev, next)) {
|
|
1432
|
+
this.pendingValue = next;
|
|
1188
1433
|
this.flags = MutableDirty;
|
|
1189
|
-
updateSignalDevtools(this,
|
|
1434
|
+
if (isDev5) updateSignalDevtools(this, next);
|
|
1190
1435
|
const subs = this.subs;
|
|
1191
1436
|
if (subs !== void 0) {
|
|
1192
1437
|
propagate(subs);
|
|
@@ -1213,7 +1458,7 @@ function signalOper(value) {
|
|
|
1213
1458
|
}
|
|
1214
1459
|
return this.currentValue;
|
|
1215
1460
|
}
|
|
1216
|
-
function computed(getter) {
|
|
1461
|
+
function computed(getter, options2) {
|
|
1217
1462
|
const c = {
|
|
1218
1463
|
value: void 0,
|
|
1219
1464
|
subs: void 0,
|
|
@@ -1221,13 +1466,21 @@ function computed(getter) {
|
|
|
1221
1466
|
deps: void 0,
|
|
1222
1467
|
depsTail: void 0,
|
|
1223
1468
|
flags: 0,
|
|
1224
|
-
getter
|
|
1469
|
+
getter,
|
|
1470
|
+
__id: void 0,
|
|
1471
|
+
...options2?.equals !== void 0 ? { equals: options2.equals } : {},
|
|
1472
|
+
...options2?.name !== void 0 ? { name: options2.name } : {},
|
|
1473
|
+
...options2?.devToolsSource !== void 0 ? { devToolsSource: options2.devToolsSource } : {}
|
|
1225
1474
|
};
|
|
1226
|
-
|
|
1475
|
+
if (isDev5) registerComputedDevtools(c);
|
|
1476
|
+
const bound = computedOper.bind(
|
|
1477
|
+
c
|
|
1478
|
+
);
|
|
1227
1479
|
bound[COMPUTED_MARKER] = true;
|
|
1228
1480
|
return bound;
|
|
1229
1481
|
}
|
|
1230
1482
|
function computedOper() {
|
|
1483
|
+
if (inCleanup) return this.value;
|
|
1231
1484
|
const flags = this.flags;
|
|
1232
1485
|
if (flags & Dirty) {
|
|
1233
1486
|
if (updateComputed(this)) {
|
|
@@ -1248,6 +1501,7 @@ function computedOper() {
|
|
|
1248
1501
|
const prevSub = setActiveSub(this);
|
|
1249
1502
|
try {
|
|
1250
1503
|
this.value = this.getter(void 0);
|
|
1504
|
+
if (isDev5) updateComputedDevtools(this, this.value);
|
|
1251
1505
|
} finally {
|
|
1252
1506
|
setActiveSub(prevSub);
|
|
1253
1507
|
this.flags &= ~Running;
|
|
@@ -1270,12 +1524,12 @@ function effect(fn) {
|
|
|
1270
1524
|
if (root) {
|
|
1271
1525
|
e.root = root;
|
|
1272
1526
|
}
|
|
1273
|
-
registerEffectDevtools(e);
|
|
1527
|
+
if (isDev5) registerEffectDevtools(e);
|
|
1274
1528
|
const prevSub = activeSub;
|
|
1275
1529
|
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
1276
1530
|
activeSub = e;
|
|
1277
1531
|
try {
|
|
1278
|
-
effectRunDevtools(e);
|
|
1532
|
+
if (isDev5) effectRunDevtools(e);
|
|
1279
1533
|
fn();
|
|
1280
1534
|
} finally {
|
|
1281
1535
|
activeSub = prevSub;
|
|
@@ -1300,12 +1554,12 @@ function effectWithCleanup(fn, cleanupRunner, root) {
|
|
|
1300
1554
|
if (resolvedRoot) {
|
|
1301
1555
|
e.root = resolvedRoot;
|
|
1302
1556
|
}
|
|
1303
|
-
registerEffectDevtools(e);
|
|
1557
|
+
if (isDev5) registerEffectDevtools(e);
|
|
1304
1558
|
const prevSub = activeSub;
|
|
1305
1559
|
if (prevSub !== void 0) link(e, prevSub, 0);
|
|
1306
1560
|
activeSub = e;
|
|
1307
1561
|
try {
|
|
1308
|
-
effectRunDevtools(e);
|
|
1562
|
+
if (isDev5) effectRunDevtools(e);
|
|
1309
1563
|
fn();
|
|
1310
1564
|
} finally {
|
|
1311
1565
|
activeSub = prevSub;
|
|
@@ -1365,6 +1619,16 @@ function setActiveSub(sub) {
|
|
|
1365
1619
|
activeSub = sub;
|
|
1366
1620
|
return prev;
|
|
1367
1621
|
}
|
|
1622
|
+
function __resetReactiveState() {
|
|
1623
|
+
highPriorityQueue.length = 0;
|
|
1624
|
+
lowPriorityQueue.length = 0;
|
|
1625
|
+
batchDepth = 0;
|
|
1626
|
+
activeSub = void 0;
|
|
1627
|
+
flushScheduled = false;
|
|
1628
|
+
isInTransition = false;
|
|
1629
|
+
inCleanup = false;
|
|
1630
|
+
cycle = 0;
|
|
1631
|
+
}
|
|
1368
1632
|
function untrack(fn) {
|
|
1369
1633
|
const prev = activeSub;
|
|
1370
1634
|
activeSub = void 0;
|
|
@@ -1394,17 +1658,28 @@ function setTransitionContext(value) {
|
|
|
1394
1658
|
var registerSignalDevtools = () => void 0;
|
|
1395
1659
|
var updateSignalDevtools = () => {
|
|
1396
1660
|
};
|
|
1661
|
+
var registerComputedDevtools = () => void 0;
|
|
1662
|
+
var updateComputedDevtools = () => {
|
|
1663
|
+
};
|
|
1397
1664
|
var registerEffectDevtools = () => void 0;
|
|
1398
1665
|
var effectRunDevtools = () => {
|
|
1399
1666
|
};
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1667
|
+
var trackDependencyDevtools = () => {
|
|
1668
|
+
};
|
|
1669
|
+
var untrackDependencyDevtools = () => {
|
|
1670
|
+
};
|
|
1671
|
+
if (isDev5) {
|
|
1672
|
+
let nextDevtoolsId = 0;
|
|
1673
|
+
registerSignalDevtools = (node) => {
|
|
1404
1674
|
const hook = getDevtoolsHook();
|
|
1405
1675
|
if (!hook) return void 0;
|
|
1406
|
-
const id = ++
|
|
1407
|
-
|
|
1676
|
+
const id = ++nextDevtoolsId;
|
|
1677
|
+
const options2 = {};
|
|
1678
|
+
if (node.name !== void 0) options2.name = node.name;
|
|
1679
|
+
if (node.devToolsSource !== void 0) options2.source = node.devToolsSource;
|
|
1680
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1681
|
+
if (ownerId !== void 0) options2.ownerId = ownerId;
|
|
1682
|
+
hook.registerSignal(id, node.currentValue, options2);
|
|
1408
1683
|
node.__id = id;
|
|
1409
1684
|
return id;
|
|
1410
1685
|
};
|
|
@@ -1414,11 +1689,32 @@ if (isDev4) {
|
|
|
1414
1689
|
const id = node.__id;
|
|
1415
1690
|
if (id) hook.updateSignal(id, value);
|
|
1416
1691
|
};
|
|
1692
|
+
registerComputedDevtools = (node) => {
|
|
1693
|
+
const hook = getDevtoolsHook();
|
|
1694
|
+
if (!hook) return void 0;
|
|
1695
|
+
const id = ++nextDevtoolsId;
|
|
1696
|
+
const options2 = {};
|
|
1697
|
+
if (node.name !== void 0) options2.name = node.name;
|
|
1698
|
+
if (node.devToolsSource !== void 0) options2.source = node.devToolsSource;
|
|
1699
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1700
|
+
if (ownerId !== void 0) options2.ownerId = ownerId;
|
|
1701
|
+
options2.hasValue = false;
|
|
1702
|
+
hook.registerComputed(id, node.value, options2);
|
|
1703
|
+
node.__id = id;
|
|
1704
|
+
return id;
|
|
1705
|
+
};
|
|
1706
|
+
updateComputedDevtools = (node, value) => {
|
|
1707
|
+
const hook = getDevtoolsHook();
|
|
1708
|
+
if (!hook) return;
|
|
1709
|
+
const id = node.__id;
|
|
1710
|
+
if (id) hook.updateComputed(id, value);
|
|
1711
|
+
};
|
|
1417
1712
|
registerEffectDevtools = (node) => {
|
|
1418
1713
|
const hook = getDevtoolsHook();
|
|
1419
1714
|
if (!hook) return void 0;
|
|
1420
|
-
const id = ++
|
|
1421
|
-
|
|
1715
|
+
const id = ++nextDevtoolsId;
|
|
1716
|
+
const ownerId = __fictGetCurrentComponentId();
|
|
1717
|
+
hook.registerEffect(id, ownerId !== void 0 ? { ownerId } : void 0);
|
|
1422
1718
|
node.__id = id;
|
|
1423
1719
|
return id;
|
|
1424
1720
|
};
|
|
@@ -1428,6 +1724,20 @@ if (isDev4) {
|
|
|
1428
1724
|
const id = node.__id;
|
|
1429
1725
|
if (id) hook.effectRun(id);
|
|
1430
1726
|
};
|
|
1727
|
+
trackDependencyDevtools = (dep, sub) => {
|
|
1728
|
+
const hook = getDevtoolsHook();
|
|
1729
|
+
if (!hook?.trackDependency) return;
|
|
1730
|
+
const depId = dep.__id;
|
|
1731
|
+
const subId = sub.__id;
|
|
1732
|
+
if (depId && subId) hook.trackDependency(subId, depId);
|
|
1733
|
+
};
|
|
1734
|
+
untrackDependencyDevtools = (dep, sub) => {
|
|
1735
|
+
const hook = getDevtoolsHook();
|
|
1736
|
+
if (!hook?.untrackDependency) return;
|
|
1737
|
+
const depId = dep.__id;
|
|
1738
|
+
const subId = sub.__id;
|
|
1739
|
+
if (depId && subId) hook.untrackDependency(subId, depId);
|
|
1740
|
+
};
|
|
1431
1741
|
}
|
|
1432
1742
|
function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
1433
1743
|
let current = source();
|
|
@@ -1456,78 +1766,9 @@ function createSelector(source, equalityFn = (a, b) => a === b) {
|
|
|
1456
1766
|
};
|
|
1457
1767
|
}
|
|
1458
1768
|
|
|
1459
|
-
// src/
|
|
1460
|
-
function
|
|
1461
|
-
|
|
1462
|
-
const rootForError = getCurrentRoot();
|
|
1463
|
-
const doCleanup = () => {
|
|
1464
|
-
runCleanupList(cleanups);
|
|
1465
|
-
cleanups = [];
|
|
1466
|
-
};
|
|
1467
|
-
const run = () => {
|
|
1468
|
-
const bucket = [];
|
|
1469
|
-
withEffectCleanups(bucket, () => {
|
|
1470
|
-
try {
|
|
1471
|
-
const maybeCleanup = fn();
|
|
1472
|
-
if (typeof maybeCleanup === "function") {
|
|
1473
|
-
bucket.push(maybeCleanup);
|
|
1474
|
-
}
|
|
1475
|
-
} catch (err) {
|
|
1476
|
-
if (handleSuspend(err, rootForError)) {
|
|
1477
|
-
return;
|
|
1478
|
-
}
|
|
1479
|
-
if (handleError(err, { source: "effect" }, rootForError)) {
|
|
1480
|
-
return;
|
|
1481
|
-
}
|
|
1482
|
-
throw err;
|
|
1483
|
-
}
|
|
1484
|
-
});
|
|
1485
|
-
cleanups = bucket;
|
|
1486
|
-
};
|
|
1487
|
-
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
1488
|
-
const teardown = () => {
|
|
1489
|
-
runCleanupList(cleanups);
|
|
1490
|
-
disposeEffect();
|
|
1491
|
-
};
|
|
1492
|
-
registerRootCleanup(teardown);
|
|
1493
|
-
return teardown;
|
|
1494
|
-
}
|
|
1495
|
-
function createRenderEffect(fn) {
|
|
1496
|
-
let cleanup;
|
|
1497
|
-
const rootForError = getCurrentRoot();
|
|
1498
|
-
const doCleanup = () => {
|
|
1499
|
-
if (cleanup) {
|
|
1500
|
-
cleanup();
|
|
1501
|
-
cleanup = void 0;
|
|
1502
|
-
}
|
|
1503
|
-
};
|
|
1504
|
-
const run = () => {
|
|
1505
|
-
try {
|
|
1506
|
-
const maybeCleanup = fn();
|
|
1507
|
-
if (typeof maybeCleanup === "function") {
|
|
1508
|
-
cleanup = maybeCleanup;
|
|
1509
|
-
}
|
|
1510
|
-
} catch (err) {
|
|
1511
|
-
if (handleSuspend(err, rootForError)) {
|
|
1512
|
-
return;
|
|
1513
|
-
}
|
|
1514
|
-
const handled = handleError(err, { source: "effect" }, rootForError);
|
|
1515
|
-
if (handled) {
|
|
1516
|
-
return;
|
|
1517
|
-
}
|
|
1518
|
-
throw err;
|
|
1519
|
-
}
|
|
1520
|
-
};
|
|
1521
|
-
const disposeEffect = effectWithCleanup(run, doCleanup, rootForError);
|
|
1522
|
-
const teardown = () => {
|
|
1523
|
-
if (cleanup) {
|
|
1524
|
-
cleanup();
|
|
1525
|
-
cleanup = void 0;
|
|
1526
|
-
}
|
|
1527
|
-
disposeEffect();
|
|
1528
|
-
};
|
|
1529
|
-
registerRootCleanup(teardown);
|
|
1530
|
-
return teardown;
|
|
1769
|
+
// src/memo.ts
|
|
1770
|
+
function createMemo(fn, options2) {
|
|
1771
|
+
return computed(fn, options2);
|
|
1531
1772
|
}
|
|
1532
1773
|
|
|
1533
1774
|
// src/jsx.ts
|
|
@@ -1723,13 +1964,22 @@ function untrack2(fn) {
|
|
|
1723
1964
|
}
|
|
1724
1965
|
|
|
1725
1966
|
// src/binding.ts
|
|
1726
|
-
var
|
|
1967
|
+
var isDev6 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
1727
1968
|
function isReactive(value) {
|
|
1728
1969
|
if (typeof value !== "function") return false;
|
|
1729
1970
|
if (isSignal(value) || isComputed(value)) return true;
|
|
1730
1971
|
if (isEffect(value) || isEffectScope(value)) return false;
|
|
1731
1972
|
return value.length === 0;
|
|
1732
1973
|
}
|
|
1974
|
+
function isStrictlyReactive(value) {
|
|
1975
|
+
if (typeof value !== "function") return false;
|
|
1976
|
+
return isSignal(value) || isComputed(value) || isPropGetterFn(value);
|
|
1977
|
+
}
|
|
1978
|
+
var PROP_GETTER_MARKER = Symbol.for("fict:prop-getter");
|
|
1979
|
+
function isPropGetterFn(value) {
|
|
1980
|
+
if (typeof value !== "function") return false;
|
|
1981
|
+
return value[PROP_GETTER_MARKER] === true;
|
|
1982
|
+
}
|
|
1733
1983
|
function unwrap(value) {
|
|
1734
1984
|
return isReactive(value) ? value() : value;
|
|
1735
1985
|
}
|
|
@@ -1896,7 +2146,7 @@ function applyStyle(el, value, prev) {
|
|
|
1896
2146
|
}
|
|
1897
2147
|
}
|
|
1898
2148
|
}
|
|
1899
|
-
var isUnitlessStyleProperty =
|
|
2149
|
+
var isUnitlessStyleProperty = isDev6 ? (prop2) => UnitlessStyles.has(prop2) : (prop2) => prop2 === "opacity" || prop2 === "zIndex";
|
|
1900
2150
|
function createClassBinding(el, value) {
|
|
1901
2151
|
if (isReactive(value)) {
|
|
1902
2152
|
let prev = {};
|
|
@@ -2275,15 +2525,15 @@ function addEventListener(node, name, handler, delegate) {
|
|
|
2275
2525
|
node.addEventListener(name, handler);
|
|
2276
2526
|
}
|
|
2277
2527
|
}
|
|
2278
|
-
function bindEvent(el, eventName, handler,
|
|
2528
|
+
function bindEvent(el, eventName, handler, options2) {
|
|
2279
2529
|
if (handler == null) return () => {
|
|
2280
2530
|
};
|
|
2281
2531
|
const rootRef = getCurrentRoot();
|
|
2282
|
-
const shouldDelegate =
|
|
2532
|
+
const shouldDelegate = options2 == null && DelegatedEvents.has(eventName);
|
|
2283
2533
|
if (shouldDelegate) {
|
|
2284
2534
|
const key = `$$${eventName}`;
|
|
2285
2535
|
delegateEvents([eventName]);
|
|
2286
|
-
const resolveHandler =
|
|
2536
|
+
const resolveHandler = isStrictlyReactive(handler) ? handler : () => handler;
|
|
2287
2537
|
el[key] = function(...args) {
|
|
2288
2538
|
try {
|
|
2289
2539
|
const fn = resolveHandler();
|
|
@@ -2298,7 +2548,7 @@ function bindEvent(el, eventName, handler, options) {
|
|
|
2298
2548
|
el[key] = void 0;
|
|
2299
2549
|
};
|
|
2300
2550
|
}
|
|
2301
|
-
const getHandler =
|
|
2551
|
+
const getHandler = isStrictlyReactive(handler) ? handler : () => handler;
|
|
2302
2552
|
const wrapped = (event) => {
|
|
2303
2553
|
try {
|
|
2304
2554
|
const resolved = getHandler();
|
|
@@ -2310,8 +2560,8 @@ function bindEvent(el, eventName, handler, options) {
|
|
|
2310
2560
|
throw err;
|
|
2311
2561
|
}
|
|
2312
2562
|
};
|
|
2313
|
-
el.addEventListener(eventName, wrapped,
|
|
2314
|
-
const cleanup = () => el.removeEventListener(eventName, wrapped,
|
|
2563
|
+
el.addEventListener(eventName, wrapped, options2);
|
|
2564
|
+
const cleanup = () => el.removeEventListener(eventName, wrapped, options2);
|
|
2315
2565
|
registerRootCleanup(cleanup);
|
|
2316
2566
|
return cleanup;
|
|
2317
2567
|
}
|
|
@@ -2460,9 +2710,9 @@ function assignProp(node, prop2, value, prev, isSVG, skipRef, props) {
|
|
|
2460
2710
|
}
|
|
2461
2711
|
const isCE = node.nodeName.includes("-") || "is" in props;
|
|
2462
2712
|
if (!isSVG) {
|
|
2463
|
-
const propAlias =
|
|
2464
|
-
const isProperty =
|
|
2465
|
-
const isChildProp =
|
|
2713
|
+
const propAlias = isDev6 ? getPropAlias(prop2, node.tagName) : void 0;
|
|
2714
|
+
const isProperty = isDev6 ? Properties.has(prop2) : prop2 in node;
|
|
2715
|
+
const isChildProp = isDev6 ? ChildProperties.has(prop2) : prop2 === "innerHTML" || prop2 === "textContent" || prop2 === "innerText" || prop2 === "children";
|
|
2466
2716
|
if (propAlias || isProperty || isChildProp || isCE) {
|
|
2467
2717
|
const propName = propAlias || prop2;
|
|
2468
2718
|
if (isCE && !isProperty && !isChildProp && !propAlias) {
|
|
@@ -2659,79 +2909,8 @@ function createPortal(container, render2, createElementFn) {
|
|
|
2659
2909
|
};
|
|
2660
2910
|
}
|
|
2661
2911
|
|
|
2662
|
-
// src/memo.ts
|
|
2663
|
-
function createMemo(fn) {
|
|
2664
|
-
return computed(fn);
|
|
2665
|
-
}
|
|
2666
|
-
|
|
2667
|
-
// src/hooks.ts
|
|
2668
|
-
var isDev6 = true ? false : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
2669
|
-
var ctxStack = [];
|
|
2670
|
-
function assertRenderContext(ctx, hookName) {
|
|
2671
|
-
if (!ctx.rendering) {
|
|
2672
|
-
const message = isDev6 ? `${hookName} can only be used during render execution` : "FICT:E_HOOK_RENDER";
|
|
2673
|
-
throw new Error(message);
|
|
2674
|
-
}
|
|
2675
|
-
}
|
|
2676
|
-
function __fictUseContext() {
|
|
2677
|
-
if (ctxStack.length === 0) {
|
|
2678
|
-
const ctx2 = { slots: [], cursor: 0, rendering: true };
|
|
2679
|
-
ctxStack.push(ctx2);
|
|
2680
|
-
return ctx2;
|
|
2681
|
-
}
|
|
2682
|
-
const ctx = ctxStack[ctxStack.length - 1];
|
|
2683
|
-
ctx.cursor = 0;
|
|
2684
|
-
ctx.rendering = true;
|
|
2685
|
-
return ctx;
|
|
2686
|
-
}
|
|
2687
|
-
function __fictPushContext() {
|
|
2688
|
-
const ctx = { slots: [], cursor: 0 };
|
|
2689
|
-
ctxStack.push(ctx);
|
|
2690
|
-
return ctx;
|
|
2691
|
-
}
|
|
2692
|
-
function __fictPopContext() {
|
|
2693
|
-
ctxStack.pop();
|
|
2694
|
-
}
|
|
2695
|
-
function __fictResetContext() {
|
|
2696
|
-
ctxStack.length = 0;
|
|
2697
|
-
}
|
|
2698
|
-
function __fictUseSignal(ctx, initial, slot) {
|
|
2699
|
-
assertRenderContext(ctx, "__fictUseSignal");
|
|
2700
|
-
const index = slot ?? ctx.cursor++;
|
|
2701
|
-
if (!ctx.slots[index]) {
|
|
2702
|
-
ctx.slots[index] = signal(initial);
|
|
2703
|
-
}
|
|
2704
|
-
return ctx.slots[index];
|
|
2705
|
-
}
|
|
2706
|
-
function __fictUseMemo(ctx, fn, slot) {
|
|
2707
|
-
assertRenderContext(ctx, "__fictUseMemo");
|
|
2708
|
-
const index = slot ?? ctx.cursor++;
|
|
2709
|
-
if (!ctx.slots[index]) {
|
|
2710
|
-
ctx.slots[index] = createMemo(fn);
|
|
2711
|
-
}
|
|
2712
|
-
return ctx.slots[index];
|
|
2713
|
-
}
|
|
2714
|
-
function __fictUseEffect(ctx, fn, slot) {
|
|
2715
|
-
assertRenderContext(ctx, "__fictUseEffect");
|
|
2716
|
-
const index = slot ?? ctx.cursor++;
|
|
2717
|
-
if (!ctx.slots[index]) {
|
|
2718
|
-
ctx.slots[index] = createEffect(fn);
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
function __fictRender(ctx, fn) {
|
|
2722
|
-
ctxStack.push(ctx);
|
|
2723
|
-
ctx.cursor = 0;
|
|
2724
|
-
ctx.rendering = true;
|
|
2725
|
-
try {
|
|
2726
|
-
return fn();
|
|
2727
|
-
} finally {
|
|
2728
|
-
ctx.rendering = false;
|
|
2729
|
-
ctxStack.pop();
|
|
2730
|
-
}
|
|
2731
|
-
}
|
|
2732
|
-
|
|
2733
2912
|
// src/props.ts
|
|
2734
|
-
var
|
|
2913
|
+
var PROP_GETTER_MARKER2 = Symbol.for("fict:prop-getter");
|
|
2735
2914
|
var propGetters = /* @__PURE__ */ new WeakSet();
|
|
2736
2915
|
var rawToProxy = /* @__PURE__ */ new WeakMap();
|
|
2737
2916
|
var proxyToRaw = /* @__PURE__ */ new WeakMap();
|
|
@@ -2741,7 +2920,7 @@ function __fictProp(getter) {
|
|
|
2741
2920
|
if (Object.isExtensible(getter)) {
|
|
2742
2921
|
try {
|
|
2743
2922
|
;
|
|
2744
|
-
getter[
|
|
2923
|
+
getter[PROP_GETTER_MARKER2] = true;
|
|
2745
2924
|
} catch {
|
|
2746
2925
|
}
|
|
2747
2926
|
}
|
|
@@ -2751,7 +2930,7 @@ function __fictProp(getter) {
|
|
|
2751
2930
|
function isPropGetter(value) {
|
|
2752
2931
|
if (typeof value !== "function") return false;
|
|
2753
2932
|
const fn = value;
|
|
2754
|
-
return propGetters.has(fn) || fn[
|
|
2933
|
+
return propGetters.has(fn) || fn[PROP_GETTER_MARKER2] === true;
|
|
2755
2934
|
}
|
|
2756
2935
|
function createPropsProxy(props) {
|
|
2757
2936
|
if (!props || typeof props !== "object") {
|
|
@@ -2875,12 +3054,19 @@ function mergeProps(...sources) {
|
|
|
2875
3054
|
}
|
|
2876
3055
|
});
|
|
2877
3056
|
}
|
|
2878
|
-
function
|
|
3057
|
+
function keyed(target, key, options2) {
|
|
3058
|
+
return prop(() => {
|
|
3059
|
+
const resolvedTarget = isPropGetter(target) ? target() : target;
|
|
3060
|
+
const resolvedKey = typeof key === "function" ? key() : key;
|
|
3061
|
+
return resolvedTarget[resolvedKey];
|
|
3062
|
+
}, options2);
|
|
3063
|
+
}
|
|
3064
|
+
function prop(getter, options2) {
|
|
2879
3065
|
if (isPropGetter(getter)) {
|
|
2880
3066
|
return getter;
|
|
2881
3067
|
}
|
|
2882
3068
|
const fn = getter;
|
|
2883
|
-
const unwrap2 =
|
|
3069
|
+
const unwrap2 = options2?.unwrap !== false;
|
|
2884
3070
|
return __fictProp(
|
|
2885
3071
|
createMemo(() => {
|
|
2886
3072
|
const value = fn();
|
|
@@ -2895,7 +3081,8 @@ function prop(getter, options) {
|
|
|
2895
3081
|
// src/dom.ts
|
|
2896
3082
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
2897
3083
|
var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
|
|
2898
|
-
var isDev7 =
|
|
3084
|
+
var isDev7 = typeof __DEV__ !== "undefined" ? __DEV__ : typeof process === "undefined" || process.env?.NODE_ENV !== "production";
|
|
3085
|
+
var nextComponentId = 1;
|
|
2899
3086
|
function render(view, container) {
|
|
2900
3087
|
const root = createRootContext();
|
|
2901
3088
|
const prev = pushRoot(root);
|
|
@@ -2988,9 +3175,27 @@ function createElementWithContext(node, namespace) {
|
|
|
2988
3175
|
}
|
|
2989
3176
|
});
|
|
2990
3177
|
const props = createPropsProxy(baseProps);
|
|
2991
|
-
|
|
3178
|
+
const hook = isDev7 ? getDevtoolsHook() : void 0;
|
|
3179
|
+
const parentId = hook ? __fictGetCurrentComponentId() : void 0;
|
|
3180
|
+
const componentId = hook ? nextComponentId++ : void 0;
|
|
3181
|
+
if (hook?.registerComponent && componentId !== void 0) {
|
|
3182
|
+
hook.registerComponent(componentId, vnode.type.name || "Anonymous", parentId);
|
|
3183
|
+
}
|
|
3184
|
+
const ctx = __fictPushContext();
|
|
3185
|
+
if (componentId !== void 0) {
|
|
3186
|
+
ctx.componentId = componentId;
|
|
3187
|
+
if (parentId !== void 0) {
|
|
3188
|
+
ctx.parentId = parentId;
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
2992
3191
|
try {
|
|
2993
3192
|
const rendered = vnode.type(props);
|
|
3193
|
+
if (hook && componentId !== void 0) {
|
|
3194
|
+
onMount(() => {
|
|
3195
|
+
hook.componentMount?.(componentId);
|
|
3196
|
+
});
|
|
3197
|
+
onCleanup(() => hook.componentUnmount?.(componentId));
|
|
3198
|
+
}
|
|
2994
3199
|
return createElementWithContext(rendered, namespace);
|
|
2995
3200
|
} catch (err) {
|
|
2996
3201
|
if (handleSuspend(err)) {
|
|
@@ -3022,15 +3227,48 @@ function createElementWithContext(node, namespace) {
|
|
|
3022
3227
|
function template(html, isImportNode, isSVG, isMathML) {
|
|
3023
3228
|
let node = null;
|
|
3024
3229
|
const create = () => {
|
|
3025
|
-
const t =
|
|
3026
|
-
t.innerHTML = html;
|
|
3230
|
+
const t = document.createElement("template");
|
|
3027
3231
|
if (isSVG) {
|
|
3028
|
-
|
|
3232
|
+
t.innerHTML = `<svg>${html}</svg>`;
|
|
3233
|
+
const wrapper = t.content.firstChild;
|
|
3234
|
+
if (isDev7 && wrapper.childNodes.length !== 1) {
|
|
3235
|
+
console.warn(
|
|
3236
|
+
`[fict] template() received multi-root SVG content (${wrapper.childNodes.length} nodes). Returning a DocumentFragment. This may indicate a compiler bug or invalid JSX structure.`
|
|
3237
|
+
);
|
|
3238
|
+
}
|
|
3239
|
+
if (wrapper.childNodes.length === 1) {
|
|
3240
|
+
return wrapper.firstChild;
|
|
3241
|
+
}
|
|
3242
|
+
const fragment = document.createDocumentFragment();
|
|
3243
|
+
fragment.append(...Array.from(wrapper.childNodes));
|
|
3244
|
+
return fragment;
|
|
3029
3245
|
}
|
|
3030
3246
|
if (isMathML) {
|
|
3031
|
-
|
|
3247
|
+
t.innerHTML = `<math>${html}</math>`;
|
|
3248
|
+
const wrapper = t.content.firstChild;
|
|
3249
|
+
if (isDev7 && wrapper.childNodes.length !== 1) {
|
|
3250
|
+
console.warn(
|
|
3251
|
+
`[fict] template() received multi-root MathML content (${wrapper.childNodes.length} nodes). Returning a DocumentFragment. This may indicate a compiler bug or invalid JSX structure.`
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
if (wrapper.childNodes.length === 1) {
|
|
3255
|
+
return wrapper.firstChild;
|
|
3256
|
+
}
|
|
3257
|
+
const fragment = document.createDocumentFragment();
|
|
3258
|
+
fragment.append(...Array.from(wrapper.childNodes));
|
|
3259
|
+
return fragment;
|
|
3260
|
+
}
|
|
3261
|
+
t.innerHTML = html;
|
|
3262
|
+
const content = t.content;
|
|
3263
|
+
if (isDev7 && content.childNodes.length !== 1) {
|
|
3264
|
+
console.warn(
|
|
3265
|
+
`[fict] template() received multi-root content (${content.childNodes.length} nodes). Returning a DocumentFragment. This may indicate a compiler bug or invalid JSX structure.`
|
|
3266
|
+
);
|
|
3267
|
+
}
|
|
3268
|
+
if (content.childNodes.length === 1) {
|
|
3269
|
+
return content.firstChild;
|
|
3032
3270
|
}
|
|
3033
|
-
return
|
|
3271
|
+
return content;
|
|
3034
3272
|
};
|
|
3035
3273
|
const fn = isImportNode ? () => untrack2(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true);
|
|
3036
3274
|
fn.cloneNode = fn;
|
|
@@ -3334,11 +3572,21 @@ export {
|
|
|
3334
3572
|
registerErrorHandler,
|
|
3335
3573
|
registerSuspenseHandler,
|
|
3336
3574
|
handleError,
|
|
3575
|
+
createMemo,
|
|
3576
|
+
__fictUseContext,
|
|
3577
|
+
__fictPushContext,
|
|
3578
|
+
__fictPopContext,
|
|
3579
|
+
__fictResetContext,
|
|
3580
|
+
__fictUseSignal,
|
|
3581
|
+
__fictUseMemo,
|
|
3582
|
+
__fictUseEffect,
|
|
3583
|
+
__fictRender,
|
|
3337
3584
|
flush,
|
|
3338
3585
|
signal,
|
|
3339
3586
|
effectScope,
|
|
3340
3587
|
batch,
|
|
3341
3588
|
setActiveSub,
|
|
3589
|
+
__resetReactiveState,
|
|
3342
3590
|
untrack,
|
|
3343
3591
|
createSelector,
|
|
3344
3592
|
createEffect,
|
|
@@ -3377,22 +3625,14 @@ export {
|
|
|
3377
3625
|
createConditional,
|
|
3378
3626
|
createShow,
|
|
3379
3627
|
createPortal,
|
|
3380
|
-
createMemo,
|
|
3381
|
-
__fictUseContext,
|
|
3382
|
-
__fictPushContext,
|
|
3383
|
-
__fictPopContext,
|
|
3384
|
-
__fictResetContext,
|
|
3385
|
-
__fictUseSignal,
|
|
3386
|
-
__fictUseMemo,
|
|
3387
|
-
__fictUseEffect,
|
|
3388
|
-
__fictRender,
|
|
3389
3628
|
__fictProp,
|
|
3390
3629
|
createPropsProxy,
|
|
3391
3630
|
__fictPropsRest,
|
|
3392
3631
|
mergeProps,
|
|
3632
|
+
keyed,
|
|
3393
3633
|
prop,
|
|
3394
3634
|
render,
|
|
3395
3635
|
createElement,
|
|
3396
3636
|
template
|
|
3397
3637
|
};
|
|
3398
|
-
//# sourceMappingURL=chunk-
|
|
3638
|
+
//# sourceMappingURL=chunk-SO6X7G5S.js.map
|