sibujs 4.8.0 → 4.10.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 (66) hide show
  1. package/dist/browser.cjs +44 -6
  2. package/dist/browser.d.cts +3 -2
  3. package/dist/browser.d.ts +3 -2
  4. package/dist/browser.js +4 -4
  5. package/dist/build.cjs +128 -56
  6. package/dist/build.js +10 -10
  7. package/dist/cdn.dev.global.js +14 -14
  8. package/dist/cdn.full.dev.global.js +13 -13
  9. package/dist/cdn.full.global.js +12 -12
  10. package/dist/cdn.global.js +15 -15
  11. package/dist/{chunk-J3YQ457H.js → chunk-2NWHJ2UJ.js} +99 -61
  12. package/dist/{chunk-JUTFX2RM.js → chunk-4DCVJ4YA.js} +42 -15
  13. package/dist/{chunk-QGMSESDD.js → chunk-54F4TPHK.js} +2 -2
  14. package/dist/{chunk-KJ3UKABJ.js → chunk-5PC7OTQW.js} +1 -1
  15. package/dist/{chunk-V3LHZSU5.js → chunk-7WIHYHWD.js} +8 -1
  16. package/dist/{chunk-44MTL7ED.js → chunk-BMCR7TXG.js} +3 -3
  17. package/dist/{chunk-TQQUN4WR.js → chunk-D6HYFOWR.js} +39 -4
  18. package/dist/{chunk-VWT3VXPL.js → chunk-EVI4ZQO3.js} +2 -2
  19. package/dist/{chunk-CZPRSWSS.js → chunk-EVOK663Z.js} +1 -1
  20. package/dist/{chunk-DSID757X.js → chunk-FYUEL5IW.js} +1 -1
  21. package/dist/{chunk-UCNP3HVM.js → chunk-GMMDHJJT.js} +30 -12
  22. package/dist/{chunk-C7AA2CZX.js → chunk-GOL3FU5Q.js} +1 -1
  23. package/dist/{chunk-EGUQLBHE.js → chunk-GTS35FLA.js} +5 -4
  24. package/dist/{chunk-GSGNX35Q.js → chunk-IFRIBZ4O.js} +4 -4
  25. package/dist/{chunk-C5PEWEGH.js → chunk-IL5MMSCL.js} +19 -12
  26. package/dist/{chunk-ZVLHNEEL.js → chunk-ITEL5KPL.js} +6 -6
  27. package/dist/{chunk-RGLPEBDE.js → chunk-JCKUWWHU.js} +3 -3
  28. package/dist/{chunk-Q5J2LVKH.js → chunk-N6U4GOIU.js} +1 -1
  29. package/dist/{chunk-LI4W3U6C.js → chunk-TOPRMXFY.js} +1 -1
  30. package/dist/{chunk-4WMSTZ7J.js → chunk-VWPMWV7O.js} +4 -4
  31. package/dist/{chunk-O6TRVMJI.js → chunk-XUQUQJYE.js} +1 -1
  32. package/dist/data.cjs +67 -12
  33. package/dist/data.d.cts +32 -5
  34. package/dist/data.d.ts +32 -5
  35. package/dist/data.js +5 -5
  36. package/dist/devtools.cjs +41 -4
  37. package/dist/devtools.js +4 -4
  38. package/dist/ecosystem.cjs +41 -4
  39. package/dist/ecosystem.js +7 -7
  40. package/dist/extras.cjs +125 -41
  41. package/dist/extras.js +20 -20
  42. package/dist/index.cjs +128 -56
  43. package/dist/index.d.cts +22 -0
  44. package/dist/index.d.ts +22 -0
  45. package/dist/index.js +10 -10
  46. package/dist/motion.cjs +36 -4
  47. package/dist/motion.js +3 -3
  48. package/dist/patterns.cjs +41 -4
  49. package/dist/patterns.js +5 -5
  50. package/dist/performance.cjs +55 -14
  51. package/dist/performance.js +4 -4
  52. package/dist/plugins.cjs +176 -60
  53. package/dist/plugins.d.cts +62 -2
  54. package/dist/plugins.d.ts +62 -2
  55. package/dist/plugins.js +143 -61
  56. package/dist/ssr.cjs +77 -16
  57. package/dist/ssr.d.cts +4 -0
  58. package/dist/ssr.d.ts +4 -0
  59. package/dist/ssr.js +7 -7
  60. package/dist/testing.cjs +41 -4
  61. package/dist/testing.js +2 -2
  62. package/dist/ui.cjs +42 -5
  63. package/dist/ui.js +7 -7
  64. package/dist/widgets.cjs +36 -4
  65. package/dist/widgets.js +6 -6
  66. package/package.json +1 -1
