sibujs 2.0.0 → 2.1.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.
Files changed (60) hide show
  1. package/dist/browser.cjs +144 -102
  2. package/dist/browser.js +4 -4
  3. package/dist/build.cjs +183 -102
  4. package/dist/build.js +10 -10
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-MIUAXB7K.js → chunk-3DZP6OIT.js} +2 -2
  7. package/dist/{chunk-ITX6OO3F.js → chunk-45YP72ZQ.js} +1 -1
  8. package/dist/{chunk-ND2664SF.js → chunk-AMK2TYNW.js} +13 -9
  9. package/dist/{chunk-R73P76YZ.js → chunk-CWBVQML6.js} +1 -1
  10. package/dist/{chunk-54EDRCEF.js → chunk-DRUZZAK4.js} +1 -1
  11. package/dist/{chunk-3NSGB5JN.js → chunk-GWWURC5M.js} +2 -2
  12. package/dist/{chunk-SAHNHTFC.js → chunk-KGYT6UO6.js} +3 -3
  13. package/dist/{chunk-52YJLLRO.js → chunk-NASX6ST2.js} +1 -1
  14. package/dist/{chunk-O2MNQFLP.js → chunk-O6EFQ3KT.js} +5 -5
  15. package/dist/{chunk-GTBNNBJ6.js → chunk-OJ3P4ECI.js} +1 -1
  16. package/dist/{chunk-7JDB7I65.js → chunk-ON5MMR2J.js} +4 -4
  17. package/dist/{chunk-KLRMB5ZS.js → chunk-P2HSJDDN.js} +2 -2
  18. package/dist/{chunk-VLPPXTYG.js → chunk-QO3WC6FS.js} +145 -93
  19. package/dist/{chunk-CC65Y57T.js → chunk-RDTDJCAB.js} +1 -1
  20. package/dist/{chunk-JXMMDLBY.js → chunk-TH2ILCYW.js} +8 -4
  21. package/dist/{chunk-3LR7GLWQ.js → chunk-V6C4FADE.js} +3 -3
  22. package/dist/{chunk-WOMYAHHI.js → chunk-WANSMF2L.js} +4 -4
  23. package/dist/{chunk-DFPFITST.js → chunk-WIPZPFBQ.js} +1 -1
  24. package/dist/{chunk-HB24TBAF.js → chunk-WZA53FXU.js} +38 -10
  25. package/dist/{chunk-JA6667UN.js → chunk-ZAQSMOED.js} +4 -4
  26. package/dist/data.cjs +176 -102
  27. package/dist/data.js +6 -6
  28. package/dist/devtools.cjs +148 -91
  29. package/dist/devtools.d.cts +1 -1
  30. package/dist/devtools.d.ts +1 -1
  31. package/dist/devtools.js +4 -4
  32. package/dist/ecosystem.cjs +176 -102
  33. package/dist/ecosystem.js +7 -7
  34. package/dist/extras.cjs +182 -104
  35. package/dist/extras.d.cts +1 -1
  36. package/dist/extras.d.ts +1 -1
  37. package/dist/extras.js +19 -19
  38. package/dist/index.cjs +185 -102
  39. package/dist/index.d.cts +15 -1
  40. package/dist/index.d.ts +15 -1
  41. package/dist/index.js +14 -10
  42. package/dist/{introspect-BWNjNw64.d.cts → introspect-2TOlQ7oa.d.cts} +3 -1
  43. package/dist/{introspect-cY2pg9pW.d.ts → introspect-DnIpHQQz.d.ts} +3 -1
  44. package/dist/motion.cjs +78 -62
  45. package/dist/motion.js +3 -3
  46. package/dist/patterns.cjs +176 -102
  47. package/dist/patterns.js +5 -5
  48. package/dist/performance.cjs +142 -89
  49. package/dist/performance.js +4 -4
  50. package/dist/plugins.cjs +142 -89
  51. package/dist/plugins.js +6 -6
  52. package/dist/ssr.cjs +144 -102
  53. package/dist/ssr.js +7 -7
  54. package/dist/testing.cjs +66 -28
  55. package/dist/testing.js +2 -2
  56. package/dist/ui.cjs +174 -89
  57. package/dist/ui.js +6 -6
  58. package/dist/widgets.cjs +176 -102
  59. package/dist/widgets.js +6 -6
  60. package/package.json +1 -1
