sibujs 2.0.0 → 2.2.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/browser.cjs +369 -276
- package/dist/browser.js +4 -4
- package/dist/build.cjs +411 -300
- package/dist/build.js +10 -10
- package/dist/cdn.global.js +8 -8
- package/dist/{chunk-JA6667UN.js → chunk-2JQUV4Y3.js} +4 -4
- package/dist/{chunk-3NSGB5JN.js → chunk-2KM2724A.js} +2 -2
- package/dist/{chunk-52YJLLRO.js → chunk-4YTVESDX.js} +1 -1
- package/dist/chunk-5WD7BYTZ.js +152 -0
- package/dist/{chunk-CC65Y57T.js → chunk-6QZO7MMG.js} +48 -16
- package/dist/{chunk-54EDRCEF.js → chunk-DF3GTP4Q.js} +7 -2
- package/dist/{chunk-ND2664SF.js → chunk-J63GPPCJ.js} +13 -9
- package/dist/{chunk-O2MNQFLP.js → chunk-KH4OE6WY.js} +5 -5
- package/dist/{chunk-3LR7GLWQ.js → chunk-KZA7ANXP.js} +3 -3
- package/dist/chunk-L4DAT4WU.js +400 -0
- package/dist/{chunk-WOMYAHHI.js → chunk-L52H775O.js} +4 -4
- package/dist/{chunk-ITX6OO3F.js → chunk-NEWH4O5U.js} +1 -1
- package/dist/{chunk-7JDB7I65.js → chunk-RJIRT46U.js} +4 -4
- package/dist/{chunk-KLRMB5ZS.js → chunk-STFTTMO2.js} +2 -2
- package/dist/{chunk-DFPFITST.js → chunk-UKMXT5T6.js} +1 -1
- package/dist/{chunk-SAHNHTFC.js → chunk-V65KTDZW.js} +3 -3
- package/dist/{chunk-R73P76YZ.js → chunk-VSNLICTS.js} +1 -1
- package/dist/{chunk-MIUAXB7K.js → chunk-XDKP4T7G.js} +2 -2
- package/dist/{chunk-JXMMDLBY.js → chunk-XVYB3J6C.js} +27 -29
- package/dist/{chunk-GTBNNBJ6.js → chunk-YMOIAHWA.js} +1 -1
- package/dist/data.cjs +382 -274
- package/dist/data.js +6 -6
- package/dist/devtools.cjs +398 -284
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +4 -4
- package/dist/ecosystem.cjs +382 -274
- package/dist/ecosystem.js +7 -7
- package/dist/extras.cjs +421 -299
- package/dist/extras.d.cts +1 -1
- package/dist/extras.d.ts +1 -1
- package/dist/extras.js +19 -19
- package/dist/index.cjs +413 -300
- package/dist/index.d.cts +16 -11
- package/dist/index.d.ts +16 -11
- package/dist/index.js +14 -10
- package/dist/{introspect-cY2pg9pW.d.ts → introspect-BZWKvQUZ.d.ts} +2 -1
- package/dist/{introspect-BWNjNw64.d.cts → introspect-DsJlDD2T.d.cts} +2 -1
- package/dist/motion.cjs +189 -149
- package/dist/motion.js +3 -3
- package/dist/patterns.cjs +382 -274
- package/dist/patterns.js +5 -5
- package/dist/performance.cjs +360 -260
- package/dist/performance.js +4 -4
- package/dist/plugins.cjs +376 -257
- package/dist/plugins.js +6 -6
- package/dist/ssr.cjs +383 -271
- package/dist/ssr.js +7 -7
- package/dist/testing.cjs +168 -109
- package/dist/testing.js +2 -2
- package/dist/ui.cjs +373 -258
- package/dist/ui.js +6 -6
- package/dist/widgets.cjs +382 -274
- package/dist/widgets.js +6 -6
- package/package.json +1 -1
- package/dist/chunk-HB24TBAF.js +0 -121
- package/dist/chunk-VLPPXTYG.js +0 -332
package/dist/extras.cjs
CHANGED
|
@@ -145,7 +145,7 @@ __export(extras_exports, {
|
|
|
145
145
|
getPerformanceReport: () => getPerformanceReport,
|
|
146
146
|
getQueryData: () => getQueryData,
|
|
147
147
|
getSignalName: () => getSignalName,
|
|
148
|
-
getSubscriberCount: () =>
|
|
148
|
+
getSubscriberCount: () => getSubscriberCount2,
|
|
149
149
|
globalStore: () => globalStore,
|
|
150
150
|
healthCheck: () => healthCheck,
|
|
151
151
|
hmrState: () => hmrState,
|
|
@@ -332,11 +332,88 @@ function devWarn(message) {
|
|
|
332
332
|
|
|
333
333
|
// src/reactivity/track.ts
|
|
334
334
|
var _isDev2 = isDev();
|
|
335
|
-
var
|
|
336
|
-
var
|
|
337
|
-
|
|
335
|
+
var POOL_MAX = 4096;
|
|
336
|
+
var nodePool = [];
|
|
337
|
+
function createNode() {
|
|
338
|
+
return {
|
|
339
|
+
sig: null,
|
|
340
|
+
sub: null,
|
|
341
|
+
epoch: 0,
|
|
342
|
+
sigPrev: null,
|
|
343
|
+
sigNext: null,
|
|
344
|
+
subPrev: null,
|
|
345
|
+
subNext: null,
|
|
346
|
+
prevActive: null
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
function allocNode(sig, sub2, epoch) {
|
|
350
|
+
const n = nodePool.pop();
|
|
351
|
+
if (n) {
|
|
352
|
+
n.sig = sig;
|
|
353
|
+
n.sub = sub2;
|
|
354
|
+
n.epoch = epoch;
|
|
355
|
+
return n;
|
|
356
|
+
}
|
|
357
|
+
const fresh = createNode();
|
|
358
|
+
fresh.sig = sig;
|
|
359
|
+
fresh.sub = sub2;
|
|
360
|
+
fresh.epoch = epoch;
|
|
361
|
+
return fresh;
|
|
362
|
+
}
|
|
363
|
+
function freeNode(node) {
|
|
364
|
+
node.sig = null;
|
|
365
|
+
node.sub = null;
|
|
366
|
+
node.sigPrev = null;
|
|
367
|
+
node.sigNext = null;
|
|
368
|
+
node.subPrev = null;
|
|
369
|
+
node.subNext = null;
|
|
370
|
+
node.prevActive = null;
|
|
371
|
+
if (nodePool.length < POOL_MAX) nodePool.push(node);
|
|
372
|
+
}
|
|
373
|
+
function linkSignal(sig, node) {
|
|
374
|
+
const oldHead = sig.subsHead ?? null;
|
|
375
|
+
node.sigPrev = null;
|
|
376
|
+
node.sigNext = oldHead;
|
|
377
|
+
if (oldHead) oldHead.sigPrev = node;
|
|
378
|
+
else sig.subsTail = node;
|
|
379
|
+
sig.subsHead = node;
|
|
380
|
+
sig.__sc = (sig.__sc ?? 0) + 1;
|
|
381
|
+
}
|
|
382
|
+
function unlinkSignal(node) {
|
|
383
|
+
const sig = node.sig;
|
|
384
|
+
if (!sig) return;
|
|
385
|
+
const prev = node.sigPrev;
|
|
386
|
+
const next = node.sigNext;
|
|
387
|
+
if (prev) prev.sigNext = next;
|
|
388
|
+
else sig.subsHead = next;
|
|
389
|
+
if (next) next.sigPrev = prev;
|
|
390
|
+
else sig.subsTail = prev;
|
|
391
|
+
sig.__sc = (sig.__sc ?? 1) - 1;
|
|
392
|
+
if (sig.__activeNode === node) sig.__activeNode = node.prevActive;
|
|
393
|
+
if (sig.__sc === 0) {
|
|
394
|
+
sig.subsHead = null;
|
|
395
|
+
sig.subsTail = null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function linkSub(sub2, node) {
|
|
399
|
+
const oldTail = sub2.depsTail ?? null;
|
|
400
|
+
node.subPrev = oldTail;
|
|
401
|
+
node.subNext = null;
|
|
402
|
+
if (oldTail) oldTail.subNext = node;
|
|
403
|
+
else sub2.depsHead = node;
|
|
404
|
+
sub2.depsTail = node;
|
|
405
|
+
}
|
|
406
|
+
function unlinkSub(node) {
|
|
407
|
+
const sub2 = node.sub;
|
|
408
|
+
if (!sub2) return;
|
|
409
|
+
const prev = node.subPrev;
|
|
410
|
+
const next = node.subNext;
|
|
411
|
+
if (prev) prev.subNext = next;
|
|
412
|
+
else sub2.depsHead = next;
|
|
413
|
+
if (next) next.subPrev = prev;
|
|
414
|
+
else sub2.depsTail = prev;
|
|
415
|
+
}
|
|
338
416
|
var currentSubscriber = null;
|
|
339
|
-
var SUBS = "__s";
|
|
340
417
|
var notifyDepth = 0;
|
|
341
418
|
var pendingQueue = [];
|
|
342
419
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
@@ -349,92 +426,136 @@ function safeInvoke(sub2) {
|
|
|
349
426
|
}
|
|
350
427
|
}
|
|
351
428
|
var trackingSuspended = false;
|
|
429
|
+
var subscriberEpochCounter = 0;
|
|
352
430
|
function retrack(effectFn, subscriber) {
|
|
353
431
|
const prev = currentSubscriber;
|
|
354
432
|
currentSubscriber = subscriber;
|
|
433
|
+
const sub2 = subscriber;
|
|
434
|
+
const epoch = ++subscriberEpochCounter;
|
|
435
|
+
sub2._epoch = epoch;
|
|
436
|
+
sub2._structDirty = false;
|
|
437
|
+
for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
|
|
438
|
+
const sig = n.sig;
|
|
439
|
+
n.prevActive = sig.__activeNode ?? null;
|
|
440
|
+
sig.__activeNode = n;
|
|
441
|
+
}
|
|
355
442
|
try {
|
|
356
443
|
effectFn();
|
|
357
444
|
} finally {
|
|
358
445
|
currentSubscriber = prev;
|
|
446
|
+
let node = sub2.depsHead ?? null;
|
|
447
|
+
while (node !== null) {
|
|
448
|
+
const next = node.subNext;
|
|
449
|
+
const sig = node.sig;
|
|
450
|
+
sig.__activeNode = node.prevActive;
|
|
451
|
+
node.prevActive = null;
|
|
452
|
+
if (node.epoch !== epoch) {
|
|
453
|
+
unlinkSub(node);
|
|
454
|
+
unlinkSignal(node);
|
|
455
|
+
freeNode(node);
|
|
456
|
+
}
|
|
457
|
+
node = next;
|
|
458
|
+
}
|
|
359
459
|
}
|
|
360
460
|
}
|
|
361
461
|
function track(effectFn, subscriber) {
|
|
362
462
|
if (!subscriber) subscriber = effectFn;
|
|
363
463
|
cleanup(subscriber);
|
|
364
|
-
|
|
365
|
-
if (stackTop >= stackCapacity) {
|
|
366
|
-
stackCapacity *= 2;
|
|
367
|
-
subscriberStack.length = stackCapacity;
|
|
368
|
-
}
|
|
369
|
-
subscriberStack[stackTop] = subscriber;
|
|
464
|
+
const prev = currentSubscriber;
|
|
370
465
|
currentSubscriber = subscriber;
|
|
371
466
|
try {
|
|
372
467
|
effectFn();
|
|
373
468
|
} finally {
|
|
374
|
-
|
|
375
|
-
|
|
469
|
+
currentSubscriber = prev;
|
|
470
|
+
const sub3 = subscriber;
|
|
471
|
+
for (let n = sub3.depsHead ?? null; n !== null; n = n.subNext) {
|
|
472
|
+
const sig = n.sig;
|
|
473
|
+
sig.__activeNode = n.prevActive;
|
|
474
|
+
n.prevActive = null;
|
|
475
|
+
}
|
|
376
476
|
}
|
|
377
|
-
|
|
477
|
+
const sub2 = subscriber;
|
|
478
|
+
return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
|
|
378
479
|
}
|
|
379
480
|
function recordDependency(signal2) {
|
|
380
481
|
if (!currentSubscriber) return;
|
|
381
482
|
const sub2 = currentSubscriber;
|
|
382
|
-
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const set = /* @__PURE__ */ new Set();
|
|
389
|
-
set.add(sub2._dep);
|
|
390
|
-
set.add(signal2);
|
|
391
|
-
sub2._deps = set;
|
|
392
|
-
sub2._dep = void 0;
|
|
393
|
-
} else {
|
|
394
|
-
sub2._dep = signal2;
|
|
483
|
+
const sig = signal2;
|
|
484
|
+
const epoch = sub2._epoch ?? 0;
|
|
485
|
+
const active = sig.__activeNode ?? null;
|
|
486
|
+
if (active !== null && active.sub === sub2) {
|
|
487
|
+
active.epoch = epoch;
|
|
488
|
+
return;
|
|
395
489
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
490
|
+
const node = allocNode(signal2, sub2, epoch);
|
|
491
|
+
node.prevActive = active;
|
|
492
|
+
sig.__activeNode = node;
|
|
493
|
+
linkSub(sub2, node);
|
|
494
|
+
linkSignal(sig, node);
|
|
495
|
+
sub2._structDirty = true;
|
|
496
|
+
}
|
|
497
|
+
function cleanup(subscriber) {
|
|
498
|
+
const sub2 = subscriber;
|
|
499
|
+
let node = sub2.depsHead ?? null;
|
|
500
|
+
sub2.depsHead = null;
|
|
501
|
+
sub2.depsTail = null;
|
|
502
|
+
while (node) {
|
|
503
|
+
const next = node.subNext;
|
|
504
|
+
unlinkSignal(node);
|
|
505
|
+
freeNode(node);
|
|
506
|
+
node = next;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
var maxSubscriberRepeats = 50;
|
|
510
|
+
var maxDrainIterations = 1e6;
|
|
511
|
+
var drainEpoch = 0;
|
|
512
|
+
function tickRepeat(sub2) {
|
|
513
|
+
const s2 = sub2;
|
|
514
|
+
if (s2._runEpoch !== drainEpoch) {
|
|
515
|
+
s2._runEpoch = drainEpoch;
|
|
516
|
+
s2._runs = 1;
|
|
517
|
+
return false;
|
|
400
518
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
519
|
+
s2._runs = (s2._runs ?? 0) + 1;
|
|
520
|
+
return s2._runs > maxSubscriberRepeats;
|
|
521
|
+
}
|
|
522
|
+
function cycleError(sub2) {
|
|
523
|
+
if (typeof console !== "undefined") {
|
|
524
|
+
const name = sub2.__name ?? "<unnamed>";
|
|
525
|
+
console.error(
|
|
526
|
+
`[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
|
|
527
|
+
);
|
|
406
528
|
}
|
|
407
529
|
}
|
|
408
|
-
function
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
530
|
+
function absoluteDrainError() {
|
|
531
|
+
if (typeof console !== "undefined") {
|
|
532
|
+
console.error(
|
|
533
|
+
`[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function drainQueue() {
|
|
538
|
+
let i2 = 0;
|
|
539
|
+
while (i2 < pendingQueue.length) {
|
|
540
|
+
if (i2 >= maxDrainIterations) {
|
|
541
|
+
absoluteDrainError();
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
const sub2 = pendingQueue[i2++];
|
|
545
|
+
if (tickRepeat(sub2)) {
|
|
546
|
+
cycleError(sub2);
|
|
547
|
+
break;
|
|
417
548
|
}
|
|
549
|
+
pendingSet.delete(sub2);
|
|
550
|
+
safeInvoke(sub2);
|
|
418
551
|
}
|
|
419
552
|
}
|
|
420
|
-
var maxDrainIterations = 1e5;
|
|
421
553
|
function drainNotificationQueue() {
|
|
422
554
|
if (notifyDepth > 0) return;
|
|
423
555
|
notifyDepth++;
|
|
556
|
+
drainEpoch++;
|
|
424
557
|
try {
|
|
425
|
-
|
|
426
|
-
while (i2 < pendingQueue.length) {
|
|
427
|
-
if (i2 >= maxDrainIterations) {
|
|
428
|
-
if (typeof console !== "undefined") {
|
|
429
|
-
console.error(
|
|
430
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
435
|
-
safeInvoke(pendingQueue[i2]);
|
|
436
|
-
i2++;
|
|
437
|
-
}
|
|
558
|
+
drainQueue();
|
|
438
559
|
} finally {
|
|
439
560
|
notifyDepth--;
|
|
440
561
|
if (notifyDepth === 0) {
|
|
@@ -452,131 +573,82 @@ function propagateDirty(sub2) {
|
|
|
452
573
|
stack.push(rootSig);
|
|
453
574
|
while (stack.length > baseLen) {
|
|
454
575
|
const sig = stack.pop();
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
if (
|
|
460
|
-
nSig
|
|
461
|
-
|
|
576
|
+
let node = sig.subsHead ?? null;
|
|
577
|
+
while (node) {
|
|
578
|
+
const s2 = node.sub;
|
|
579
|
+
if (s2) {
|
|
580
|
+
if (s2._c) {
|
|
581
|
+
const nSig = s2._sig;
|
|
582
|
+
if (nSig) {
|
|
583
|
+
if (!nSig._d) {
|
|
584
|
+
nSig._d = true;
|
|
585
|
+
stack.push(nSig);
|
|
586
|
+
}
|
|
587
|
+
} else {
|
|
588
|
+
s2();
|
|
589
|
+
}
|
|
590
|
+
} else if (!pendingSet.has(s2)) {
|
|
591
|
+
pendingSet.add(s2);
|
|
592
|
+
pendingQueue.push(s2);
|
|
462
593
|
}
|
|
463
|
-
} else if (!pendingSet.has(first)) {
|
|
464
|
-
pendingSet.add(first);
|
|
465
|
-
pendingQueue.push(first);
|
|
466
594
|
}
|
|
467
|
-
|
|
595
|
+
node = node.sigNext;
|
|
468
596
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function queueSignalNotification(signal2) {
|
|
600
|
+
const sig = signal2;
|
|
601
|
+
let node = sig.subsHead ?? null;
|
|
602
|
+
while (node) {
|
|
603
|
+
const s2 = node.sub;
|
|
604
|
+
if (s2) {
|
|
472
605
|
if (s2._c) {
|
|
473
|
-
|
|
474
|
-
if (nSig && !nSig._d) {
|
|
475
|
-
nSig._d = true;
|
|
476
|
-
stack.push(nSig);
|
|
477
|
-
} else if (!nSig) {
|
|
478
|
-
s2();
|
|
479
|
-
}
|
|
606
|
+
propagateDirty(s2);
|
|
480
607
|
} else if (!pendingSet.has(s2)) {
|
|
481
608
|
pendingSet.add(s2);
|
|
482
609
|
pendingQueue.push(s2);
|
|
483
610
|
}
|
|
484
611
|
}
|
|
612
|
+
node = node.sigNext;
|
|
485
613
|
}
|
|
486
614
|
}
|
|
487
615
|
function notifySubscribers(signal2) {
|
|
488
|
-
const
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
if (first._c) {
|
|
492
|
-
propagateDirty(first);
|
|
493
|
-
} else if (!pendingSet.has(first)) {
|
|
494
|
-
pendingSet.add(first);
|
|
495
|
-
pendingQueue.push(first);
|
|
496
|
-
}
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
notifyDepth++;
|
|
500
|
-
try {
|
|
501
|
-
if (first._c) {
|
|
502
|
-
propagateDirty(first);
|
|
503
|
-
} else {
|
|
504
|
-
safeInvoke(first);
|
|
505
|
-
}
|
|
506
|
-
let i2 = 0;
|
|
507
|
-
while (i2 < pendingQueue.length) {
|
|
508
|
-
if (i2 >= maxDrainIterations) {
|
|
509
|
-
if (typeof console !== "undefined") {
|
|
510
|
-
console.error(
|
|
511
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
break;
|
|
515
|
-
}
|
|
516
|
-
safeInvoke(pendingQueue[i2]);
|
|
517
|
-
i2++;
|
|
518
|
-
}
|
|
519
|
-
} finally {
|
|
520
|
-
notifyDepth--;
|
|
521
|
-
if (notifyDepth === 0) {
|
|
522
|
-
pendingQueue.length = 0;
|
|
523
|
-
pendingSet.clear();
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
const subs = signal2[SUBS];
|
|
529
|
-
if (!subs || subs.size === 0) return;
|
|
616
|
+
const sig = signal2;
|
|
617
|
+
const head2 = sig.subsHead;
|
|
618
|
+
if (!head2) return;
|
|
530
619
|
if (notifyDepth > 0) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
620
|
+
let node = head2;
|
|
621
|
+
while (node) {
|
|
622
|
+
const s2 = node.sub;
|
|
623
|
+
if (s2) {
|
|
624
|
+
if (s2._c) {
|
|
625
|
+
propagateDirty(s2);
|
|
626
|
+
} else if (!pendingSet.has(s2)) {
|
|
627
|
+
pendingSet.add(s2);
|
|
628
|
+
pendingQueue.push(s2);
|
|
629
|
+
}
|
|
537
630
|
}
|
|
631
|
+
node = node.sigNext;
|
|
538
632
|
}
|
|
539
633
|
return;
|
|
540
634
|
}
|
|
541
635
|
notifyDepth++;
|
|
636
|
+
drainEpoch++;
|
|
542
637
|
try {
|
|
543
|
-
let
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
if (
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
553
|
-
} else {
|
|
554
|
-
for (let i3 = 0; i3 < directCount; i3++) {
|
|
555
|
-
if (pendingQueue[i3]._c) {
|
|
556
|
-
propagateDirty(pendingQueue[i3]);
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
for (let i3 = 0; i3 < directCount; i3++) {
|
|
560
|
-
const sub2 = pendingQueue[i3];
|
|
561
|
-
if (!sub2._c && !pendingSet.has(sub2)) {
|
|
562
|
-
pendingSet.add(sub2);
|
|
563
|
-
safeInvoke(sub2);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
let i2 = directCount;
|
|
568
|
-
while (i2 < pendingQueue.length) {
|
|
569
|
-
if (i2 - directCount >= maxDrainIterations) {
|
|
570
|
-
if (typeof console !== "undefined") {
|
|
571
|
-
console.error(
|
|
572
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
573
|
-
);
|
|
638
|
+
let node = head2;
|
|
639
|
+
while (node) {
|
|
640
|
+
const s2 = node.sub;
|
|
641
|
+
if (s2) {
|
|
642
|
+
if (s2._c) {
|
|
643
|
+
propagateDirty(s2);
|
|
644
|
+
} else if (!pendingSet.has(s2)) {
|
|
645
|
+
pendingSet.add(s2);
|
|
646
|
+
pendingQueue.push(s2);
|
|
574
647
|
}
|
|
575
|
-
break;
|
|
576
648
|
}
|
|
577
|
-
|
|
578
|
-
i2++;
|
|
649
|
+
node = node.sigNext;
|
|
579
650
|
}
|
|
651
|
+
drainQueue();
|
|
580
652
|
} finally {
|
|
581
653
|
notifyDepth--;
|
|
582
654
|
if (notifyDepth === 0) {
|
|
@@ -585,36 +657,26 @@ function notifySubscribers(signal2) {
|
|
|
585
657
|
}
|
|
586
658
|
}
|
|
587
659
|
}
|
|
588
|
-
function
|
|
660
|
+
function getSubscriberCount(signal2) {
|
|
661
|
+
return signal2.__sc ?? 0;
|
|
662
|
+
}
|
|
663
|
+
function getSubscriberDeps(subscriber) {
|
|
589
664
|
const sub2 = subscriber;
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
if (
|
|
594
|
-
|
|
595
|
-
if (singleDep.__f === subscriber) {
|
|
596
|
-
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
597
|
-
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
598
|
-
singleDep.__f = subs.values().next().value;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
sub2._dep = void 0;
|
|
602
|
-
return;
|
|
665
|
+
const out = [];
|
|
666
|
+
let node = sub2.depsHead ?? null;
|
|
667
|
+
while (node) {
|
|
668
|
+
if (node.sig) out.push(node.sig);
|
|
669
|
+
node = node.subNext;
|
|
603
670
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
613
|
-
signal2.__f = subs.values().next().value;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
671
|
+
return out;
|
|
672
|
+
}
|
|
673
|
+
function forEachSubscriber(signal2, visit) {
|
|
674
|
+
let node = signal2.subsHead ?? null;
|
|
675
|
+
while (node) {
|
|
676
|
+
const s2 = node.sub;
|
|
677
|
+
if (s2) visit(s2);
|
|
678
|
+
node = node.sigNext;
|
|
616
679
|
}
|
|
617
|
-
deps.clear();
|
|
618
680
|
}
|
|
619
681
|
|
|
620
682
|
// src/core/signals/derived.ts
|
|
@@ -625,6 +687,7 @@ function derived(getter, options) {
|
|
|
625
687
|
const cs = {};
|
|
626
688
|
cs._d = false;
|
|
627
689
|
cs._g = getter;
|
|
690
|
+
cs.__v = 0;
|
|
628
691
|
const markDirty = () => {
|
|
629
692
|
if (cs._d) return;
|
|
630
693
|
cs._d = true;
|
|
@@ -654,11 +717,14 @@ function derived(getter, options) {
|
|
|
654
717
|
evaluating = true;
|
|
655
718
|
let threw = true;
|
|
656
719
|
try {
|
|
720
|
+
const prev = cs._v;
|
|
657
721
|
retrack(() => {
|
|
658
|
-
|
|
722
|
+
const next = getter();
|
|
723
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
659
724
|
cs._d = false;
|
|
660
725
|
threw = false;
|
|
661
726
|
}, markDirty);
|
|
727
|
+
if (!Object.is(prev, cs._v)) cs.__v++;
|
|
662
728
|
} finally {
|
|
663
729
|
evaluating = false;
|
|
664
730
|
if (threw) cs._d = true;
|
|
@@ -678,6 +744,7 @@ function derived(getter, options) {
|
|
|
678
744
|
cs._d = false;
|
|
679
745
|
threw = false;
|
|
680
746
|
}, markDirty);
|
|
747
|
+
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
681
748
|
} finally {
|
|
682
749
|
evaluating = false;
|
|
683
750
|
if (threw) cs._d = true;
|
|
@@ -724,92 +791,122 @@ function isSSR() {
|
|
|
724
791
|
|
|
725
792
|
// src/core/signals/effect.ts
|
|
726
793
|
var _g = globalThis;
|
|
794
|
+
var MAX_RERUNS = 100;
|
|
795
|
+
function flushUserCleanups(ctx) {
|
|
796
|
+
const list = ctx.userCleanups;
|
|
797
|
+
if (list.length === 0) return;
|
|
798
|
+
ctx.userCleanups = [];
|
|
799
|
+
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
800
|
+
try {
|
|
801
|
+
list[i2]();
|
|
802
|
+
} catch (err) {
|
|
803
|
+
if (typeof console !== "undefined") console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
function drainReruns(ctx) {
|
|
808
|
+
let reruns = 1;
|
|
809
|
+
do {
|
|
810
|
+
ctx.rerunPending = false;
|
|
811
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
812
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
813
|
+
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
814
|
+
if (ctx.rerunPending) {
|
|
815
|
+
ctx.rerunPending = false;
|
|
816
|
+
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
817
|
+
console.error(
|
|
818
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
function disposeEffect(ctx) {
|
|
824
|
+
if (ctx.disposed) return;
|
|
825
|
+
ctx.disposed = true;
|
|
826
|
+
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
827
|
+
if (h) {
|
|
828
|
+
try {
|
|
829
|
+
h.emit("effect:destroy", { effectFn: ctx.fn });
|
|
830
|
+
} catch {
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
try {
|
|
834
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
835
|
+
} catch (err) {
|
|
836
|
+
if (typeof console !== "undefined") {
|
|
837
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
try {
|
|
841
|
+
cleanup(ctx.subscriber);
|
|
842
|
+
} catch (err) {
|
|
843
|
+
if (typeof console !== "undefined") {
|
|
844
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
727
848
|
function effect(effectFn, options) {
|
|
728
849
|
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
729
850
|
if (isSSR()) return () => {
|
|
730
851
|
};
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
userCleanups
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
const invokeBody = () => effectFn(onCleanup);
|
|
751
|
-
const wrappedFn = onError ? () => {
|
|
852
|
+
const ctx = {
|
|
853
|
+
fn: effectFn,
|
|
854
|
+
onError: options?.onError,
|
|
855
|
+
userCleanups: [],
|
|
856
|
+
running: false,
|
|
857
|
+
rerunPending: false,
|
|
858
|
+
disposed: false,
|
|
859
|
+
onCleanup: null,
|
|
860
|
+
subscriber: null,
|
|
861
|
+
bodyFn: null
|
|
862
|
+
};
|
|
863
|
+
ctx.onCleanup = (fn) => {
|
|
864
|
+
ctx.userCleanups.push(fn);
|
|
865
|
+
};
|
|
866
|
+
const onErrorCaptured = ctx.onError;
|
|
867
|
+
ctx.bodyFn = onErrorCaptured ? () => {
|
|
752
868
|
try {
|
|
753
|
-
|
|
869
|
+
ctx.fn(ctx.onCleanup);
|
|
754
870
|
} catch (err) {
|
|
755
|
-
|
|
871
|
+
onErrorCaptured(err);
|
|
756
872
|
}
|
|
757
|
-
} :
|
|
758
|
-
|
|
873
|
+
} : () => {
|
|
874
|
+
ctx.fn(ctx.onCleanup);
|
|
759
875
|
};
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
764
|
-
console.warn(
|
|
765
|
-
"[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
|
|
766
|
-
);
|
|
767
|
-
}
|
|
876
|
+
const sub2 = (() => {
|
|
877
|
+
if (ctx.running) {
|
|
878
|
+
ctx.rerunPending = true;
|
|
768
879
|
return;
|
|
769
880
|
}
|
|
770
|
-
running = true;
|
|
881
|
+
ctx.running = true;
|
|
771
882
|
try {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
883
|
+
ctx.rerunPending = false;
|
|
884
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
885
|
+
retrack(ctx.bodyFn, sub2);
|
|
886
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
775
887
|
} finally {
|
|
776
|
-
running = false;
|
|
888
|
+
ctx.running = false;
|
|
889
|
+
ctx.rerunPending = false;
|
|
777
890
|
}
|
|
778
|
-
};
|
|
779
|
-
|
|
891
|
+
});
|
|
892
|
+
sub2.depsHead = null;
|
|
893
|
+
sub2.depsTail = null;
|
|
894
|
+
sub2._epoch = 0;
|
|
895
|
+
sub2._structDirty = false;
|
|
896
|
+
sub2._runEpoch = 0;
|
|
897
|
+
sub2._runs = 0;
|
|
898
|
+
ctx.subscriber = sub2;
|
|
899
|
+
ctx.running = true;
|
|
780
900
|
try {
|
|
781
|
-
|
|
901
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
902
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
782
903
|
} finally {
|
|
783
|
-
running = false;
|
|
904
|
+
ctx.running = false;
|
|
905
|
+
ctx.rerunPending = false;
|
|
784
906
|
}
|
|
785
907
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
786
908
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
787
|
-
|
|
788
|
-
return () => {
|
|
789
|
-
if (disposed) return;
|
|
790
|
-
disposed = true;
|
|
791
|
-
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
792
|
-
if (h) {
|
|
793
|
-
try {
|
|
794
|
-
h.emit("effect:destroy", { effectFn });
|
|
795
|
-
} catch {
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
try {
|
|
799
|
-
runUserCleanups();
|
|
800
|
-
} catch (err) {
|
|
801
|
-
if (typeof console !== "undefined") {
|
|
802
|
-
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
try {
|
|
806
|
-
cleanupHandle();
|
|
807
|
-
} catch (err) {
|
|
808
|
-
if (typeof console !== "undefined") {
|
|
809
|
-
console.warn("[SibuJS effect] dispose threw:", err);
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
};
|
|
909
|
+
return () => disposeEffect(ctx);
|
|
813
910
|
}
|
|
814
911
|
|
|
815
912
|
// src/reactivity/batch.ts
|
|
@@ -846,32 +943,64 @@ function flushBatch() {
|
|
|
846
943
|
var _g2 = globalThis;
|
|
847
944
|
var _isDev3 = isDev();
|
|
848
945
|
function signal(initial, options) {
|
|
849
|
-
const state = {
|
|
946
|
+
const state = {
|
|
947
|
+
value: initial,
|
|
948
|
+
__v: 0,
|
|
949
|
+
__sc: 0,
|
|
950
|
+
subsHead: null,
|
|
951
|
+
subsTail: null,
|
|
952
|
+
__activeNode: null,
|
|
953
|
+
__name: void 0
|
|
954
|
+
};
|
|
850
955
|
const debugName = _isDev3 ? options?.name : void 0;
|
|
851
956
|
const equalsFn = options?.equals;
|
|
852
|
-
if (debugName)
|
|
853
|
-
state.__name = debugName;
|
|
854
|
-
}
|
|
957
|
+
if (debugName) state.__name = debugName;
|
|
855
958
|
function get() {
|
|
856
959
|
recordDependency(state);
|
|
857
960
|
return state.value;
|
|
858
961
|
}
|
|
859
962
|
get.__signal = state;
|
|
860
963
|
if (debugName) get.__name = debugName;
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
const
|
|
964
|
+
let set;
|
|
965
|
+
if (equalsFn) {
|
|
966
|
+
set = (next) => {
|
|
967
|
+
const prev = state.value;
|
|
968
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
969
|
+
if (equalsFn(prev, newValue)) return;
|
|
970
|
+
state.value = newValue;
|
|
971
|
+
state.__v++;
|
|
972
|
+
if (_isDev3) {
|
|
973
|
+
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
974
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
975
|
+
}
|
|
976
|
+
if (!enqueueBatchedSignal(state)) {
|
|
977
|
+
notifySubscribers(state);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
} else if (_isDev3) {
|
|
981
|
+
set = (next) => {
|
|
982
|
+
const prev = state.value;
|
|
983
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
984
|
+
if (Object.is(newValue, prev)) return;
|
|
866
985
|
state.value = newValue;
|
|
986
|
+
state.__v++;
|
|
867
987
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
868
|
-
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
|
|
869
|
-
|
|
988
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
989
|
+
if (!enqueueBatchedSignal(state)) {
|
|
990
|
+
notifySubscribers(state);
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
} else {
|
|
994
|
+
set = (next) => {
|
|
995
|
+
const prev = state.value;
|
|
996
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
997
|
+
if (Object.is(newValue, prev)) return;
|
|
870
998
|
state.value = newValue;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
999
|
+
state.__v++;
|
|
1000
|
+
if (!enqueueBatchedSignal(state)) {
|
|
1001
|
+
notifySubscribers(state);
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
875
1004
|
}
|
|
876
1005
|
if (_isDev3) {
|
|
877
1006
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -9178,13 +9307,14 @@ function initDevTools(config) {
|
|
|
9178
9307
|
} catch {
|
|
9179
9308
|
value = "<error>";
|
|
9180
9309
|
}
|
|
9181
|
-
const subs = node.ref?.__s;
|
|
9182
9310
|
result.push({
|
|
9183
9311
|
id: node.id,
|
|
9184
9312
|
name: node.name,
|
|
9185
9313
|
type: node.type,
|
|
9186
9314
|
value,
|
|
9187
|
-
|
|
9315
|
+
// __sc is the O(1) subscriber count maintained by the reactivity
|
|
9316
|
+
// core (track.ts) on every linked-list splice.
|
|
9317
|
+
subscriberCount: node.ref?.__sc ?? 0
|
|
9188
9318
|
});
|
|
9189
9319
|
}
|
|
9190
9320
|
return result;
|
|
@@ -9325,14 +9455,13 @@ function initDevTools(config) {
|
|
|
9325
9455
|
}
|
|
9326
9456
|
const fullVal = val;
|
|
9327
9457
|
const shortVal = val.length > 80 ? `${val.substring(0, 80)}...` : val;
|
|
9328
|
-
const subs = node.ref?.__s;
|
|
9329
9458
|
sArr.push({
|
|
9330
9459
|
id: node.id,
|
|
9331
9460
|
n: node.name,
|
|
9332
9461
|
tp: node.type,
|
|
9333
9462
|
v: shortVal,
|
|
9334
9463
|
fv: fullVal,
|
|
9335
|
-
sc:
|
|
9464
|
+
sc: node.ref?.__sc ?? 0
|
|
9336
9465
|
});
|
|
9337
9466
|
}
|
|
9338
9467
|
function walkElement(el, depth) {
|
|
@@ -9959,28 +10088,24 @@ function startMeasure(profiler) {
|
|
|
9959
10088
|
}
|
|
9960
10089
|
|
|
9961
10090
|
// src/devtools/introspect.ts
|
|
9962
|
-
var SUBS2 = "__s";
|
|
9963
10091
|
function getSignalName(getter) {
|
|
9964
10092
|
return getter.__name;
|
|
9965
10093
|
}
|
|
9966
|
-
function
|
|
10094
|
+
function getSubscriberCount2(getter) {
|
|
9967
10095
|
const signal2 = getter.__signal;
|
|
9968
10096
|
if (!signal2) return 0;
|
|
9969
|
-
|
|
9970
|
-
return subs ? subs.size : 0;
|
|
10097
|
+
return getSubscriberCount(signal2);
|
|
9971
10098
|
}
|
|
9972
10099
|
function getDependencies(subscriberFn) {
|
|
9973
|
-
|
|
9974
|
-
return deps ? Array.from(deps) : [];
|
|
10100
|
+
return getSubscriberDeps(subscriberFn);
|
|
9975
10101
|
}
|
|
9976
10102
|
function inspectSignal(getter) {
|
|
9977
10103
|
const signal2 = getter.__signal;
|
|
9978
10104
|
if (!signal2) return null;
|
|
9979
|
-
const subs = signal2[SUBS2];
|
|
9980
10105
|
return {
|
|
9981
10106
|
name: getter.__name,
|
|
9982
10107
|
signal: signal2,
|
|
9983
|
-
subscriberCount:
|
|
10108
|
+
subscriberCount: getSubscriberCount(signal2)
|
|
9984
10109
|
};
|
|
9985
10110
|
}
|
|
9986
10111
|
function walkDependencyGraph(getter, maxDepth = 10, visited = /* @__PURE__ */ new WeakSet()) {
|
|
@@ -9989,24 +10114,21 @@ function walkDependencyGraph(getter, maxDepth = 10, visited = /* @__PURE__ */ ne
|
|
|
9989
10114
|
return { name: getSignalName(getter), subscribers: 0, downstream: [] };
|
|
9990
10115
|
}
|
|
9991
10116
|
visited.add(signal2);
|
|
9992
|
-
const subs = signal2[SUBS2];
|
|
9993
10117
|
const downstream = [];
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
|
|
10003
|
-
downstream.push(walkDependencyGraph(fakeGetter, maxDepth - 1, visited));
|
|
10004
|
-
}
|
|
10118
|
+
forEachSubscriber(signal2, (sub2) => {
|
|
10119
|
+
const subSig = sub2._sig;
|
|
10120
|
+
if (subSig && !visited.has(subSig)) {
|
|
10121
|
+
const subName = subSig.__name;
|
|
10122
|
+
const fakeGetter = (() => void 0);
|
|
10123
|
+
const tag = fakeGetter;
|
|
10124
|
+
tag.__signal = subSig;
|
|
10125
|
+
if (subName !== void 0) tag.__name = subName;
|
|
10126
|
+
downstream.push(walkDependencyGraph(fakeGetter, maxDepth - 1, visited));
|
|
10005
10127
|
}
|
|
10006
|
-
}
|
|
10128
|
+
});
|
|
10007
10129
|
return {
|
|
10008
10130
|
name: getSignalName(getter),
|
|
10009
|
-
subscribers:
|
|
10131
|
+
subscribers: getSubscriberCount(signal2),
|
|
10010
10132
|
downstream
|
|
10011
10133
|
};
|
|
10012
10134
|
}
|