@@ -4,7 +4,7 @@ import {
4
4
  notifySubscribers,
5
5
  queueSignalNotification,
6
6
  recordDependency
7
- } from "./chunk-TQQUN4WR.js";
7
+ } from "./chunk-D6HYFOWR.js";
8
8
  import {
9
9
  DEV
10
10
  } from "./chunk-NYNYSPK7.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  derived
3
- } from "./chunk-KJ3UKABJ.js";
3
+ } from "./chunk-5PC7OTQW.js";
4
4
  import {
5
5
  globalSingleton
6
6
  } from "./chunk-7ZHH77QA.js";
7
7
  import {
8
8
  effect
9
- } from "./chunk-V3LHZSU5.js";
9
+ } from "./chunk-7WIHYHWD.js";
10
10
  import {
11
11
  sanitizeUrl
12
12
  } from "./chunk-EXXSN3BW.js";
@@ -16,10 +16,10 @@ import {
16
16
  import {
17
17
  batch,
18
18
  signal
19
- } from "./chunk-DSID757X.js";
19
+ } from "./chunk-FYUEL5IW.js";
20
20
  import {
21
21
  untracked
22
- } from "./chunk-TQQUN4WR.js";
22
+ } from "./chunk-D6HYFOWR.js";
23
23
  import {
24
24
  reportError
25
25
  } from "./chunk-NYNYSPK7.js";
@@ -268,6 +268,8 @@ function query(key, fetcher, options = {}) {
268
268
  structuralSharing = true
269
269
  } = options;
270
270
  const resolveKey = typeof key === "function" ? key : () => key;
271
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
272
+ const isEnabled = enabledGate ?? (() => Boolean(enabled));
271
273
  const cache = getActiveQueryCache();
272
274
  const [data, setData] = signal(initialData);
273
275
  const [isFetching, setIsFetching] = signal(false);