package/dist/devtools.cjs CHANGED
@@ -184,11 +184,24 @@ function devWarn(message) {
184
184
 
185
185
  // src/reactivity/track.ts
186
186
  var _isDev2 = isDev();
187
- var subscriberStack = new Array(32);
188
- var stackCapacity = 32;
187
+ var STACK_INITIAL = 32;
188
+ var STACK_SHRINK_THRESHOLD = 128;
189
+ var subscriberStack = new Array(STACK_INITIAL);
190
+ var stackCapacity = STACK_INITIAL;
189
191
  var stackTop = -1;
190
192
  var currentSubscriber = null;
191
193
  var SUBS = "__s";
194
+ function syncFastPath(signal2, subs) {
195
+ const size = subs.size;
196
+ if (size === 0) {
197
+ signal2.__f = void 0;
198
+ delete signal2[SUBS];
199
+ } else if (size === 1) {
200
+ signal2.__f = subs.values().next().value;
201
+ } else {
202
+ signal2.__f = void 0;
203
+ }
204
+ }
192
205
  var notifyDepth = 0;
193
206
  var pendingQueue = [];
194
207
  var pendingSet = /* @__PURE__ */ new Set();
@@ -215,39 +228,94 @@ function track(effectFn, subscriber) {
215
228
  } finally {
216
229
  stackTop--;
217
230
  currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
231
+ if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
232
+ stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
233
+ subscriberStack.length = stackCapacity;
234
+ }
218
235
  }
219
236
  return () => cleanup(subscriber);
220
237
  }
