sibujs 4.4.0 → 4.6.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 (112) hide show
  1. package/README.md +11 -0
  2. package/dist/browser.cjs +339 -130
  3. package/dist/browser.d.cts +61 -16
  4. package/dist/browser.d.ts +61 -16
  5. package/dist/browser.js +8 -6
  6. package/dist/build.cjs +273 -82
  7. package/dist/build.js +15 -16
  8. package/dist/cdn.dev.global.js +12 -12
  9. package/dist/cdn.full.dev.global.js +11 -11
  10. package/dist/cdn.full.global.js +10 -10
  11. package/dist/cdn.global.js +12 -12
  12. package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
  13. package/dist/chunk-3ISI6ACU.js +44 -0
  14. package/dist/{chunk-VCTAEPSB.js → chunk-47M47FOM.js} +11 -3
  15. package/dist/chunk-5HZXGZ6T.js +24 -0
  16. package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
  17. package/dist/{chunk-3BTTCZ5J.js → chunk-5Q4R7HCL.js} +42 -4
  18. package/dist/{chunk-ADM46X22.js → chunk-7GQCWFOE.js} +157 -61
  19. package/dist/{chunk-4Z3SPQ67.js → chunk-7NCARGJW.js} +16 -8
  20. package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
  21. package/dist/{chunk-LQFGQNMV.js → chunk-AIF3Z2T7.js} +302 -39
  22. package/dist/{chunk-UCALUKB5.js → chunk-BAAG6ZTI.js} +98 -29
  23. package/dist/{chunk-NVNJH22U.js → chunk-D33YTSX5.js} +2 -2
  24. package/dist/{chunk-M2F7TZHH.js → chunk-DKGBBKOF.js} +136 -80
  25. package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
  26. package/dist/{chunk-HFCOH2GN.js → chunk-HYXDKS4N.js} +153 -110
  27. package/dist/chunk-J6FW5TV6.js +233 -0
  28. package/dist/{chunk-36S2YPP4.js → chunk-JSXPZCET.js} +1 -1
  29. package/dist/chunk-NYNYSPK7.js +318 -0
  30. package/dist/{chunk-HQSEH5F6.js → chunk-ORMZXBKQ.js} +108 -45
  31. package/dist/{chunk-LYVUX7NT.js → chunk-OXUY2A6L.js} +287 -130
  32. package/dist/{chunk-6GSIXTWX.js → chunk-PK6FK2G2.js} +187 -66
  33. package/dist/{chunk-W2EQ7X2L.js → chunk-QE4TTDU3.js} +47 -9
  34. package/dist/{chunk-XLO7SLIX.js → chunk-SXXVZMKZ.js} +262 -70
  35. package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
  36. package/dist/{chunk-RR7M3FHM.js → chunk-UZQ6ALFS.js} +3 -3
  37. package/dist/{chunk-PNIRUQ4C.js → chunk-VVWPJ543.js} +6 -8
  38. package/dist/{chunk-7GIHSAWB.js → chunk-XC4MEKGA.js} +3 -3
  39. package/dist/{chunk-SKPTERHP.js → chunk-XRRZKZYX.js} +55 -31
  40. package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
  41. package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
  42. package/dist/{customElement-CNZxEB9G.d.ts → customElement-MmInOW1U.d.cts} +59 -10
  43. package/dist/{customElement-CNZxEB9G.d.cts → customElement-MmInOW1U.d.ts} +59 -10
  44. package/dist/data.cjs +293 -125
  45. package/dist/data.d.cts +47 -9
  46. package/dist/data.d.ts +47 -9
  47. package/dist/data.js +12 -9
  48. package/dist/devtools.cjs +121 -58
  49. package/dist/devtools.js +7 -8
  50. package/dist/dispose-GEIG2KOF.js +28 -0
  51. package/dist/ecosystem.cjs +391 -112
  52. package/dist/ecosystem.d.cts +31 -7
  53. package/dist/ecosystem.d.ts +31 -7
  54. package/dist/ecosystem.js +12 -12
  55. package/dist/extras.cjs +2250 -879
  56. package/dist/extras.d.cts +10 -9
  57. package/dist/extras.d.ts +10 -9
  58. package/dist/extras.js +39 -28
  59. package/dist/index.cjs +273 -82
  60. package/dist/index.d.cts +44 -154
  61. package/dist/index.d.ts +44 -154
  62. package/dist/index.js +24 -27
  63. package/dist/motion.cjs +137 -42
  64. package/dist/motion.js +5 -5
  65. package/dist/patterns.cjs +397 -48
  66. package/dist/patterns.d.cts +32 -9
  67. package/dist/patterns.d.ts +32 -9
  68. package/dist/patterns.js +8 -8
  69. package/dist/performance.cjs +338 -217
  70. package/dist/performance.d.cts +2 -2
  71. package/dist/performance.d.ts +2 -2
  72. package/dist/performance.js +8 -9
  73. package/dist/plugin-DVgSnTfK.d.cts +112 -0
  74. package/dist/plugin-DVgSnTfK.d.ts +112 -0
  75. package/dist/plugins.cjs +587 -203
  76. package/dist/plugins.d.cts +3 -3
  77. package/dist/plugins.d.ts +3 -3
  78. package/dist/plugins.js +35 -23
  79. package/dist/signal-EotCj4hS.d.cts +110 -0
  80. package/dist/signal-EotCj4hS.d.ts +110 -0
  81. package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
  82. package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
  83. package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
  84. package/dist/ssr.cjs +214 -73
  85. package/dist/ssr.d.cts +9 -3
  86. package/dist/ssr.d.ts +9 -3
  87. package/dist/ssr.js +11 -12
  88. package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
  89. package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
  90. package/dist/tagFactory-DFstCLQV.d.cts +117 -0
  91. package/dist/tagFactory-DkaNVUNV.d.ts +117 -0
  92. package/dist/testing.cjs +2481 -2153
  93. package/dist/testing.d.cts +56 -5
  94. package/dist/testing.d.ts +56 -5
  95. package/dist/testing.js +580 -307
  96. package/dist/ui.cjs +798 -328
  97. package/dist/ui.d.cts +40 -7
  98. package/dist/ui.d.ts +40 -7
  99. package/dist/ui.js +151 -56
  100. package/dist/widgets.cjs +319 -285
  101. package/dist/widgets.js +9 -10
  102. package/package.json +2 -2
  103. package/dist/chunk-2WLZ6757.js +0 -149
  104. package/dist/chunk-7NBDXVHS.js +0 -60
  105. package/dist/chunk-CCSJMTRN.js +0 -15
  106. package/dist/chunk-QKRPLZ2V.js +0 -108
  107. package/dist/chunk-WWV3SJ3L.js +0 -131
  108. package/dist/dispose-46BOMMQJ.js +0 -19
  109. package/dist/plugin-D30wlGW5.d.cts +0 -71
  110. package/dist/plugin-D30wlGW5.d.ts +0 -71
  111. package/dist/tagFactory-Bzupt4Pj.d.cts +0 -55
  112. package/dist/tagFactory-Bzupt4Pj.d.ts +0 -55