@@ -286,6 +288,7 @@ function query(key, fetcher, options = {}) {
286
288
  let currentKey = null;
287
289
  let attachedEntry = null;
288
290
  let attachedKey = null;
291
+ let lastEnabled = null;
289
292
  let intervalTimer = null;
290
293
  const loading = derived(() => isFetching() && data() === void 0);
291
294
  const isStale = derived(() => {
@@ -382,7 +385,7 @@ function query(key, fetcher, options = {}) {
382
385
  }
383
386
  }
384
387
  async function doFetch() {
385
- if (disposed || !currentKey || !enabled) return;
388
+ if (disposed || !currentKey || !untracked(isEnabled)) return;
386
389
  const key2 = currentKey;
387
390
  const entry = getOrCreateEntry(cache, key2);
388
391
  attachToEntry(entry, key2);
@@ -484,10 +487,20 @@ function query(key, fetcher, options = {}) {
484
487
  }
485
488
  const effectCleanup = effect(() => {
486
489
  const key2 = resolveKey();
490
+ const on = isEnabled();
487
491
  const keyChanged = currentKey !== key2;
492
+ const enabledRose = on && lastEnabled === false;
488
493
  currentKey = key2;
494
+ lastEnabled = on;
495
+ if (key2 === "") {
496
+ detachFromEntry();
497
+ setIsFetching(false);
498
+ return;
499
+ }
489
500
  const entry = getOrCreateEntry(cache, key2, initialData);
501
+ const reattached = attachedEntry !== entry;
490
502
  attachToEntry(entry, key2);
503
+ if (keyChanged) setIsFetching(entry.promise !== null);
491
504
  if (entry.data !== void 0) {
492
505
  const view = viewOf(entry);
493
506
  batch(() => {
@@ -496,19 +509,20 @@ function query(key, fetcher, options = {}) {
496
509
  setUpdatedAt(entry.dataUpdatedAt);
497
510
  });
498
511
  }
499
- if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
512
+ if (!keyChanged && !reattached && !enabledRose) return;
513
+ if (!keyChanged && entry.data !== void 0) {
500
514
  const isDataStale2 = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
501
- if (enabled && isDataStale2 && !entry.promise) doFetch();
515
+ if (on && isDataStale2 && !entry.promise) doFetch();
502
516
  return;
503
517
  }
504
518
  const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
505
- if (enabled && (entry.data === void 0 || isDataStale)) {
519
+ if (on && (entry.data === void 0 || isDataStale)) {
506
520
  doFetch();
507
521
  }
508
522
  });
509
523
  if (refetchInterval && refetchInterval > 0) {
510
524
  intervalTimer = setInterval(() => {
511
- if (!disposed && currentKey && enabled) doFetch();
525
+ if (!disposed && currentKey) doFetch();
512
526
  }, refetchInterval);
513
527
  }
514
528
  let focusHandler = null;
@@ -516,13 +530,13 @@ function query(key, fetcher, options = {}) {
516
530
  if (typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
517
531
  if (refetchOnWindowFocus) {
518
532
  focusHandler = () => {
519
- if (!disposed && currentKey && enabled) doFetch();
533
+ if (!disposed && currentKey) doFetch();
520
534
  };
521
535
  globalThis.addEventListener("focus", focusHandler);
522
536
  }
523
537
  if (refetchOnReconnect) {
524
538
  onlineHandler = () => {
525
- if (!disposed && currentKey && enabled) doFetch();
539
+ if (!disposed && currentKey) doFetch();
526
540
  };
527
541
  globalThis.addEventListener("online", onlineHandler);
528
542
  }
@@ -534,6 +548,7 @@ function query(key, fetcher, options = {}) {
534
548
  stopSelect?.();
535
549
  loading.dispose();
536
550
  isStale.dispose();
551
+ enabledGate?.dispose();
537
552
  if (intervalTimer) clearInterval(intervalTimer);
538
553
  detachFromEntry();
539
554
  if (focusHandler && typeof globalThis.removeEventListener === "function") {
@@ -713,6 +728,8 @@ function infiniteQuery(key, fetcher, options) {
713
728
  onError
714
729
  } = options;
715
730
  const resolveKey = typeof key === "function" ? key : () => key;
731
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
732
+ const isEnabled = enabledGate ?? (() => enabled);
716
733
  const [pages, setPages] = signal([]);
717
734
  const [isFetching, setIsFetching] = signal(false);
718
735
  const [isFetchingNext, setIsFetchingNext] = signal(false);
@@ -791,7 +808,7 @@ function infiniteQuery(key, fetcher, options) {
791
808
  }
792
809
  const effectCleanup = effect(() => {
793
810
  resolveKey();
794
- if (enabled) {
811
+ if (isEnabled()) {
795
812
  abortController?.abort();
796
813
  batch(() => {
797
814
  setPages([]);
@@ -832,6 +849,7 @@ function infiniteQuery(key, fetcher, options) {
832
849
  loading.dispose();
833
850
  hasNextPage.dispose();
834
851
  hasPreviousPage.dispose();
852
+ enabledGate?.dispose();
835
853
  }
836
854
  return {
837
855
  data,
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-7XHATCIH.js";
5
5
  import {
6
6
  reactiveBinding
7
- } from "./chunk-TQQUN4WR.js";
7
+ } from "./chunk-D6HYFOWR.js";
8
8
 
9
9
  // src/core/rendering/createId.ts
10
10
  var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
@@ -9,14 +9,14 @@ import {
9
9
  } from "./chunk-7ZHH77QA.js";
10
10
  import {
11
11
  effect
12
- } from "./chunk-V3LHZSU5.js";
12
+ } from "./chunk-7WIHYHWD.js";
13
13
  import {
14
14
  sanitizeUrl
15
15
  } from "./chunk-EXXSN3BW.js";
16
16
  import {
17
17
  batch,
18
18
  signal
19
- } from "./chunk-DSID757X.js";
19
+ } from "./chunk-FYUEL5IW.js";
20
20
  import {
21
21
  reportError
22
22
  } from "./chunk-NYNYSPK7.js";
@@ -1142,6 +1142,7 @@ function keyboard(options = {}) {
1142
1142
  };
1143
1143
  }
1144
1144
  const target = options.target ?? window;
1145
+ const view = options.target?.ownerDocument?.defaultView ?? window;
1145
1146
  const filter = options.keys ? new Set(options.keys) : null;
1146
1147
  const onDown = (e) => {
1147
1148
  if (filter && !filter.has(e.key)) return;
@@ -1164,14 +1165,14 @@ function keyboard(options = {}) {
1164
1165
  const onBlur = () => setPressed(/* @__PURE__ */ new Set());
1165
1166
  target.addEventListener("keydown", onDown);
1166
1167
  target.addEventListener("keyup", onUp);
1167
- window.addEventListener("blur", onBlur);
1168
+ view.addEventListener("blur", onBlur);
1168
1169
  function isPressed(key) {
1169
1170
  return pressed().has(key);
1170
1171
  }
1171
1172
  function dispose() {
1172
1173
  target.removeEventListener("keydown", onDown);
1173
1174
  target.removeEventListener("keyup", onUp);
1174
- window.removeEventListener("blur", onBlur);
1175
+ view.removeEventListener("blur", onBlur);
1175
1176
  }
1176
1177
  return { pressed, isPressed, dispose };
1177
1178
  }
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  watch
3
- } from "./chunk-CZPRSWSS.js";
3
+ } from "./chunk-EVOK663Z.js";
4
4
  import {
5
5
  createId,
6
6
  domBinding,
7
7
  idSegment
8
- } from "./chunk-C7AA2CZX.js";
8
+ } from "./chunk-GOL3FU5Q.js";
9
9
  import {
10
10
  derived
11
- } from "./chunk-KJ3UKABJ.js";
11
+ } from "./chunk-5PC7OTQW.js";
12
12
  import {
13
13
  stripHtml
14
14
  } from "./chunk-EXXSN3BW.js";
15
15
  import {
16
16
  batch,
17
17
  signal
18
- } from "./chunk-DSID757X.js";
18
+ } from "./chunk-FYUEL5IW.js";
19
19
 
20
20
  // src/widgets/Combobox.ts
21
21
  var boundComboboxes = /* @__PURE__ */ new WeakMap();
@@ -6,13 +6,16 @@ import {
6
6
  } from "./chunk-7ZHH77QA.js";
7
7
  import {
8
8
  effect
9
- } from "./chunk-V3LHZSU5.js";
9
+ } from "./chunk-7WIHYHWD.js";
10
10
  import {
11
11
  sanitizeUrl
12
12
  } from "./chunk-EXXSN3BW.js";
13
13
  import {
14
14
  signal
15
- } from "./chunk-DSID757X.js";
15
+ } from "./chunk-FYUEL5IW.js";
16
+ import {
17
+ bindOwnerScope
18
+ } from "./chunk-D6HYFOWR.js";
16
19
  import {
17
20
  DEV,
18
21
  devWarn,
@@ -785,16 +788,20 @@ function lazyChunk(id, loader, registry, fallback) {
785
788
  registry.load(id, async () => {
786
789
  const mod = await loader();
787
790
  return typeof mod === "function" ? mod : mod.default;
788
- }).then((component) => {
789
- if (disposed) return;
790
- const node = component();
791
- if (disposed) {
792
- dispose(node);
793
- return;
794
- }
795
- clearChildren(container);
796
- container.appendChild(node);
797
- }).catch((err) => {
791
+ }).then(
792
+ // Instantiated after the chunk resolves, in the owner scope of the
793
+ // render that asked for it — as `lazy()` does.
794
+ bindOwnerScope((component) => {
795
+ if (disposed) return;
796
+ const node = component();
797
+ if (disposed) {
798
+ dispose(node);
799
+ return;
800
+ }
801
+ clearChildren(container);
802
+ container.appendChild(node);
803
+ })
804
+ ).catch((err) => {
798
805
  if (disposed) return;
799
806
  clearChildren(container);
800
807
  const errorEl = document.createElement("div");
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  domBinding
3
- } from "./chunk-C7AA2CZX.js";
3
+ } from "./chunk-GOL3FU5Q.js";
4
4
  import {
5
5
  bindAttribute,
6
6
  setSafeAttribute
7
- } from "./chunk-O6TRVMJI.js";
7
+ } from "./chunk-XUQUQJYE.js";
8
8
  import {
9
9
  isBlockedElement
10
10
  } from "./chunk-3ACAAQIN.js";
11
11
  import {
12
12
  derived
13
- } from "./chunk-KJ3UKABJ.js";
13
+ } from "./chunk-5PC7OTQW.js";
14
14
  import {
15
15
  globalSingleton
16
16
  } from "./chunk-7ZHH77QA.js";
@@ -23,11 +23,11 @@ import {
23
23
  } from "./chunk-5HZXGZ6T.js";
24
24
  import {
25
25
  signal
26
- } from "./chunk-DSID757X.js";
26
+ } from "./chunk-FYUEL5IW.js";
27
27
  import {
28
28
  reactiveBinding,
29
29
  track
30
- } from "./chunk-TQQUN4WR.js";
30
+ } from "./chunk-D6HYFOWR.js";
31
31
  import {
32
32
  dispose,
33
33
  disposeNodeOwn,
@@ -1466,7 +1466,7 @@ function svgElement(tag, props = {}, ...nodes) {
1466
1466
  for (const child of nodes) {
1467
1467
  if (typeof child === "string") {
1468
1468
  el.appendChild(document.createTextNode(child));
1469
- } else if (child instanceof Node) {
1469
+ } else if (typeof child?.nodeType === "number") {
1470
1470
  el.appendChild(child);
1471
1471
  }
1472
1472
  }
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-62BDYGAG.js";
5
5
  import {
6
6
  derived
7
- } from "./chunk-KJ3UKABJ.js";
7
+ } from "./chunk-5PC7OTQW.js";
8
8
  import {
9
9
  effect
10
- } from "./chunk-V3LHZSU5.js";
10
+ } from "./chunk-7WIHYHWD.js";
11
11
  import {
12
12
  batch,
13
13
  signal
14
- } from "./chunk-DSID757X.js";
14
+ } from "./chunk-FYUEL5IW.js";
15
15
  import {
16
16
  DEV,
17
17
  devWarn,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SVG_NS,
3
3
  tagFactory
4
- } from "./chunk-VWT3VXPL.js";
4
+ } from "./chunk-EVI4ZQO3.js";
5
5
 
6
6
  // src/core/rendering/html.ts
7
7
  var html = tagFactory("html");
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5HZXGZ6T.js";
4
4
  import {
5
5
  signal
6
- } from "./chunk-DSID757X.js";
6
+ } from "./chunk-FYUEL5IW.js";
7
7
  import {
8
8
  registerDisposer,
9
9
  reportError
@@ -3,23 +3,23 @@ import {
3
3
  } from "./chunk-J6FW5TV6.js";
4
4
  import {
5
5
  tagFactory
6
- } from "./chunk-VWT3VXPL.js";
6
+ } from "./chunk-EVI4ZQO3.js";
7
7
  import {
8
8
  derived
9
- } from "./chunk-KJ3UKABJ.js";
9
+ } from "./chunk-5PC7OTQW.js";
10
10
  import {
11
11
  globalSingleton
12
12
  } from "./chunk-7ZHH77QA.js";
