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/devtools.cjs
CHANGED
|
@@ -45,7 +45,7 @@ __export(devtools_exports, {
|
|
|
45
45
|
getDependencies: () => getDependencies,
|
|
46
46
|
getPerformanceReport: () => getPerformanceReport,
|
|
47
47
|
getSignalName: () => getSignalName,
|
|
48
|
-
getSubscriberCount: () =>
|
|
48
|
+
getSubscriberCount: () => getSubscriberCount2,
|
|
49
49
|
hmrState: () => hmrState,
|
|
50
50
|
initDevTools: () => initDevTools,
|
|
51
51
|
inspectSignal: () => inspectSignal,
|
|
@@ -184,11 +184,88 @@ function devWarn(message) {
|
|
|
184
184
|
|
|
185
185
|
// src/reactivity/track.ts
|
|
186
186
|
var _isDev2 = isDev();
|
|
187
|
-
var
|
|
188
|
-
var
|
|
189
|
-
|
|
187
|
+
var POOL_MAX = 4096;
|
|
188
|
+
var nodePool = [];
|
|
189
|
+
function createNode() {
|
|
190
|
+
return {
|
|
191
|
+
sig: null,
|
|
192
|
+
sub: null,
|
|
193
|
+
epoch: 0,
|
|
194
|
+
sigPrev: null,
|
|
195
|
+
sigNext: null,
|
|
196
|
+
subPrev: null,
|
|
197
|
+
subNext: null,
|
|
198
|
+
prevActive: null
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function allocNode(sig, sub, epoch) {
|
|
202
|
+
const n = nodePool.pop();
|
|
203
|
+
if (n) {
|
|
204
|
+
n.sig = sig;
|
|
205
|
+
n.sub = sub;
|
|
206
|
+
n.epoch = epoch;
|
|
207
|
+
return n;
|
|
208
|
+
}
|
|
209
|
+
const fresh = createNode();
|
|
210
|
+
fresh.sig = sig;
|
|
211
|
+
fresh.sub = sub;
|
|
212
|
+
fresh.epoch = epoch;
|
|
213
|
+
return fresh;
|
|
214
|
+
}
|
|
215
|
+
function freeNode(node) {
|
|
216
|
+
node.sig = null;
|
|
217
|
+
node.sub = null;
|
|
218
|
+
node.sigPrev = null;
|
|
219
|
+
node.sigNext = null;
|
|
220
|
+
node.subPrev = null;
|
|
221
|
+
node.subNext = null;
|
|
222
|
+
node.prevActive = null;
|
|
223
|
+
if (nodePool.length < POOL_MAX) nodePool.push(node);
|
|
224
|
+
}
|
|
225
|
+
function linkSignal(sig, node) {
|
|
226
|
+
const oldHead = sig.subsHead ?? null;
|
|
227
|
+
node.sigPrev = null;
|
|
228
|
+
node.sigNext = oldHead;
|
|
229
|
+
if (oldHead) oldHead.sigPrev = node;
|
|
230
|
+
else sig.subsTail = node;
|
|
231
|
+
sig.subsHead = node;
|
|
232
|
+
sig.__sc = (sig.__sc ?? 0) + 1;
|
|
233
|
+
}
|
|
234
|
+
function unlinkSignal(node) {
|
|
235
|
+
const sig = node.sig;
|
|
236
|
+
if (!sig) return;
|
|
237
|
+
const prev = node.sigPrev;
|
|
238
|
+
const next = node.sigNext;
|
|
239
|
+
if (prev) prev.sigNext = next;
|
|
240
|
+
else sig.subsHead = next;
|
|
241
|
+
if (next) next.sigPrev = prev;
|
|
242
|
+
else sig.subsTail = prev;
|
|
243
|
+
sig.__sc = (sig.__sc ?? 1) - 1;
|
|
244
|
+
if (sig.__activeNode === node) sig.__activeNode = node.prevActive;
|
|
245
|
+
if (sig.__sc === 0) {
|
|
246
|
+
sig.subsHead = null;
|
|
247
|
+
sig.subsTail = null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function linkSub(sub, node) {
|
|
251
|
+
const oldTail = sub.depsTail ?? null;
|
|
252
|
+
node.subPrev = oldTail;
|
|
253
|
+
node.subNext = null;
|
|
254
|
+
if (oldTail) oldTail.subNext = node;
|
|
255
|
+
else sub.depsHead = node;
|
|
256
|
+
sub.depsTail = node;
|
|
257
|
+
}
|
|
258
|
+
function unlinkSub(node) {
|
|
259
|
+
const sub = node.sub;
|
|
260
|
+
if (!sub) return;
|
|
261
|
+
const prev = node.subPrev;
|
|
262
|
+
const next = node.subNext;
|
|
263
|
+
if (prev) prev.subNext = next;
|
|
264
|
+
else sub.depsHead = next;
|
|
265
|
+
if (next) next.subPrev = prev;
|
|
266
|
+
else sub.depsTail = prev;
|
|
267
|
+
}
|
|
190
268
|
var currentSubscriber = null;
|
|
191
|
-
var SUBS = "__s";
|
|
192
269
|
var notifyDepth = 0;
|
|
193
270
|
var pendingQueue = [];
|
|
194
271
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
@@ -200,54 +277,111 @@ function safeInvoke(sub) {
|
|
|
200
277
|
if (_isDev2) devWarn(`Subscriber threw during notification: ${err instanceof Error ? err.message : String(err)}`);
|
|
201
278
|
}
|
|
202
279
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
++stackTop;
|
|
207
|
-
if (stackTop >= stackCapacity) {
|
|
208
|
-
stackCapacity *= 2;
|
|
209
|
-
subscriberStack.length = stackCapacity;
|
|
210
|
-
}
|
|
211
|
-
subscriberStack[stackTop] = subscriber;
|
|
280
|
+
var subscriberEpochCounter = 0;
|
|
281
|
+
function retrack(effectFn, subscriber) {
|
|
282
|
+
const prev = currentSubscriber;
|
|
212
283
|
currentSubscriber = subscriber;
|
|
284
|
+
const sub = subscriber;
|
|
285
|
+
const epoch = ++subscriberEpochCounter;
|
|
286
|
+
sub._epoch = epoch;
|
|
287
|
+
sub._structDirty = false;
|
|
288
|
+
for (let n = sub.depsHead ?? null; n !== null; n = n.subNext) {
|
|
289
|
+
const sig = n.sig;
|
|
290
|
+
n.prevActive = sig.__activeNode ?? null;
|
|
291
|
+
sig.__activeNode = n;
|
|
292
|
+
}
|
|
213
293
|
try {
|
|
214
294
|
effectFn();
|
|
215
295
|
} finally {
|
|
216
|
-
|
|
217
|
-
|
|
296
|
+
currentSubscriber = prev;
|
|
297
|
+
let node = sub.depsHead ?? null;
|
|
298
|
+
while (node !== null) {
|
|
299
|
+
const next = node.subNext;
|
|
300
|
+
const sig = node.sig;
|
|
301
|
+
sig.__activeNode = node.prevActive;
|
|
302
|
+
node.prevActive = null;
|
|
303
|
+
if (node.epoch !== epoch) {
|
|
304
|
+
unlinkSub(node);
|
|
305
|
+
unlinkSignal(node);
|
|
306
|
+
freeNode(node);
|
|
307
|
+
}
|
|
308
|
+
node = next;
|
|
309
|
+
}
|
|
218
310
|
}
|
|
219
|
-
return () => cleanup(subscriber);
|
|
220
311
|
}
|
|
221
312
|
function recordDependency(signal2) {
|
|
222
313
|
if (!currentSubscriber) return;
|
|
223
314
|
const sub = currentSubscriber;
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const set = /* @__PURE__ */ new Set();
|
|
231
|
-
set.add(sub._dep);
|
|
232
|
-
set.add(signal2);
|
|
233
|
-
sub._deps = set;
|
|
234
|
-
sub._dep = void 0;
|
|
235
|
-
} else {
|
|
236
|
-
sub._dep = signal2;
|
|
237
|
-
}
|
|
238
|
-
let subs = signal2[SUBS];
|
|
239
|
-
if (!subs) {
|
|
240
|
-
subs = /* @__PURE__ */ new Set();
|
|
241
|
-
signal2[SUBS] = subs;
|
|
315
|
+
const sig = signal2;
|
|
316
|
+
const epoch = sub._epoch ?? 0;
|
|
317
|
+
const active = sig.__activeNode ?? null;
|
|
318
|
+
if (active !== null && active.sub === sub) {
|
|
319
|
+
active.epoch = epoch;
|
|
320
|
+
return;
|
|
242
321
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
322
|
+
const node = allocNode(signal2, sub, epoch);
|
|
323
|
+
node.prevActive = active;
|
|
324
|
+
sig.__activeNode = node;
|
|
325
|
+
linkSub(sub, node);
|
|
326
|
+
linkSignal(sig, node);
|
|
327
|
+
sub._structDirty = true;
|
|
328
|
+
}
|
|
329
|
+
function cleanup(subscriber) {
|
|
330
|
+
const sub = subscriber;
|
|
331
|
+
let node = sub.depsHead ?? null;
|
|
332
|
+
sub.depsHead = null;
|
|
333
|
+
sub.depsTail = null;
|
|
334
|
+
while (node) {
|
|
335
|
+
const next = node.subNext;
|
|
336
|
+
unlinkSignal(node);
|
|
337
|
+
freeNode(node);
|
|
338
|
+
node = next;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
var maxSubscriberRepeats = 50;
|
|
342
|
+
var maxDrainIterations = 1e6;
|
|
343
|
+
var drainEpoch = 0;
|
|
344
|
+
function tickRepeat(sub) {
|
|
345
|
+
const s = sub;
|
|
346
|
+
if (s._runEpoch !== drainEpoch) {
|
|
347
|
+
s._runEpoch = drainEpoch;
|
|
348
|
+
s._runs = 1;
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
s._runs = (s._runs ?? 0) + 1;
|
|
352
|
+
return s._runs > maxSubscriberRepeats;
|
|
353
|
+
}
|
|
354
|
+
function cycleError(sub) {
|
|
355
|
+
if (typeof console !== "undefined") {
|
|
356
|
+
const name = sub.__name ?? "<unnamed>";
|
|
357
|
+
console.error(
|
|
358
|
+
`[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function absoluteDrainError() {
|
|
363
|
+
if (typeof console !== "undefined") {
|
|
364
|
+
console.error(
|
|
365
|
+
`[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function drainQueue() {
|
|
370
|
+
let i = 0;
|
|
371
|
+
while (i < pendingQueue.length) {
|
|
372
|
+
if (i >= maxDrainIterations) {
|
|
373
|
+
absoluteDrainError();
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
const sub = pendingQueue[i++];
|
|
377
|
+
if (tickRepeat(sub)) {
|
|
378
|
+
cycleError(sub);
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
pendingSet.delete(sub);
|
|
382
|
+
safeInvoke(sub);
|
|
248
383
|
}
|
|
249
384
|
}
|
|
250
|
-
var maxDrainIterations = 1e5;
|
|
251
385
|
function propagateDirty(sub) {
|
|
252
386
|
sub();
|
|
253
387
|
const rootSig = sub._sig;
|
|
@@ -257,131 +391,66 @@ function propagateDirty(sub) {
|
|
|
257
391
|
stack.push(rootSig);
|
|
258
392
|
while (stack.length > baseLen) {
|
|
259
393
|
const sig = stack.pop();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
if (
|
|
265
|
-
nSig
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (s._c) {
|
|
278
|
-
const nSig = s._sig;
|
|
279
|
-
if (nSig && !nSig._d) {
|
|
280
|
-
nSig._d = true;
|
|
281
|
-
stack.push(nSig);
|
|
282
|
-
} else if (!nSig) {
|
|
283
|
-
s();
|
|
394
|
+
let node = sig.subsHead ?? null;
|
|
395
|
+
while (node) {
|
|
396
|
+
const s = node.sub;
|
|
397
|
+
if (s) {
|
|
398
|
+
if (s._c) {
|
|
399
|
+
const nSig = s._sig;
|
|
400
|
+
if (nSig) {
|
|
401
|
+
if (!nSig._d) {
|
|
402
|
+
nSig._d = true;
|
|
403
|
+
stack.push(nSig);
|
|
404
|
+
}
|
|
405
|
+
} else {
|
|
406
|
+
s();
|
|
407
|
+
}
|
|
408
|
+
} else if (!pendingSet.has(s)) {
|
|
409
|
+
pendingSet.add(s);
|
|
410
|
+
pendingQueue.push(s);
|
|
284
411
|
}
|
|
285
|
-
} else if (!pendingSet.has(s)) {
|
|
286
|
-
pendingSet.add(s);
|
|
287
|
-
pendingQueue.push(s);
|
|
288
412
|
}
|
|
413
|
+
node = node.sigNext;
|
|
289
414
|
}
|
|
290
415
|
}
|
|
291
416
|
}
|
|
292
417
|
function notifySubscribers(signal2) {
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (first._c) {
|
|
297
|
-
propagateDirty(first);
|
|
298
|
-
} else if (!pendingSet.has(first)) {
|
|
299
|
-
pendingSet.add(first);
|
|
300
|
-
pendingQueue.push(first);
|
|
301
|
-
}
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
notifyDepth++;
|
|
305
|
-
try {
|
|
306
|
-
if (first._c) {
|
|
307
|
-
propagateDirty(first);
|
|
308
|
-
} else {
|
|
309
|
-
safeInvoke(first);
|
|
310
|
-
}
|
|
311
|
-
let i = 0;
|
|
312
|
-
while (i < pendingQueue.length) {
|
|
313
|
-
if (i >= maxDrainIterations) {
|
|
314
|
-
if (typeof console !== "undefined") {
|
|
315
|
-
console.error(
|
|
316
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
|
-
safeInvoke(pendingQueue[i]);
|
|
322
|
-
i++;
|
|
323
|
-
}
|
|
324
|
-
} finally {
|
|
325
|
-
notifyDepth--;
|
|
326
|
-
if (notifyDepth === 0) {
|
|
327
|
-
pendingQueue.length = 0;
|
|
328
|
-
pendingSet.clear();
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
const subs = signal2[SUBS];
|
|
334
|
-
if (!subs || subs.size === 0) return;
|
|
418
|
+
const sig = signal2;
|
|
419
|
+
const head = sig.subsHead;
|
|
420
|
+
if (!head) return;
|
|
335
421
|
if (notifyDepth > 0) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
422
|
+
let node = head;
|
|
423
|
+
while (node) {
|
|
424
|
+
const s = node.sub;
|
|
425
|
+
if (s) {
|
|
426
|
+
if (s._c) {
|
|
427
|
+
propagateDirty(s);
|
|
428
|
+
} else if (!pendingSet.has(s)) {
|
|
429
|
+
pendingSet.add(s);
|
|
430
|
+
pendingQueue.push(s);
|
|
431
|
+
}
|
|
342
432
|
}
|
|
433
|
+
node = node.sigNext;
|
|
343
434
|
}
|
|
344
435
|
return;
|
|
345
436
|
}
|
|
346
437
|
notifyDepth++;
|
|
438
|
+
drainEpoch++;
|
|
347
439
|
try {
|
|
348
|
-
let
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if (
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
} else {
|
|
359
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
360
|
-
if (pendingQueue[i2]._c) {
|
|
361
|
-
propagateDirty(pendingQueue[i2]);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
for (let i2 = 0; i2 < directCount; i2++) {
|
|
365
|
-
const sub = pendingQueue[i2];
|
|
366
|
-
if (!sub._c && !pendingSet.has(sub)) {
|
|
367
|
-
pendingSet.add(sub);
|
|
368
|
-
safeInvoke(sub);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
let i = directCount;
|
|
373
|
-
while (i < pendingQueue.length) {
|
|
374
|
-
if (i - directCount >= maxDrainIterations) {
|
|
375
|
-
if (typeof console !== "undefined") {
|
|
376
|
-
console.error(
|
|
377
|
-
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
378
|
-
);
|
|
440
|
+
let node = head;
|
|
441
|
+
while (node) {
|
|
442
|
+
const s = node.sub;
|
|
443
|
+
if (s) {
|
|
444
|
+
if (s._c) {
|
|
445
|
+
propagateDirty(s);
|
|
446
|
+
} else if (!pendingSet.has(s)) {
|
|
447
|
+
pendingSet.add(s);
|
|
448
|
+
pendingQueue.push(s);
|
|
379
449
|
}
|
|
380
|
-
break;
|
|
381
450
|
}
|
|
382
|
-
|
|
383
|
-
i++;
|
|
451
|
+
node = node.sigNext;
|
|
384
452
|
}
|
|
453
|
+
drainQueue();
|
|
385
454
|
} finally {
|
|
386
455
|
notifyDepth--;
|
|
387
456
|
if (notifyDepth === 0) {
|
|
@@ -390,36 +459,26 @@ function notifySubscribers(signal2) {
|
|
|
390
459
|
}
|
|
391
460
|
}
|
|
392
461
|
}
|
|
393
|
-
function
|
|
462
|
+
function getSubscriberCount(signal2) {
|
|
463
|
+
return signal2.__sc ?? 0;
|
|
464
|
+
}
|
|
465
|
+
function getSubscriberDeps(subscriber) {
|
|
394
466
|
const sub = subscriber;
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (
|
|
399
|
-
|
|
400
|
-
if (singleDep.__f === subscriber) {
|
|
401
|
-
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
402
|
-
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
403
|
-
singleDep.__f = subs.values().next().value;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
sub._dep = void 0;
|
|
407
|
-
return;
|
|
467
|
+
const out = [];
|
|
468
|
+
let node = sub.depsHead ?? null;
|
|
469
|
+
while (node) {
|
|
470
|
+
if (node.sig) out.push(node.sig);
|
|
471
|
+
node = node.subNext;
|
|
408
472
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
418
|
-
signal2.__f = subs.values().next().value;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
473
|
+
return out;
|
|
474
|
+
}
|
|
475
|
+
function forEachSubscriber(signal2, visit) {
|
|
476
|
+
let node = signal2.subsHead ?? null;
|
|
477
|
+
while (node) {
|
|
478
|
+
const s = node.sub;
|
|
479
|
+
if (s) visit(s);
|
|
480
|
+
node = node.sigNext;
|
|
421
481
|
}
|
|
422
|
-
deps.clear();
|
|
423
482
|
}
|
|
424
483
|
|
|
425
484
|
// src/reactivity/batch.ts
|
|
@@ -435,32 +494,64 @@ function enqueueBatchedSignal(signal2) {
|
|
|
435
494
|
var _g = globalThis;
|
|
436
495
|
var _isDev3 = isDev();
|
|
437
496
|
function signal(initial, options) {
|
|
438
|
-
const state = {
|
|
497
|
+
const state = {
|
|
498
|
+
value: initial,
|
|
499
|
+
__v: 0,
|
|
500
|
+
__sc: 0,
|
|
501
|
+
subsHead: null,
|
|
502
|
+
subsTail: null,
|
|
503
|
+
__activeNode: null,
|
|
504
|
+
__name: void 0
|
|
505
|
+
};
|
|
439
506
|
const debugName = _isDev3 ? options?.name : void 0;
|
|
440
507
|
const equalsFn = options?.equals;
|
|
441
|
-
if (debugName)
|
|
442
|
-
state.__name = debugName;
|
|
443
|
-
}
|
|
508
|
+
if (debugName) state.__name = debugName;
|
|
444
509
|
function get() {
|
|
445
510
|
recordDependency(state);
|
|
446
511
|
return state.value;
|
|
447
512
|
}
|
|
448
513
|
get.__signal = state;
|
|
449
514
|
if (debugName) get.__name = debugName;
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const
|
|
515
|
+
let set;
|
|
516
|
+
if (equalsFn) {
|
|
517
|
+
set = (next) => {
|
|
518
|
+
const prev = state.value;
|
|
519
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
520
|
+
if (equalsFn(prev, newValue)) return;
|
|
521
|
+
state.value = newValue;
|
|
522
|
+
state.__v++;
|
|
523
|
+
if (_isDev3) {
|
|
524
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
525
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
526
|
+
}
|
|
527
|
+
if (!enqueueBatchedSignal(state)) {
|
|
528
|
+
notifySubscribers(state);
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
} else if (_isDev3) {
|
|
532
|
+
set = (next) => {
|
|
533
|
+
const prev = state.value;
|
|
534
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
535
|
+
if (Object.is(newValue, prev)) return;
|
|
455
536
|
state.value = newValue;
|
|
537
|
+
state.__v++;
|
|
456
538
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
457
|
-
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
|
|
458
|
-
|
|
539
|
+
if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
|
|
540
|
+
if (!enqueueBatchedSignal(state)) {
|
|
541
|
+
notifySubscribers(state);
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
} else {
|
|
545
|
+
set = (next) => {
|
|
546
|
+
const prev = state.value;
|
|
547
|
+
const newValue = typeof next === "function" ? next(prev) : next;
|
|
548
|
+
if (Object.is(newValue, prev)) return;
|
|
459
549
|
state.value = newValue;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
550
|
+
state.__v++;
|
|
551
|
+
if (!enqueueBatchedSignal(state)) {
|
|
552
|
+
notifySubscribers(state);
|
|
553
|
+
}
|
|
554
|
+
};
|
|
464
555
|
}
|
|
465
556
|
if (_isDev3) {
|
|
466
557
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -669,13 +760,14 @@ function initDevTools(config) {
|
|
|
669
760
|
} catch {
|
|
670
761
|
value = "<error>";
|
|
671
762
|
}
|
|
672
|
-
const subs = node.ref?.__s;
|
|
673
763
|
result.push({
|
|
674
764
|
id: node.id,
|
|
675
765
|
name: node.name,
|
|
676
766
|
type: node.type,
|
|
677
767
|
value,
|
|
678
|
-
|
|
768
|
+
// __sc is the O(1) subscriber count maintained by the reactivity
|
|
769
|
+
// core (track.ts) on every linked-list splice.
|
|
770
|
+
subscriberCount: node.ref?.__sc ?? 0
|
|
679
771
|
});
|
|
680
772
|
}
|
|
681
773
|
return result;
|
|
@@ -816,14 +908,13 @@ function initDevTools(config) {
|
|
|
816
908
|
}
|
|
817
909
|
const fullVal = val;
|
|
818
910
|
const shortVal = val.length > 80 ? `${val.substring(0, 80)}...` : val;
|
|
819
|
-
const subs = node.ref?.__s;
|
|
820
911
|
sArr.push({
|
|
821
912
|
id: node.id,
|
|
822
913
|
n: node.name,
|
|
823
914
|
tp: node.type,
|
|
824
915
|
v: shortVal,
|
|
825
916
|
fv: fullVal,
|
|
826
|
-
sc:
|
|
917
|
+
sc: node.ref?.__sc ?? 0
|
|
827
918
|
});
|
|
828
919
|
}
|
|
829
920
|
function walkElement(el, depth) {
|
|
@@ -1463,92 +1554,122 @@ function isSSR() {
|
|
|
1463
1554
|
|
|
1464
1555
|
// src/core/signals/effect.ts
|
|
1465
1556
|
var _g2 = globalThis;
|
|
1557
|
+
var MAX_RERUNS = 100;
|
|
1558
|
+
function flushUserCleanups(ctx) {
|
|
1559
|
+
const list = ctx.userCleanups;
|
|
1560
|
+
if (list.length === 0) return;
|
|
1561
|
+
ctx.userCleanups = [];
|
|
1562
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
1563
|
+
try {
|
|
1564
|
+
list[i]();
|
|
1565
|
+
} catch (err) {
|
|
1566
|
+
if (typeof console !== "undefined") console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
function drainReruns(ctx) {
|
|
1571
|
+
let reruns = 1;
|
|
1572
|
+
do {
|
|
1573
|
+
ctx.rerunPending = false;
|
|
1574
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
1575
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
1576
|
+
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
1577
|
+
if (ctx.rerunPending) {
|
|
1578
|
+
ctx.rerunPending = false;
|
|
1579
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
1580
|
+
console.error(
|
|
1581
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
function disposeEffect(ctx) {
|
|
1587
|
+
if (ctx.disposed) return;
|
|
1588
|
+
ctx.disposed = true;
|
|
1589
|
+
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1590
|
+
if (h) {
|
|
1591
|
+
try {
|
|
1592
|
+
h.emit("effect:destroy", { effectFn: ctx.fn });
|
|
1593
|
+
} catch {
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
try {
|
|
1597
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
1598
|
+
} catch (err) {
|
|
1599
|
+
if (typeof console !== "undefined") {
|
|
1600
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
try {
|
|
1604
|
+
cleanup(ctx.subscriber);
|
|
1605
|
+
} catch (err) {
|
|
1606
|
+
if (typeof console !== "undefined") {
|
|
1607
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1466
1611
|
function effect(effectFn, options) {
|
|
1467
1612
|
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
1468
1613
|
if (isSSR()) return () => {
|
|
1469
1614
|
};
|
|
1470
|
-
const
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
userCleanups
|
|
1615
|
+
const ctx = {
|
|
1616
|
+
fn: effectFn,
|
|
1617
|
+
onError: options?.onError,
|
|
1618
|
+
userCleanups: [],
|
|
1619
|
+
running: false,
|
|
1620
|
+
rerunPending: false,
|
|
1621
|
+
disposed: false,
|
|
1622
|
+
onCleanup: null,
|
|
1623
|
+
subscriber: null,
|
|
1624
|
+
bodyFn: null
|
|
1474
1625
|
};
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
const list = userCleanups;
|
|
1478
|
-
userCleanups = [];
|
|
1479
|
-
for (let i = list.length - 1; i >= 0; i--) {
|
|
1480
|
-
try {
|
|
1481
|
-
list[i]();
|
|
1482
|
-
} catch (err) {
|
|
1483
|
-
if (typeof console !== "undefined") {
|
|
1484
|
-
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1626
|
+
ctx.onCleanup = (fn) => {
|
|
1627
|
+
ctx.userCleanups.push(fn);
|
|
1488
1628
|
};
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1629
|
+
const onErrorCaptured = ctx.onError;
|
|
1630
|
+
ctx.bodyFn = onErrorCaptured ? () => {
|
|
1491
1631
|
try {
|
|
1492
|
-
|
|
1632
|
+
ctx.fn(ctx.onCleanup);
|
|
1493
1633
|
} catch (err) {
|
|
1494
|
-
|
|
1634
|
+
onErrorCaptured(err);
|
|
1495
1635
|
}
|
|
1496
|
-
} :
|
|
1497
|
-
|
|
1636
|
+
} : () => {
|
|
1637
|
+
ctx.fn(ctx.onCleanup);
|
|
1498
1638
|
};
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
1503
|
-
console.warn(
|
|
1504
|
-
"[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."
|
|
1505
|
-
);
|
|
1506
|
-
}
|
|
1639
|
+
const sub = (() => {
|
|
1640
|
+
if (ctx.running) {
|
|
1641
|
+
ctx.rerunPending = true;
|
|
1507
1642
|
return;
|
|
1508
1643
|
}
|
|
1509
|
-
running = true;
|
|
1644
|
+
ctx.running = true;
|
|
1510
1645
|
try {
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1646
|
+
ctx.rerunPending = false;
|
|
1647
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
1648
|
+
retrack(ctx.bodyFn, sub);
|
|
1649
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
1514
1650
|
} finally {
|
|
1515
|
-
running = false;
|
|
1651
|
+
ctx.running = false;
|
|
1652
|
+
ctx.rerunPending = false;
|
|
1516
1653
|
}
|
|
1517
|
-
};
|
|
1518
|
-
|
|
1654
|
+
});
|
|
1655
|
+
sub.depsHead = null;
|
|
1656
|
+
sub.depsTail = null;
|
|
1657
|
+
sub._epoch = 0;
|
|
1658
|
+
sub._structDirty = false;
|
|
1659
|
+
sub._runEpoch = 0;
|
|
1660
|
+
sub._runs = 0;
|
|
1661
|
+
ctx.subscriber = sub;
|
|
1662
|
+
ctx.running = true;
|
|
1519
1663
|
try {
|
|
1520
|
-
|
|
1664
|
+
retrack(ctx.bodyFn, ctx.subscriber);
|
|
1665
|
+
if (ctx.rerunPending) drainReruns(ctx);
|
|
1521
1666
|
} finally {
|
|
1522
|
-
running = false;
|
|
1667
|
+
ctx.running = false;
|
|
1668
|
+
ctx.rerunPending = false;
|
|
1523
1669
|
}
|
|
1524
1670
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1525
1671
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
1526
|
-
|
|
1527
|
-
return () => {
|
|
1528
|
-
if (disposed) return;
|
|
1529
|
-
disposed = true;
|
|
1530
|
-
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1531
|
-
if (h) {
|
|
1532
|
-
try {
|
|
1533
|
-
h.emit("effect:destroy", { effectFn });
|
|
1534
|
-
} catch {
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
try {
|
|
1538
|
-
runUserCleanups();
|
|
1539
|
-
} catch (err) {
|
|
1540
|
-
if (typeof console !== "undefined") {
|
|
1541
|
-
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
try {
|
|
1545
|
-
cleanupHandle();
|
|
1546
|
-
} catch (err) {
|
|
1547
|
-
if (typeof console !== "undefined") {
|
|
1548
|
-
console.warn("[SibuJS effect] dispose threw:", err);
|
|
1549
|
-
}
|
|
1550
|
-
}
|
|
1551
|
-
};
|
|
1672
|
+
return () => disposeEffect(ctx);
|
|
1552
1673
|
}
|
|
1553
1674
|
|
|
1554
1675
|
// src/devtools/debugValue.ts
|
|
@@ -1651,28 +1772,24 @@ function createDevtoolsOverlay(options) {
|
|
|
1651
1772
|
}
|
|
1652
1773
|
|
|
1653
1774
|
// src/devtools/introspect.ts
|
|
1654
|
-
var SUBS2 = "__s";
|
|
1655
1775
|
function getSignalName(getter) {
|
|
1656
1776
|
return getter.__name;
|
|
1657
1777
|
}
|
|
1658
|
-
function
|
|
1778
|
+
function getSubscriberCount2(getter) {
|
|
1659
1779
|
const signal2 = getter.__signal;
|
|
1660
1780
|
if (!signal2) return 0;
|
|
1661
|
-
|
|
1662
|
-
return subs ? subs.size : 0;
|
|
1781
|
+
return getSubscriberCount(signal2);
|
|
1663
1782
|
}
|
|
1664
1783
|
function getDependencies(subscriberFn) {
|
|
1665
|
-
|
|
1666
|
-
return deps ? Array.from(deps) : [];
|
|
1784
|
+
return getSubscriberDeps(subscriberFn);
|
|
1667
1785
|
}
|
|
1668
1786
|
function inspectSignal(getter) {
|
|
1669
1787
|
const signal2 = getter.__signal;
|
|
1670
1788
|
if (!signal2) return null;
|
|
1671
|
-
const subs = signal2[SUBS2];
|
|
1672
1789
|
return {
|
|
1673
1790
|
name: getter.__name,
|
|
1674
1791
|
signal: signal2,
|
|
1675
|
-
subscriberCount:
|
|
1792
|
+
subscriberCount: getSubscriberCount(signal2)
|
|
1676
1793
|
};
|
|
1677
1794
|
}
|
|
1678
1795
|
function walkDependencyGraph(getter, maxDepth = 10, visited = /* @__PURE__ */ new WeakSet()) {
|
|
@@ -1681,24 +1798,21 @@ function walkDependencyGraph(getter, maxDepth = 10, visited = /* @__PURE__ */ ne
|
|
|
1681
1798
|
return { name: getSignalName(getter), subscribers: 0, downstream: [] };
|
|
1682
1799
|
}
|
|
1683
1800
|
visited.add(signal2);
|
|
1684
|
-
const subs = signal2[SUBS2];
|
|
1685
1801
|
const downstream = [];
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
downstream.push(walkDependencyGraph(fakeGetter, maxDepth - 1, visited));
|
|
1696
|
-
}
|
|
1802
|
+
forEachSubscriber(signal2, (sub) => {
|
|
1803
|
+
const subSig = sub._sig;
|
|
1804
|
+
if (subSig && !visited.has(subSig)) {
|
|
1805
|
+
const subName = subSig.__name;
|
|
1806
|
+
const fakeGetter = (() => void 0);
|
|
1807
|
+
const tag = fakeGetter;
|
|
1808
|
+
tag.__signal = subSig;
|
|
1809
|
+
if (subName !== void 0) tag.__name = subName;
|
|
1810
|
+
downstream.push(walkDependencyGraph(fakeGetter, maxDepth - 1, visited));
|
|
1697
1811
|
}
|
|
1698
|
-
}
|
|
1812
|
+
});
|
|
1699
1813
|
return {
|
|
1700
1814
|
name: getSignalName(getter),
|
|
1701
|
-
subscribers:
|
|
1815
|
+
subscribers: getSubscriberCount(signal2),
|
|
1702
1816
|
downstream
|
|
1703
1817
|
};
|
|
1704
1818
|
}
|