package/dist/data.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { D as DisposableAccessor } from './signal-EotCj4hS.cjs';
2
+
1
3
  /**
2
4
  * Configurable retry strategies for async operations.
3
5
  * Used by `resource` and `query` for automatic error recovery.
@@ -278,7 +280,8 @@ declare function infiniteQuery<TData, TPageParam = number>(key: string | (() =>
278
280
  * Returns `undefined` on first read (there is no previous value yet).
279
281
  *
280
282
  * @param getter A reactive getter to track
281
- * @returns A reactive getter for the previous value
283
+ * @returns A reactive getter for the previous value, with `dispose()` to stop
284
+ * tracking the source
282
285
  *
283
286
  * @example
284
287
  * ```ts
@@ -291,7 +294,7 @@ declare function infiniteQuery<TData, TPageParam = number>(key: string | (() =>
291
294
  * prev(); // 5
292
295
  * ```
293
296
  */
294
- declare function previous<T>(getter: () => T): () => T | undefined;
297
+ declare function previous<T>(getter: () => T): DisposableAccessor<T | undefined>;
295
298
 
296
299
  /**
297
300
  * Returns a debounced reactive getter that only updates after `delay` ms
@@ -299,7 +302,8 @@ declare function previous<T>(getter: () => T): () => T | undefined;
299
302
  *
300
303
  * @param getter A reactive getter to debounce
301
304
  * @param delay Debounce delay in milliseconds
302
- * @returns A reactive getter for the debounced value
305
+ * @returns A reactive getter for the debounced value, with `dispose()` to stop
306
+ * tracking the source and cancel the pending timer
303
307
  *
304
308
  * @example
305
309
  * ```ts
@@ -308,7 +312,7 @@ declare function previous<T>(getter: () => T): () => T | undefined;
308
312
  * // debouncedSearch() only updates 300ms after the last setSearch call
309
313
  * ```
310
314
  */