13
13
  import {
14
14
  effect
15
- } from "./chunk-V3LHZSU5.js";
15
+ } from "./chunk-7WIHYHWD.js";
16
16
  import {
17
17
  sanitizeCSSDeclaration
18
18
  } from "./chunk-EXXSN3BW.js";
19
19
  import {
20
20
  batch,
21
21
  signal
22
- } from "./chunk-DSID757X.js";
22
+ } from "./chunk-FYUEL5IW.js";
23
23
 
24
24
  // src/ecosystem/adapters/mobx.ts
25
25
  function mobXAdapter(options) {
@@ -10,7 +10,7 @@ import {
10
10
  } from "./chunk-EXXSN3BW.js";
11
11
  import {
12
12
  reactiveBinding
13
- } from "./chunk-TQQUN4WR.js";
13
+ } from "./chunk-D6HYFOWR.js";
14
14
  import {
15
15
  DEV,
16
16
  devWarn,
package/dist/data.cjs CHANGED
@@ -313,6 +313,24 @@ function untracked(fn) {
313
313
  resumeTracking();
314
314
  }
315
315
  }
316
+ var currentOwnerScope = null;
317
+ function getOwnerScope() {
318
+ return currentOwnerScope;
319
+ }
320
+ function runWithOwnerScope(scope, fn) {
321
+ const prev = currentOwnerScope;
322
+ currentOwnerScope = scope;
323
+ try {
324
+ return fn();
325
+ } finally {
326
+ currentOwnerScope = prev;
327
+ }
328
+ }
329
+ function bindOwnerScope(fn) {
330
+ const scope = currentOwnerScope;
331
+ if (scope === null) return fn;
332
+ return (...args) => runWithOwnerScope(scope, () => fn(...args));
333
+ }
316
334
  var subscriberEpochCounter = 0;