221
238
  function recordDependency(signal2) {
222
239
  if (!currentSubscriber) return;
223
240
  const sub = currentSubscriber;
224
- if (sub._dep === signal2) return;
241
+ const epoch = sub._epoch;
242
+ if (sub._dep === signal2) {
243
+ sub._depEpoch = epoch;
244
+ return;
245
+ }
225
246
  const deps = sub._deps;
226
247
  if (deps) {
227
- if (deps.has(signal2)) return;
228
- deps.add(signal2);
248
+ deps.set(signal2, epoch);
229
249
  } else if (sub._dep !== void 0) {
230
- const set = /* @__PURE__ */ new Set();
231
- set.add(sub._dep);
232
- set.add(signal2);
233
- sub._deps = set;
250
+ const map = /* @__PURE__ */ new Map();
251
+ map.set(sub._dep, sub._depEpoch);
252
+ map.set(signal2, epoch);
253
+ sub._deps = map;
234
254
  sub._dep = void 0;
255
+ sub._depEpoch = void 0;
235
256
  } else {
236
257
  sub._dep = signal2;
258
+ sub._depEpoch = epoch;
237
259
  }
238
- let subs = signal2[SUBS];
260
+ const sig = signal2;
261
+ let subs = sig[SUBS];
239
262
  if (!subs) {
240
263
  subs = /* @__PURE__ */ new Set();
241
- signal2[SUBS] = subs;
264
+ sig[SUBS] = subs;
242
265
  }
266
+ const prevSize = subs.size;
243
267
  subs.add(currentSubscriber);
244
- if (subs.size === 1) {
245
- signal2.__f = currentSubscriber;
246
- } else if (signal2.__f !== void 0) {
247
- signal2.__f = void 0;
268
+ if (subs.size !== prevSize) {
269
+ if (subs.size === 1) {
270
+ sig.__f = currentSubscriber;
271
+ } else if (sig.__f !== void 0) {
272
+ sig.__f = void 0;
273
+ }
274
+ }
275
+ }
276
+ var maxSubscriberRepeats = 50;
277
+ var maxDrainIterations = 1e6;
278
+ var drainEpoch = 0;
279
+ function tickRepeat(sub) {
280
+ const s = sub;
281
+ if (s._runEpoch !== drainEpoch) {
282
+ s._runEpoch = drainEpoch;
283
+ s._runs = 1;
284
+ return false;
285
+ }
286
+ return ++s._runs > maxSubscriberRepeats;
287
+ }
288
+ function cycleError(sub) {
289
+ if (typeof console !== "undefined") {
290
+ const name = sub.__name ?? "<unnamed>";
291
+ console.error(
292
+ `[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
293
+ );
294
+ }
295
+ }
296
+ function absoluteDrainError() {
297
+ if (typeof console !== "undefined") {
298
+ console.error(
299
+ `[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
300
+ );
301
+ }
302
+ }
303
+ function drainQueue() {
304
+ let i = 0;
305
+ while (i < pendingQueue.length) {
306
+ if (i >= maxDrainIterations) {
307
+ absoluteDrainError();
308
+ break;
309
+ }
310
+ const sub = pendingQueue[i++];
311
+ if (tickRepeat(sub)) {
312
+ cycleError(sub);
313
+ break;
314
+ }
315
+ pendingSet.delete(sub);
316
+ safeInvoke(sub);
248
317
  }
249
318
  }
250
- var maxDrainIterations = 1e5;
251
319
  function propagateDirty(sub) {
252
320
  sub();
253
321
  const rootSig = sub._sig;
@@ -302,25 +370,16 @@ function notifySubscribers(signal2) {
302
370
  return;
303
371
  }
304
372
  notifyDepth++;
373
+ drainEpoch++;
305
374
  try {
306
375
  if (first._c) {
307
376
  propagateDirty(first);
377
+ } else if (tickRepeat(first)) {
378
+ cycleError(first);
308
379
  } else {
309
380
  safeInvoke(first);
310
381
  }
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
- }
382
+ drainQueue();
324
383
  } finally {
325
384
  notifyDepth--;
326
385
  if (notifyDepth === 0) {
@@ -344,44 +403,17 @@ function notifySubscribers(signal2) {
344
403
  return;
345
404
  }
346
405
  notifyDepth++;
406
+ drainEpoch++;
347
407
  try {
348
- let directCount = 0;
349
- let hasComputedSub = false;
350
408
  for (const sub of subs) {
351
- if (sub._c) hasComputedSub = true;
352
- pendingQueue[directCount++] = sub;
353
- }
354
- if (!hasComputedSub) {
355
- for (let i2 = 0; i2 < directCount; i2++) {
356
- safeInvoke(pendingQueue[i2]);
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
- );
379
- }
380
- break;
409
+ if (sub._c) {
410
+ propagateDirty(sub);
411
+ } else if (!pendingSet.has(sub)) {
412
+ pendingSet.add(sub);
413
+ pendingQueue.push(sub);
381
414
  }
382
- safeInvoke(pendingQueue[i]);
383
- i++;
384
415
  }
416
+ drainQueue();
385
417
  } finally {
386
418
  notifyDepth--;
387
419
  if (notifyDepth === 0) {
@@ -394,29 +426,22 @@ function cleanup(subscriber) {
394
426
  const sub = subscriber;
395
427
  const singleDep = sub._dep;
396
428
  if (singleDep !== void 0) {
397
- const subs = singleDep[SUBS];
398
- if (subs) {
399
- subs.delete(subscriber);
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
- }
429
+ const sig = singleDep;
430
+ const subs = sig[SUBS];
431
+ if (subs?.delete(subscriber)) {
432
+ syncFastPath(sig, subs);
405
433
  }
406
434
  sub._dep = void 0;
435
+ sub._depEpoch = void 0;
407
436
  return;
408
437
  }
409
438
  const deps = sub._deps;
410
439
  if (!deps || deps.size === 0) return;
411
- for (const signal2 of deps) {
412
- const subs = signal2[SUBS];
413
- if (subs) {
414
- subs.delete(subscriber);
415
- if (signal2.__f === subscriber) {
416
- signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
417
- } else if (subs.size === 1 && signal2.__f === void 0) {
418
- signal2.__f = subs.values().next().value;
419
- }
440
+ for (const signal2 of deps.keys()) {
441
+ const sig = signal2;
442
+ const subs = sig[SUBS];
443
+ if (subs?.delete(subscriber)) {
444
+ syncFastPath(sig, subs);
420
445
  }
421
446
  }
422
447
  deps.clear();
@@ -1497,29 +1522,57 @@ function effect(effectFn, options) {
1497
1522
  let cleanupHandle = () => {
1498
1523
  };
1499
1524
  let running = false;
1525
+ let rerunPending = false;
1526
+ const MAX_RERUNS = 100;
1500
1527
  const subscriber = () => {
1501
1528
  if (running) {
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
- }
1529
+ rerunPending = true;
1507
1530
  return;
1508
1531
  }
1509
1532
  running = true;
1510
1533
  try {
1511
- runUserCleanups();
1512
- cleanupHandle();
1513
- cleanupHandle = track(wrappedFn, subscriber);
1534
+ let reruns = 0;
1535
+ do {
1536
+ rerunPending = false;
1537
+ runUserCleanups();
1538
+ cleanupHandle();
1539
+ cleanupHandle = track(wrappedFn, subscriber);
1540
+ if (++reruns > MAX_RERUNS) {
1541
+ if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1542
+ console.error(
1543
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1544
+ );
1545
+ }
1546
+ rerunPending = false;
1547
+ break;
1548
+ }
1549
+ } while (rerunPending);
1514
1550
  } finally {
1515
1551
  running = false;
1552
+ rerunPending = false;
1516
1553
  }
1517
1554
  };
1518
1555
  running = true;
1519
1556
  try {
1520
- cleanupHandle = track(wrappedFn, subscriber);
1557
+ let reruns = 0;
1558
+ do {
1559
+ rerunPending = false;
1560
+ runUserCleanups();
1561
+ cleanupHandle();
1562
+ cleanupHandle = track(wrappedFn, subscriber);
1563
+ if (++reruns > MAX_RERUNS) {
1564
+ if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
1565
+ console.error(
1566
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
1567
+ );
1568
+ }
1569
+ rerunPending = false;
1570
+ break;
1571
+ }
1572
+ } while (rerunPending);
1521
1573
  } finally {
1522
1574
  running = false;
1575
+ rerunPending = false;
1523
1576
  }
1524
1577
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1525
1578
  if (hook) hook.emit("effect:create", { effectFn });
@@ -1662,8 +1715,12 @@ function getSubscriberCount(getter) {
1662
1715
  return subs ? subs.size : 0;
1663
1716
  }
1664
1717
  function getDependencies(subscriberFn) {
1665
- const deps = subscriberFn._deps;
1666
- return deps ? Array.from(deps) : [];
1718
+ const fn = subscriberFn;
1719
+ const singleDep = fn._dep;
1720
+ if (singleDep !== void 0) return [singleDep];
1721
+ const deps = fn._deps;
1722
+ if (!deps) return [];
1723
+ return deps instanceof Map ? Array.from(deps.keys()) : Array.from(deps);
1667
1724
  }
1668
1725
  function inspectSignal(getter) {
1669
1726
  const signal2 = getter.__signal;
@@ -1,4 +1,4 @@
1
- export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R as ReactiveNodeInfo, S as SibuError, c as checkLeaks, b as clearDebugValues, d as clearHMRModule, e as clearHMRState, f as clearPerformanceData, g as createDevtoolsOverlay, h as createErrorReporter, i as createHMRBoundary, j as createProfiler, k as debugLog, l as debugValue, m as devState, n as disableDebug, o as enableDebug, p as exposeHMR, q as formatError, r as getActiveDevTools, s as getDebugValues, t as getDependencies, u as getPerformanceReport, v as getSignalName, w as getSubscriberCount, x as hmrState, y as initDevTools, z as inspectSignal, A as isDebugEnabled, B as isHMRAvailable, C as measureRender, E as perfTracker, F as registerHMR, G as runCleanups, H as startMeasure, I as trackCleanup, J as walkDependencyGraph, K as withErrorTracking } from './introspect-BWNjNw64.cjs';
1
+ export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R as ReactiveNodeInfo, S as SibuError, c as checkLeaks, b as clearDebugValues, d as clearHMRModule, e as clearHMRState, f as clearPerformanceData, g as createDevtoolsOverlay, h as createErrorReporter, i as createHMRBoundary, j as createProfiler, k as debugLog, l as debugValue, m as devState, n as disableDebug, o as enableDebug, p as exposeHMR, q as formatError, r as getActiveDevTools, s as getDebugValues, t as getDependencies, u as getPerformanceReport, v as getSignalName, w as getSubscriberCount, x as hmrState, y as initDevTools, z as inspectSignal, A as isDebugEnabled, B as isHMRAvailable, C as measureRender, E as perfTracker, F as registerHMR, G as runCleanups, H as startMeasure, I as trackCleanup, J as walkDependencyGraph, K as withErrorTracking } from './introspect-2TOlQ7oa.cjs';
2
2
  import './signal-BnWpq6WB.cjs';
3
3
 
4
4
  interface SignalNodeSnapshot {
@@ -1,4 +1,4 @@
1
- export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R as ReactiveNodeInfo, S as SibuError, c as checkLeaks, b as clearDebugValues, d as clearHMRModule, e as clearHMRState, f as clearPerformanceData, g as createDevtoolsOverlay, h as createErrorReporter, i as createHMRBoundary, j as createProfiler, k as debugLog, l as debugValue, m as devState, n as disableDebug, o as enableDebug, p as exposeHMR, q as formatError, r as getActiveDevTools, s as getDebugValues, t as getDependencies, u as getPerformanceReport, v as getSignalName, w as getSubscriberCount, x as hmrState, y as initDevTools, z as inspectSignal, A as isDebugEnabled, B as isHMRAvailable, C as measureRender, E as perfTracker, F as registerHMR, G as runCleanups, H as startMeasure, I as trackCleanup, J as walkDependencyGraph, K as withErrorTracking } from './introspect-cY2pg9pW.js';
1
+ export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R as ReactiveNodeInfo, S as SibuError, c as checkLeaks, b as clearDebugValues, d as clearHMRModule, e as clearHMRState, f as clearPerformanceData, g as createDevtoolsOverlay, h as createErrorReporter, i as createHMRBoundary, j as createProfiler, k as debugLog, l as debugValue, m as devState, n as disableDebug, o as enableDebug, p as exposeHMR, q as formatError, r as getActiveDevTools, s as getDebugValues, t as getDependencies, u as getPerformanceReport, v as getSignalName, w as getSubscriberCount, x as hmrState, y as initDevTools, z as inspectSignal, A as isDebugEnabled, B as isHMRAvailable, C as measureRender, E as perfTracker, F as registerHMR, G as runCleanups, H as startMeasure, I as trackCleanup, J as walkDependencyGraph, K as withErrorTracking } from './introspect-DnIpHQQz.js';
2
2
  import './signal-BnWpq6WB.js';
3
3
 
4
4
  interface SignalNodeSnapshot {
package/dist/devtools.js CHANGED
@@ -35,13 +35,13 @@ import {
35
35
  trackCleanup,
36
36
  walkDependencyGraph,
37
37
  withErrorTracking
38
- } from "./chunk-JXMMDLBY.js";
38
+ } from "./chunk-TH2ILCYW.js";
39
39
  import "./chunk-2UPRY23K.js";
40
40
  import "./chunk-UCS6AMJ7.js";
41
- import "./chunk-HB24TBAF.js";
41
+ import "./chunk-WZA53FXU.js";
42
42
  import "./chunk-2RA7SHDA.js";
43
- import "./chunk-CC65Y57T.js";
44
- import "./chunk-VLPPXTYG.js";
43
+ import "./chunk-RDTDJCAB.js";
44
+ import "./chunk-QO3WC6FS.js";
45
45
  import {
46
46
  isDev
47
47
  } from "./chunk-LMLD24FC.js";