311
- declare function debounce<T>(getter: () => T, delay: number): () => T;
315
+ declare function debounce<T>(getter: () => T, delay: number): DisposableAccessor<T>;
312
316
 
313
317
  /**
314
318
  * Returns a throttled reactive getter that updates at most once per `interval` ms.
@@ -317,7 +321,8 @@ declare function debounce<T>(getter: () => T, delay: number): () => T;
317
321
  *
318
322
  * @param getter A reactive getter to throttle
319
323
  * @param interval Throttle interval in milliseconds
320
- * @returns A reactive getter for the throttled value
324
+ * @returns A reactive getter for the throttled value, with `dispose()` to stop
325
+ * tracking the source and clear the cooldown timer
321
326
  *
322
327
  * @example
323
328
  * ```ts
@@ -326,7 +331,7 @@ declare function debounce<T>(getter: () => T, delay: number): () => T;
326
331
  * // throttled() updates at most once every 100ms
327
332
  * ```
328
333
  */
329
- declare function throttle<T>(getter: () => T, interval: number): () => T;
334
+ declare function throttle<T>(getter: () => T, interval: number): DisposableAccessor<T>;
330
335
 
331
336
  /**
332
337
  * Lifecycle callbacks follow the shared data-layer contract: an exception
@@ -527,14 +532,47 @@ interface LoaderRoute {
527
532
  }
528
533
  /**
529
534
  * Execute a route loader and wrap its result in a reactive Resource.
535
+ *
536
+ * Executing a loader does not make its data visible to `loaderData()`; render
537
+ * the route's component inside {@link renderWithLoader} (or use
538
+ * {@link withLoader}) so the component reads its own route's data.
530
539
  */
531
540
  declare function executeLoader<T>(loader: RouteLoaderFn<T>, context: {
532
541
  params: Record<string, string>;
533
542
  path: string;
534
543
  }, options?: ResourceOptions<T>): Resource<T>;
535
544
  /**
536
- * Access loader data from within a route component.
537
- * Must be called inside a component rendered by a route with a loader.
545
+ * Run `render` with `loader` as the loader data seen by `loaderData()`, then
546
+ * restore the previous scope — even if `render` throws. Scopes nest: an inner
547
+ * call shadows the outer one only for its own duration.
548
+ *
549
+ * `loaderData()` must be called synchronously while `render` runs (typically at
550
+ * the top of the component); the accessors it returns stay bound to `loader`
551
+ * afterwards.
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * const data = executeLoader(route.loader, ctx);
556
+ * const view = renderWithLoader(data, () => route.component());
557
+ * ```
558
+ */
559
+ declare function renderWithLoader<T, R>(loader: Resource<T>, render: () => R): R;
560
+ /**
561
+ * Execute `loader` and render with its data in scope, in one step. Returns the
562
+ * rendered result together with the resource, which the caller disposes when
563
+ * the route unmounts.
564
+ */
565
+ declare function withLoader<T, R>(loader: RouteLoaderFn<T>, context: {
566
+ params: Record<string, string>;
567
+ path: string;
568
+ }, render: () => R, options?: ResourceOptions<T>): {
569
+ view: R;
570
+ resource: Resource<T>;
571
+ };
572
+ /**
573
+ * Access loader data from within a route component: the innermost
574
+ * {@link renderWithLoader} scope (per SSR request on the server). Throws when
575
+ * called outside such a scope, or when that scope's loader has been disposed.
538
576
  */