317
335
  function retrack(effectFn, subscriber) {
318
336
  const prev = currentSubscriber;
@@ -328,6 +346,10 @@ function retrack(effectFn, subscriber) {
328
346
  currentSubscriber = subscriber;
329
347
  const sub = subscriber;
330
348
  if (sub._cap === void 0) sub._cap = currentDisposerCapture();
349
+ const prevScope = currentOwnerScope;
350
+ if (prevScope !== null && !sub._epoch && sub._scope === void 0) sub._scope = prevScope;
351
+ const scope = sub._scope === void 0 ? null : sub._scope;
352
+ if (scope !== prevScope) currentOwnerScope = scope;
331
353
  const epoch = ++subscriberEpochCounter;
332
354
  sub._epoch = epoch;
333
355
  sub._structDirty = false;
@@ -340,6 +362,7 @@ function retrack(effectFn, subscriber) {
340
362
  effectFn();
341
363
  } finally {
342
364
  currentSubscriber = prev;
365
+ currentOwnerScope = prevScope;
343
366
  if (savedDepth !== 0) {
344
367
  suspendDepth = savedDepth;
345
368
  suspendSavedSub = savedSuspendSub;
@@ -374,23 +397,26 @@ function track(effectFn, subscriber) {
374
397
  trackingSuspended = false;
375
398
  }
376
399
  currentSubscriber = subscriber;
400
+ const sub = subscriber;
401
+ if (sub._scope === void 0) sub._scope = currentOwnerScope;
402
+ const prevScope = currentOwnerScope;
403
+ currentOwnerScope = sub._scope;
377
404
  try {
378
405
  effectFn();
379
406
  } finally {
380
407
  currentSubscriber = prev;
408
+ currentOwnerScope = prevScope;
381
409
  if (savedDepth !== 0) {
382
410
  suspendDepth = savedDepth;
383
411
  suspendSavedSub = savedSuspendSub;
384
412
  trackingSuspended = true;
385
413
  }
386
- const sub2 = subscriber;
387
- for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
414
+ for (let n = sub.depsHead ?? null; n !== null; n = n.subNext) {
388
415
  const sig = n.sig;
389
416
  sig.__activeNode = n.prevActive;
390
417
  n.prevActive = null;
391
418
  }
392
419
  }
393
- const sub = subscriber;
394
420
  return sub._dispose ?? (sub._dispose = () => cleanup(subscriber));
395
421
  }
396
422
  function reactiveBinding(commit, ownerNode) {
@@ -660,7 +686,7 @@ function forEachSubscriber(signal2, visit) {
660
686
  }
661
687
 
662
688
  // src/reactivity/track.ts
663
- var _runtimeVersion = true ? "4.8.0" : "dev";
689
+ var _runtimeVersion = true ? "4.10.0" : "dev";
664
690
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
665
691
  function resolveReactiveApi() {
666
692
  const g = globalThis;
@@ -692,6 +718,9 @@ function resolveReactiveApi() {
692
718
  getSubscriberCount,
693
719
  getSubscriberDeps,
694
720
  forEachSubscriber,
721
+ getOwnerScope,
722
+ runWithOwnerScope,
723
+ bindOwnerScope,
695
724
  version: _runtimeVersion
696
725
  };
697
726
  g[REGISTRY_KEY] = local;
@@ -715,6 +744,9 @@ var notifySubscribers2 = API.notifySubscribers;
715
744
  var getSubscriberCount2 = API.getSubscriberCount;
716
745
  var getSubscriberDeps2 = API.getSubscriberDeps;
717
746
  var forEachSubscriber2 = API.forEachSubscriber;
747
+ var getOwnerScope2 = API.getOwnerScope ?? getOwnerScope;
748
+ var runWithOwnerScope2 = API.runWithOwnerScope ?? runWithOwnerScope;
749
+ var bindOwnerScope2 = API.bindOwnerScope ?? bindOwnerScope;
718
750
 
719
751
  // src/core/devtoolsHook.ts
720
752
  function emitDevtools(hook, event, payload) {
@@ -891,6 +923,11 @@ function flushUserCleanups(ctx) {
891
923
  const list = ctx.userCleanups;
892
924
  if (list.length === 0) return;
893
925
  ctx.userCleanups = [];
926
+ const scope = ctx.subscriber._scope ?? null;
927
+ if (scope === getOwnerScope2()) runCleanups(list);
928
+ else runWithOwnerScope2(scope, () => runCleanups(list));
929
+ }
930
+ function runCleanups(list) {
894
931
  for (let i = list.length - 1; i >= 0; i--) {
895
932
  try {
896
933
  list[i]();
@@ -1384,6 +1421,8 @@ function query(key, fetcher, options = {}) {
1384
1421
  structuralSharing = true
1385
1422
  } = options;
1386
1423
  const resolveKey = typeof key === "function" ? key : () => key;
1424
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
1425
+ const isEnabled = enabledGate ?? (() => Boolean(enabled));
1387
1426
  const cache = getActiveQueryCache();
1388
1427
  const [data, setData] = signal(initialData);
1389
1428
  const [isFetching, setIsFetching] = signal(false);
@@ -1402,6 +1441,7 @@ function query(key, fetcher, options = {}) {
1402
1441
  let currentKey = null;
1403
1442
  let attachedEntry = null;
1404
1443
  let attachedKey = null;
1444
+ let lastEnabled = null;
1405
1445
  let intervalTimer = null;
1406
1446
  const loading = derived(() => isFetching() && data() === void 0);
1407
1447
  const isStale = derived(() => {
@@ -1498,7 +1538,7 @@ function query(key, fetcher, options = {}) {
1498
1538
  }
1499
1539
  }
1500
1540
  async function doFetch() {
1501
- if (disposed || !currentKey || !enabled) return;
1541
+ if (disposed || !currentKey || !untracked2(isEnabled)) return;
1502
1542
  const key2 = currentKey;
1503
1543
  const entry = getOrCreateEntry(cache, key2);
1504
1544
  attachToEntry(entry, key2);
@@ -1600,10 +1640,20 @@ function query(key, fetcher, options = {}) {
1600
1640
  }
1601
1641
  const effectCleanup = effect(() => {
1602
1642
  const key2 = resolveKey();
1643
+ const on = isEnabled();
1603
1644
  const keyChanged = currentKey !== key2;
1645
+ const enabledRose = on && lastEnabled === false;
1604
1646
  currentKey = key2;
1647
+ lastEnabled = on;
1648
+ if (key2 === "") {
1649
+ detachFromEntry();
1650
+ setIsFetching(false);
1651
+ return;
1652
+ }
1605
1653
  const entry = getOrCreateEntry(cache, key2, initialData);
1654
+ const reattached = attachedEntry !== entry;
1606
1655
  attachToEntry(entry, key2);
1656
+ if (keyChanged) setIsFetching(entry.promise !== null);
1607
1657
  if (entry.data !== void 0) {
1608
1658
  const view = viewOf(entry);
1609
1659
  batch(() => {
@@ -1612,19 +1662,20 @@ function query(key, fetcher, options = {}) {
1612
1662
  setUpdatedAt(entry.dataUpdatedAt);
1613
1663
  });
1614
1664
  }
1615
- if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
1665
+ if (!keyChanged && !reattached && !enabledRose) return;
1666
+ if (!keyChanged && entry.data !== void 0) {
1616
1667
  const isDataStale2 = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
1617
- if (enabled && isDataStale2 && !entry.promise) doFetch();
1668
+ if (on && isDataStale2 && !entry.promise) doFetch();
1618
1669
  return;
1619
1670
  }
1620
1671
  const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
1621
- if (enabled && (entry.data === void 0 || isDataStale)) {
1672
+ if (on && (entry.data === void 0 || isDataStale)) {
1622
1673
  doFetch();
1623
1674
  }
1624
1675
  });
1625
1676
  if (refetchInterval && refetchInterval > 0) {
1626
1677
  intervalTimer = setInterval(() => {
1627
- if (!disposed && currentKey && enabled) doFetch();
1678
+ if (!disposed && currentKey) doFetch();
1628
1679
  }, refetchInterval);
1629
1680
  }
1630
1681
  let focusHandler = null;
@@ -1632,13 +1683,13 @@ function query(key, fetcher, options = {}) {
1632
1683
  if (typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
1633
1684
  if (refetchOnWindowFocus) {
1634
1685
  focusHandler = () => {
1635
- if (!disposed && currentKey && enabled) doFetch();
1686
+ if (!disposed && currentKey) doFetch();
1636
1687
  };
1637
1688
  globalThis.addEventListener("focus", focusHandler);
1638
1689
  }
1639
1690
  if (refetchOnReconnect) {
1640
1691
  onlineHandler = () => {
1641
- if (!disposed && currentKey && enabled) doFetch();
1692
+ if (!disposed && currentKey) doFetch();
1642
1693
  };
1643
1694
  globalThis.addEventListener("online", onlineHandler);
1644
1695
  }
@@ -1650,6 +1701,7 @@ function query(key, fetcher, options = {}) {
1650
1701
  stopSelect?.();
1651
1702
  loading.dispose();
1652
1703
  isStale.dispose();
1704
+ enabledGate?.dispose();
1653
1705
  if (intervalTimer) clearInterval(intervalTimer);
1654
1706
  detachFromEntry();
1655
1707
  if (focusHandler && typeof globalThis.removeEventListener === "function") {
@@ -1829,6 +1881,8 @@ function infiniteQuery(key, fetcher, options) {
1829
1881
  onError
1830
1882
  } = options;
1831
1883
  const resolveKey = typeof key === "function" ? key : () => key;
1884
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
1885
+ const isEnabled = enabledGate ?? (() => enabled);
1832
1886
  const [pages, setPages] = signal([]);
1833
1887
  const [isFetching, setIsFetching] = signal(false);
1834
1888
  const [isFetchingNext, setIsFetchingNext] = signal(false);
@@ -1907,7 +1961,7 @@ function infiniteQuery(key, fetcher, options) {
1907
1961
  }
1908
1962
  const effectCleanup = effect(() => {
1909
1963
  resolveKey();
1910
- if (enabled) {
1964
+ if (isEnabled()) {
1911
1965
  abortController?.abort();
1912
1966
  batch(() => {
1913
1967
  setPages([]);
@@ -1948,6 +2002,7 @@ function infiniteQuery(key, fetcher, options) {
1948
2002
  loading.dispose();
1949
2003
  hasNextPage.dispose();
1950
2004
  hasPreviousPage.dispose();
2005
+ enabledGate?.dispose();
1951
2006
  }
1952
2007
  return {
1953
2008
  data,