539
577
  declare function loaderData<T = unknown>(): {
540
578
  data: () => T | undefined;
@@ -596,4 +634,4 @@ declare function stream(url: string, options?: {
596
634
  dispose: () => void;
597
635
  };
598
636
 
599
- export { type ConflictStrategy, type InfiniteQueryOptions, type InfiniteQueryResult, type LoaderRoute, type MutationOptions, type MutationResult, type OfflineStore, type OfflineStoreOptions, type QueryOptions, type QueryResult, type Resource, type ResourceOptions, type RetryOptions, type RouteLoaderFn, type SyncAdapter, type SyncChange, type SyncConflict, type SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, resource, setQueryData, socket, stream, syncAdapter, throttle, withRetry };
637
+ export { type ConflictStrategy, type InfiniteQueryOptions, type InfiniteQueryResult, type LoaderRoute, type MutationOptions, type MutationResult, type OfflineStore, type OfflineStoreOptions, type QueryOptions, type QueryResult, type Resource, type ResourceOptions, type RetryOptions, type RouteLoaderFn, type SyncAdapter, type SyncChange, type SyncConflict, type SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, renderWithLoader, resource, setQueryData, socket, stream, syncAdapter, throttle, withLoader, withRetry };
package/dist/data.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { D as DisposableAccessor } from './signal-EotCj4hS.js';
2
+
1
3
  /**
2
4
  * Configurable retry strategies for async operations.
3
5
  * Used by `resource` and `query` for automatic error recovery.
@@ -278,7 +280,8 @@ declare function infiniteQuery<TData, TPageParam = number>(key: string | (() =>
278
280
  * Returns `undefined` on first read (there is no previous value yet).
279
281
  *
280
282
  * @param getter A reactive getter to track
281
- * @returns A reactive getter for the previous value
283
+ * @returns A reactive getter for the previous value, with `dispose()` to stop
284
+ * tracking the source
282
285
  *
283
286
  * @example
284
287
  * ```ts
@@ -291,7 +294,7 @@ declare function infiniteQuery<TData, TPageParam = number>(key: string | (() =>
291
294
  * prev(); // 5
292
295
  * ```
293
296
  */
294
- declare function previous<T>(getter: () => T): () => T | undefined;
297
+ declare function previous<T>(getter: () => T): DisposableAccessor<T | undefined>;
295
298
 
296
299
  /**
297
300
  * Returns a debounced reactive getter that only updates after `delay` ms
@@ -299,7 +302,8 @@ declare function previous<T>(getter: () => T): () => T | undefined;
299
302
  *
300
303
  * @param getter A reactive getter to debounce
301
304
  * @param delay Debounce delay in milliseconds
302
- * @returns A reactive getter for the debounced value
305
+ * @returns A reactive getter for the debounced value, with `dispose()` to stop
306
+ * tracking the source and cancel the pending timer
303
307
  *
304
308
  * @example
305
309
  * ```ts
@@ -308,7 +312,7 @@ declare function previous<T>(getter: () => T): () => T | undefined;
308
312
  * // debouncedSearch() only updates 300ms after the last setSearch call
309
313
  * ```
310
314
  */
311
- declare function debounce<T>(getter: () => T, delay: number): () => T;
315
+ declare function debounce<T>(getter: () => T, delay: number): DisposableAccessor<T>;
312
316
 
313
317
  /**
314
318
  * Returns a throttled reactive getter that updates at most once per `interval` ms.
@@ -317,7 +321,8 @@ declare function debounce<T>(getter: () => T, delay: number): () => T;
317
321
  *
318
322
  * @param getter A reactive getter to throttle
319
323
  * @param interval Throttle interval in milliseconds
320
- * @returns A reactive getter for the throttled value
324
+ * @returns A reactive getter for the throttled value, with `dispose()` to stop
325
+ * tracking the source and clear the cooldown timer
321
326
  *
322
327
  * @example
323
328
  * ```ts
@@ -326,7 +331,7 @@ declare function debounce<T>(getter: () => T, delay: number): () => T;
326
331
  * // throttled() updates at most once every 100ms
327
332
  * ```
328
333
  */
329
- declare function throttle<T>(getter: () => T, interval: number): () => T;
334
+ declare function throttle<T>(getter: () => T, interval: number): DisposableAccessor<T>;
330
335
 
331
336
  /**
332
337
  * Lifecycle callbacks follow the shared data-layer contract: an exception
@@ -527,14 +532,47 @@ interface LoaderRoute {
527
532
  }
528
533
  /**
529
534
  * Execute a route loader and wrap its result in a reactive Resource.
535
+ *
536
+ * Executing a loader does not make its data visible to `loaderData()`; render
537
+ * the route's component inside {@link renderWithLoader} (or use
538
+ * {@link withLoader}) so the component reads its own route's data.
530
539
  */
531
540
  declare function executeLoader<T>(loader: RouteLoaderFn<T>, context: {
532
541
  params: Record<string, string>;
533
542
  path: string;
534
543
  }, options?: ResourceOptions<T>): Resource<T>;
535
544
  /**
536
- * Access loader data from within a route component.
537
- * Must be called inside a component rendered by a route with a loader.
545
+ * Run `render` with `loader` as the loader data seen by `loaderData()`, then
546
+ * restore the previous scope — even if `render` throws. Scopes nest: an inner
547
+ * call shadows the outer one only for its own duration.
548
+ *
549
+ * `loaderData()` must be called synchronously while `render` runs (typically at
550
+ * the top of the component); the accessors it returns stay bound to `loader`
551
+ * afterwards.
552
+ *
553
+ * @example
554
+ * ```ts
555
+ * const data = executeLoader(route.loader, ctx);
556
+ * const view = renderWithLoader(data, () => route.component());
557
+ * ```
558
+ */
559
+ declare function renderWithLoader<T, R>(loader: Resource<T>, render: () => R): R;
560
+ /**
561
+ * Execute `loader` and render with its data in scope, in one step. Returns the
562
+ * rendered result together with the resource, which the caller disposes when
563
+ * the route unmounts.
564
+ */
565
+ declare function withLoader<T, R>(loader: RouteLoaderFn<T>, context: {
566
+ params: Record<string, string>;
567
+ path: string;
568
+ }, render: () => R, options?: ResourceOptions<T>): {
569
+ view: R;
570
+ resource: Resource<T>;
571
+ };
572
+ /**
573
+ * Access loader data from within a route component: the innermost
574
+ * {@link renderWithLoader} scope (per SSR request on the server). Throws when
575
+ * called outside such a scope, or when that scope's loader has been disposed.
538
576
  */
539
577
  declare function loaderData<T = unknown>(): {
540
578
  data: () => T | undefined;
@@ -596,4 +634,4 @@ declare function stream(url: string, options?: {
596
634
  dispose: () => void;
597
635
  };
598
636
 
599
- export { type ConflictStrategy, type InfiniteQueryOptions, type InfiniteQueryResult, type LoaderRoute, type MutationOptions, type MutationResult, type OfflineStore, type OfflineStoreOptions, type QueryOptions, type QueryResult, type Resource, type ResourceOptions, type RetryOptions, type RouteLoaderFn, type SyncAdapter, type SyncChange, type SyncConflict, type SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, resource, setQueryData, socket, stream, syncAdapter, throttle, withRetry };
637
+ export { type ConflictStrategy, type InfiniteQueryOptions, type InfiniteQueryResult, type LoaderRoute, type MutationOptions, type MutationResult, type OfflineStore, type OfflineStoreOptions, type QueryOptions, type QueryResult, type Resource, type ResourceOptions, type RetryOptions, type RouteLoaderFn, type SyncAdapter, type SyncChange, type SyncConflict, type SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, renderWithLoader, resource, setQueryData, socket, stream, syncAdapter, throttle, withLoader, withRetry };
package/dist/data.js CHANGED
@@ -13,23 +13,24 @@ import {
13
13
  preloadRoute,
14
14
  previous,
15
15
  query,
16
+ renderWithLoader,
16
17
  resource,
17
18
  setQueryData,
18
19
  socket,
19
20
  stream,
20
21
  syncAdapter,
21
22
  throttle,
23
+ withLoader,
22
24
  withRetry
23
- } from "./chunk-6GSIXTWX.js";
24
- import "./chunk-7NBDXVHS.js";
25
- import "./chunk-W2EQ7X2L.js";
26
- import "./chunk-IXKSNWV5.js";
25
+ } from "./chunk-PK6FK2G2.js";
26
+ import "./chunk-QE4TTDU3.js";
27
+ import "./chunk-2INLLLMZ.js";
27
28
  import "./chunk-7ZHH77QA.js";
28
- import "./chunk-7GIHSAWB.js";
29
- import "./chunk-5DXA2J44.js";
30
- import "./chunk-NVNJH22U.js";
31
- import "./chunk-3BTTCZ5J.js";
32
- import "./chunk-2WLZ6757.js";
29
+ import "./chunk-XC4MEKGA.js";
30
+ import "./chunk-7XHATCIH.js";
31
+ import "./chunk-D33YTSX5.js";
32
+ import "./chunk-5Q4R7HCL.js";
33
+ import "./chunk-NYNYSPK7.js";
33
34
  export {
34
35
  __resetQueryCache,
35
36
  calculateDelay,
@@ -45,11 +46,13 @@ export {
45
46
  preloadRoute,
46
47
  previous,
47
48
  query,
49
+ renderWithLoader,
48
50
  resource,
49
51
  setQueryData,
50
52
  socket,
51
53
  stream,
52
54
  syncAdapter,
53
55
  throttle,
56
+ withLoader,
54
57
  withRetry
55
58
  };
package/dist/devtools.cjs CHANGED
@@ -280,6 +280,79 @@ function reportError(error, context) {
280
280
  });
281
281
  }
282
282
 
283
+ // src/core/rendering/dispose.ts
284
+ var elementDisposers = /* @__PURE__ */ new WeakMap();
285
+ var MAX_DRAIN_TEARDOWNS = 1e4;
286
+ function reportDrainRunaway(label, executed, remaining) {
287
+ if (typeof console === "undefined") return;
288
+ console.error(
289
+ `[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
290
+ { executed, remaining }
291
+ );
292
+ }
293
+ var activeBindingCount = 0;
294
+ function resolveCapture(capture) {
295
+ let frame = capture;
296
+ while (frame?.closed) frame = frame.forwardTo;
297
+ return frame ?? null;
298
+ }
299
+ var registrationCaptures = [];
300
+ function currentDisposerCapture() {
301
+ return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
302
+ }
303
+ function beginDisposerCapture(capture) {
304
+ if (capture === null && registrationCaptures.length === 0) return false;
305
+ registrationCaptures.push(resolveCapture(capture));
306
+ return true;
307
+ }
308
+ function endDisposerCapture() {
309
+ registrationCaptures.pop();
310
+ }
311
+ function dispose(node) {
312
+ const stack = [node];
313
+ const order = [];
314
+ while (stack.length > 0) {
315
+ const current = stack.pop();
316
+ order.push(current);
317
+ const children = Array.from(current.childNodes);
318
+ for (let i = 0; i < children.length; i++) {
319
+ stack.push(children[i]);
320
+ }
321
+ }
322
+ for (let i = order.length - 1; i >= 0; i--) {
323
+ disposeNodeOwn(order[i]);
324
+ }
325
+ }
326
+ function disposeNodeOwn(node) {
327
+ if (!elementDisposers.has(node)) return;
328
+ let executed = 0;
329
+ let runaway = false;
330
+ while (!runaway) {
331
+ const pending = elementDisposers.get(node);
332
+ if (!pending || pending.length === 0) break;
333
+ const snapshot = pending.slice();
334
+ elementDisposers.delete(node);
335
+ if (DEV) activeBindingCount -= snapshot.length;
336
+ for (let i = 0; i < snapshot.length; i++) {
337
+ if (executed >= MAX_DRAIN_TEARDOWNS) {
338
+ const rest = snapshot.slice(i);
339
+ const added = elementDisposers.get(node);
340
+ elementDisposers.set(node, added ? rest.concat(added) : rest);
341
+ if (DEV) activeBindingCount += rest.length;
342
+ reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
343
+ runaway = true;
344
+ break;
345
+ }
346
+ executed++;
347
+ try {
348
+ snapshot[i]();
349
+ } catch (err) {
350
+ reportError(err, { phase: "cleanup", name: "disposer" });
351
+ }
352
+ }
353
+ }
354
+ }
355
+
283
356
  // src/reactivity/track-core.ts
284
357
  var POOL_MAX = 4096;
285
358
  var nodePool = [];
@@ -427,8 +500,18 @@ function untracked(fn) {
427
500
  var subscriberEpochCounter = 0;
428
501
  function retrack(effectFn, subscriber) {
429
502
  const prev = currentSubscriber;
503
+ let savedDepth = 0;
504
+ let savedSuspendSub = null;
505
+ if (trackingSuspended) {
506
+ savedDepth = suspendDepth;
507
+ savedSuspendSub = suspendSavedSub;
508
+ suspendDepth = 0;
509
+ suspendSavedSub = null;
510
+ trackingSuspended = false;
511
+ }
430
512
  currentSubscriber = subscriber;
431
513
  const sub = subscriber;
514
+ if (sub._cap === void 0) sub._cap = currentDisposerCapture();
432
515
  const epoch = ++subscriberEpochCounter;
433
516
  sub._epoch = epoch;
434
517
  sub._structDirty = false;
@@ -441,6 +524,11 @@ function retrack(effectFn, subscriber) {
441
524
  effectFn();
442
525
  } finally {
443
526
  currentSubscriber = prev;
527
+ if (savedDepth !== 0) {
528
+ suspendDepth = savedDepth;
529
+ suspendSavedSub = savedSuspendSub;
530
+ trackingSuspended = true;
531
+ }
444
532
  let node = sub.depsHead ?? null;
445
533
  while (node !== null) {
446
534
  const next = node.subNext;
@@ -460,11 +548,25 @@ function track(effectFn, subscriber) {
460
548
  if (!subscriber) return reactiveBinding(effectFn);
461
549
  cleanup(subscriber);
462
550
  const prev = currentSubscriber;
551
+ let savedDepth = 0;
552
+ let savedSuspendSub = null;
553
+ if (trackingSuspended) {
554
+ savedDepth = suspendDepth;
555
+ savedSuspendSub = suspendSavedSub;
556
+ suspendDepth = 0;
557
+ suspendSavedSub = null;
558
+ trackingSuspended = false;
559
+ }
463
560
  currentSubscriber = subscriber;
464
561
  try {
465
562
  effectFn();
466
563
  } finally {
467
564
  currentSubscriber = prev;
565
+ if (savedDepth !== 0) {
566
+ suspendDepth = savedDepth;
567
+ suspendSavedSub = savedSuspendSub;
568
+ trackingSuspended = true;
569
+ }
468
570
  const sub2 = subscriber;
469
571
  for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
470
572
  const sig = n.sig;
@@ -601,7 +703,12 @@ function drainQueue() {
601
703
  quarantined.add(sub);
602
704
  continue;
603
705
  }
604
- safeInvoke(sub);
706
+ const pushed = beginDisposerCapture(sub._cap ?? null);
707
+ try {
708
+ safeInvoke(sub);
709
+ } finally {
710
+ if (pushed) endDisposerCapture();
711
+ }
605
712
  }
606
713
  }
607
714
  function drainNotificationQueue() {
@@ -635,8 +742,9 @@ function propagateDirty(sub) {
635
742
  if (s._c) {
636
743
  const nSig = s._sig;
637
744
  if (nSig) {
638
- if (!nSig._d) {
745
+ if (!nSig._d || nSig._f === true) {
639
746
  nSig._d = true;
747
+ nSig._f = false;
640
748
  stack.push(nSig);
641
749
  }
642
750
  } else {
@@ -736,7 +844,7 @@ function forEachSubscriber(signal2, visit) {
736
844
  }
737
845
 
738
846
  // src/reactivity/track.ts
739
- var _runtimeVersion = true ? "4.4.0" : "dev";
847
+ var _runtimeVersion = true ? "4.6.0" : "dev";
740
848
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
741
849
  function resolveReactiveApi() {
742
850
  const g = globalThis;
@@ -1102,6 +1210,16 @@ function initDevTools(config) {
1102
1210
  });
1103
1211
  emit();
1104
1212
  });
1213
+ hook.on("computed:destroy", (payload) => {
1214
+ const p = payload;
1215
+ for (const [id, node] of hook.nodes) {
1216
+ if (node.ref === p.signal) {
1217
+ hook.nodes.delete(id);
1218
+ break;
1219
+ }
1220
+ }
1221
+ emit();
1222
+ });
1105
1223
  hook.on("effect:create", (payload) => {
1106
1224
  _dt.nextNodeId++;
1107
1225
  const name = inferName();
@@ -1598,61 +1716,6 @@ function devState(name, initial) {
1598
1716
  return [get, trackedSet];
1599
1717
  }
1600
1718
 
1601
- // src/core/rendering/dispose.ts
1602
- var elementDisposers = /* @__PURE__ */ new WeakMap();
1603
- var MAX_DRAIN_TEARDOWNS = 1e4;
1604
- function reportDrainRunaway(label, executed, remaining) {
1605
- if (typeof console === "undefined") return;
1606
- console.error(
1607
- `[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
1608
- { executed, remaining }
1609
- );
1610
- }
1611
- var activeBindingCount = 0;
1612
- function dispose(node) {
1613
- const stack = [node];
1614
- const order = [];
1615
- while (stack.length > 0) {
1616
- const current = stack.pop();
1617
- order.push(current);
1618
- const children = Array.from(current.childNodes);
1619
- for (let i = 0; i < children.length; i++) {
1620
- stack.push(children[i]);
1621
- }
1622
- }
1623
- for (let i = order.length - 1; i >= 0; i--) {
1624
- const current = order[i];
1625
- if (elementDisposers.has(current)) {
1626
- let executed = 0;
1627
- let runaway = false;
1628
- while (!runaway) {
1629
- const pending = elementDisposers.get(current);
1630
- if (!pending || pending.length === 0) break;
1631
- const snapshot = pending.slice();
1632
- elementDisposers.delete(current);
1633
- if (DEV) activeBindingCount -= snapshot.length;
1634
- for (let i2 = 0; i2 < snapshot.length; i2++) {
1635
- if (executed >= MAX_DRAIN_TEARDOWNS) {
1636
- const rest = snapshot.slice(i2);
1637
- const added = elementDisposers.get(current);
1638
- elementDisposers.set(current, added ? rest.concat(added) : rest);
1639
- if (DEV) activeBindingCount += rest.length;
1640
- reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
1641
- runaway = true;
1642
- break;
1643
- }
1644
- executed++;
1645
- try {
1646
- snapshot[i2]();
1647
- } catch (err) {
1648
- reportError(err, { phase: "cleanup", name: "disposer" });
1649
- }
1650
- }
1651
- }
1652
- }
1653
- }
1654
- }
1655
-
1656
1719
  // src/devtools/hmr.ts
1657
1720
  var HMR_STORE_MAX_SIZE = 200;
1658
1721
  var hmrStateStore = /* @__PURE__ */ new Map();
package/dist/devtools.js CHANGED
@@ -35,17 +35,16 @@ import {
35
35
  trackCleanup,
36
36
  walkDependencyGraph,
37
37
  withErrorTracking
38
- } from "./chunk-4Z3SPQ67.js";
39
- import "./chunk-IXKSNWV5.js";
38
+ } from "./chunk-7NCARGJW.js";
39
+ import "./chunk-2INLLLMZ.js";
40
40
  import "./chunk-7ZHH77QA.js";
41
- import "./chunk-7GIHSAWB.js";
42
- import "./chunk-5DXA2J44.js";
43
- import "./chunk-QKRPLZ2V.js";
44
- import "./chunk-NVNJH22U.js";
45
- import "./chunk-3BTTCZ5J.js";
41
+ import "./chunk-XC4MEKGA.js";
42
+ import "./chunk-7XHATCIH.js";
43
+ import "./chunk-D33YTSX5.js";
44
+ import "./chunk-5Q4R7HCL.js";
46
45
  import {
47
46
  isDev
48
- } from "./chunk-2WLZ6757.js";
47
+ } from "./chunk-NYNYSPK7.js";
49
48
 
50
49
  // src/devtools/signalGraph.ts
51
50
  function getHook() {
@@ -0,0 +1,28 @@
1
+ import {
2
+ MAX_DRAIN_TEARDOWNS,
3
+ beginDisposerCapture,
4
+ checkLeaks,
5
+ currentDisposerCapture,
6
+ dispose,
7
+ disposeNodeOwn,
8
+ endDisposerCapture,
9
+ registerDisposer,
10
+ replaceChildrenSafely,
11
+ reportDrainRunaway,
12
+ unregisterDisposer,
13
+ withDisposerRollback
14
+ } from "./chunk-NYNYSPK7.js";
15
+ export {
16
+ MAX_DRAIN_TEARDOWNS,
17
+ beginDisposerCapture,
18
+ checkLeaks,
19
+ currentDisposerCapture,
20
+ dispose,
21
+ disposeNodeOwn,
22
+ endDisposerCapture,
23
+ registerDisposer,
24
+ replaceChildrenSafely,
25
+ reportDrainRunaway,
26
+ unregisterDisposer,
27
+ withDisposerRollback
28
+ };