sibujs 4.3.0 → 4.5.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 (77) hide show
  1. package/README.md +34 -4
  2. package/dist/browser.cjs +31 -2
  3. package/dist/browser.d.cts +15 -2
  4. package/dist/browser.d.ts +15 -2
  5. package/dist/browser.js +4 -4
  6. package/dist/build.cjs +92 -13
  7. package/dist/build.js +10 -10
  8. package/dist/cdn.dev.global.js +10 -10
  9. package/dist/cdn.full.dev.global.js +400 -0
  10. package/dist/cdn.full.global.js +398 -0
  11. package/dist/cdn.global.js +10 -10
  12. package/dist/{chunk-GZYQNIPS.js → chunk-2DCGACUU.js} +16 -9
  13. package/dist/{chunk-7BPN4MXR.js → chunk-3JZ4L5TJ.js} +10 -4
  14. package/dist/{chunk-R4EF7V3K.js → chunk-4PMLNECI.js} +4 -4
  15. package/dist/{chunk-IYHM4FWD.js → chunk-7LN645I6.js} +1 -1
  16. package/dist/{chunk-RE6KLGMV.js → chunk-B3WHI2QA.js} +1 -1
  17. package/dist/{chunk-ZVYNIUOG.js → chunk-FTIR4QW2.js} +13 -3
  18. package/dist/{chunk-G7GPNB6N.js → chunk-GW3SCCZG.js} +4 -4
  19. package/dist/{chunk-XGCZ45NH.js → chunk-KEISJXBU.js} +2 -2
  20. package/dist/{chunk-UD6YE2GW.js → chunk-OMJJM3KM.js} +2 -2
  21. package/dist/{chunk-7UBG6LDP.js → chunk-ONOHFDLG.js} +9 -1
  22. package/dist/{chunk-7UK6BSAT.js → chunk-PCT43HW3.js} +1 -1
  23. package/dist/{chunk-VJE6DDYM.js → chunk-R25EFXXC.js} +40 -26
  24. package/dist/{chunk-3E5YNK2F.js → chunk-RBTPLM32.js} +46 -8
  25. package/dist/{chunk-7BJLKDBI.js → chunk-RIXRAYIU.js} +1 -1
  26. package/dist/{chunk-7GQIRV27.js → chunk-RJE2BNI4.js} +3 -3
  27. package/dist/{chunk-2LSY4WDM.js → chunk-S373NSMK.js} +18 -13
  28. package/dist/{chunk-AAHT6AKT.js → chunk-TBYTO6BS.js} +2 -2
  29. package/dist/{chunk-TSL64O5L.js → chunk-UGRX3S57.js} +31 -2
  30. package/dist/{chunk-L4B3Y3OM.js → chunk-VUF4ALSW.js} +1 -1
  31. package/dist/{chunk-USS5ENJ2.js → chunk-VZKNK2V7.js} +9 -4
  32. package/dist/{chunk-MYA5HEK5.js → chunk-XZZOBQAY.js} +1 -1
  33. package/dist/{contracts-Hg6ITAEF.d.cts → contracts-DBdg9J_a.d.cts} +25 -4
  34. package/dist/{contracts-Hg6ITAEF.d.ts → contracts-DBdg9J_a.d.ts} +25 -4
  35. package/dist/{customElement-CNZxEB9G.d.ts → customElement-OB9CIsc5.d.cts} +38 -10
  36. package/dist/{customElement-CNZxEB9G.d.cts → customElement-OB9CIsc5.d.ts} +38 -10
  37. package/dist/data.cjs +81 -9
  38. package/dist/data.js +6 -6
  39. package/dist/devtools.cjs +41 -2
  40. package/dist/devtools.js +4 -4
  41. package/dist/ecosystem.cjs +83 -9
  42. package/dist/ecosystem.d.cts +13 -5
  43. package/dist/ecosystem.d.ts +13 -5
  44. package/dist/ecosystem.js +7 -7
  45. package/dist/extras.cjs +150 -40
  46. package/dist/extras.d.cts +3 -3
  47. package/dist/extras.d.ts +3 -3
  48. package/dist/extras.js +20 -20
  49. package/dist/index.cjs +92 -13
  50. package/dist/index.d.cts +24 -151
  51. package/dist/index.d.ts +24 -151
  52. package/dist/index.js +10 -10
  53. package/dist/motion.cjs +31 -2
  54. package/dist/motion.js +3 -3
  55. package/dist/patterns.cjs +116 -36
  56. package/dist/patterns.d.cts +6 -1
  57. package/dist/patterns.d.ts +6 -1
  58. package/dist/patterns.js +6 -6
  59. package/dist/performance.cjs +31 -2
  60. package/dist/performance.js +4 -4
  61. package/dist/plugins.cjs +39 -2
  62. package/dist/plugins.js +6 -6
  63. package/dist/ssr.cjs +39 -2
  64. package/dist/ssr.js +7 -7
  65. package/dist/tagFactory-DVoDpHye.d.cts +215 -0
  66. package/dist/tagFactory-DVoDpHye.d.ts +215 -0
  67. package/dist/testing.cjs +31 -2
  68. package/dist/testing.js +2 -2
  69. package/dist/ui.cjs +128 -39
  70. package/dist/ui.d.cts +2 -2
  71. package/dist/ui.d.ts +2 -2
  72. package/dist/ui.js +7 -7
  73. package/dist/widgets.cjs +75 -9
  74. package/dist/widgets.js +6 -6
  75. package/package.json +8 -2
  76. package/dist/tagFactory-Bzupt4Pj.d.cts +0 -55
  77. package/dist/tagFactory-Bzupt4Pj.d.ts +0 -55
package/dist/extras.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { ConflictStrategy, InfiniteQueryOptions, InfiniteQueryResult, LoaderRoute, MutationOptions, MutationResult, OfflineStore, OfflineStoreOptions, QueryOptions, QueryResult, Resource, ResourceOptions, RetryOptions, RouteLoaderFn, SyncAdapter, SyncChange, SyncConflict, SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, resource, setQueryData, socket, stream, syncAdapter, throttle, withRetry } from './data.js';
2
2
  export { AnimationFrameOptions, BoundsRect, GamepadSnapshot, ImageLoaderState, KeyboardOptions, MouseOptions, MutationObserverOptions, SpeakOptions, SwipeDirection, SwipeOptions, TextSelectionState, UrlStateOptions, animationFrame, battery, bounds, broadcast, clipboard, colorScheme, draggable, dropZone, favicon, formatCurrency, formatNumber, fullscreen, gamepad, geo, idle, imageLoader, keyboard, media, mouse, mutationObserver, network, online, permissions, pointerLock, resize, scroll, speech, svgFavicon, swipe, textSelection, title, urlState, vibrate, visibility, wakeLock, windowSize } from './browser.js';
3
3
  export { GlobalStore, MachineConfig, MachineReturn, Middleware, PersistOptions, Selector, StoreActionMap, TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline } from './patterns.js';
4
- export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-Hg6ITAEF.js';
4
+ export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-DBdg9J_a.js';
5
5
  export { AnimationPreset, PresetOptions, SlideDirection, SpringOptions, TransitionGroup, TransitionGroupOptions, TransitionOptions, animate, bounceIn, bounceOut, fadeIn, fadeOut, flipIn, prefersReducedMotion, pulse, reducedMotion, scaleDown, scaleUp, sequence, shake, slideIn, slideOut, spring, springSignal, stagger, transition, viewTransition } from './motion.js';
6
- export { A as AttributeSource, a as AttributeValue, B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, b as FocusTrap, c as FormConfig, d as FormField, e as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, f as ToastInstance, V as ValidatorFn, g as VirtualList, h as VirtualListProps, _ as __resetDialogStack, i as announce, j as aria, k as bindAttrs, l as bindBoolAttr, m as bindData, n as bindField, o as creditCardMask, p as custom, q as dateMask, r as defineElement, s as dialog, t as email, u as eventBus, v as focus, w as form, x as hotkey, y as infiniteScroll, z as inputMask, D as intersection, E as lazyLoad, G as matchesPattern, H as max, J as maxLength, K as min, L as minLength, N as pagination, O as phoneMask, P as removeScopedStyle, Q as required, R as scopedStyle, S as ssnMask, U as svgElement, W as timeMask, X as toast, Y as withScopedStyle, Z as zipMask } from './customElement-CNZxEB9G.js';
6
+ export { A as AttributeSource, a as AttributeValue, B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, b as FocusTrap, c as FormConfig, d as FormField, e as FormReturn, I as IntersectionResult, M as MaskOptions, P as PaginationResult, T as Toast, f as ToastInstance, V as ValidatorFn, g as VirtualList, h as VirtualListProps, _ as __resetDialogStack, i as announce, j as aria, k as bindAttrs, l as bindBoolAttr, m as bindData, n as bindField, o as creditCardMask, p as custom, q as dateMask, r as defineElement, s as dialog, t as email, u as eventBus, v as focus, w as form, x as hotkey, y as infiniteScroll, z as inputMask, D as intersection, E as lazyLoad, G as matchesPattern, H as max, J as maxLength, K as min, L as minLength, N as pagination, O as phoneMask, Q as removeScopedStyle, R as required, S as scopedStyle, U as ssnMask, W as svgElement, X as timeMask, Y as toast, Z as withScopedStyle, $ as zipMask } from './customElement-OB9CIsc5.js';
7
7
  export { ChunkConfig, DOMPool, Features, NormalizeResult, NormalizedEntities, NormalizedSchema, NormalizedState, NormalizedStoreActions, Priority, PriorityLevel, block, cloneTemplate, conditional, createChunkRegistry, deferredValue, denormalize, devOnly, flushScheduler, getDOMPool, hoistable, lazyChunk, noSideEffect, normalize, normalizedStore, pendingTasks, precompile, prefetch, preloadImage, preloadModule, preloadModules, preloadResource, processInChunks, pure, resetIdCounter, scheduleUpdate, setIdPrefix, startTransition, staticTemplate, transitionState, uniqueId, yieldToMain } from './performance.js';
8
8
  export { ActionFn, ActionResult, Head, ISROptions, LoadRemoteModuleOptions, LoadWasmOptions, MicroApp, MicroAppConfig, MiddlewareFn, SSGOptions, SSGResult, ScrollRestorationOptions, ServiceWorkerState, SharedScope, UseWorkerFnReturn, UseWorkerReturn, WasmConfig, WasmModuleState, WorkerPool, clearWasmCache, composeMiddleware, createAction, createISR, createMicroApp, createMiddlewareChain, createSharedScope, createWasmBridge, createWorkerPool, defineRemoteComponent, generateStaticSite, isWasmCached, loadRemoteModule, loadWasmModule, loadWasmModuleWithOptions, preloadWasm, scrollRestoration, serviceWorker, setCanonical, setStructuredData, wasm, worker, workerFn } from './ssr.js';
9
9
  export { H as HydrateOptions, a as HydrationMismatch, T as TrustedHTML, c as collectStream, d as deserializeState, e as escapeScriptJson, h as hydrate, b as hydrateIslands, f as hydrateProgressively, i as isDangerousMetaRefresh, g as island, r as renderToDocument, j as renderToReadableStream, k as renderToStream, l as renderToString, m as renderToSuspenseStream, n as resetSSRState, s as serializeState, o as ssrSuspense, p as suspenseSwapScript, t as trustHTML } from './ssr-BiPRdZ6n.js';
@@ -13,4 +13,4 @@ export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R
13
13
  export { AccordionAriaBinding, AccordionOptions, ComboboxOptions, DatePickerOptions, FileUploadOptions, SelectOptions, SetContentOptions, TabsAriaBinding, TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip } from './widgets.js';
14
14
  export { AdaptedComponent, AdaptedComponentProps, AdapterConfig, ComponentMapping, MobXAdapterAPI, MobXAdapterOptions, MobXReactionDisposer, ReduxAdapterAPI, ReduxAdapterOptions, ReduxStore, ThemeAPI, ThemeConfig, ZustandAdapterAPI, ZustandAdapterOptions, ZustandStore, antdAdapter, chakraAdapter, componentAdapter, createTheme, materialAdapter, mobXAdapter, reduxAdapter, zustandAdapter } from './ecosystem.js';
15
15
  import './signal-BnWpq6WB.js';
16
- import './tagFactory-Bzupt4Pj.js';
16
+ import './tagFactory-DVoDpHye.js';
package/dist/extras.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  optimisticList,
6
6
  persisted,
7
7
  timeline
8
- } from "./chunk-USS5ENJ2.js";
8
+ } from "./chunk-VZKNK2V7.js";
9
9
  import {
10
10
  DOMPool,
11
11
  Features,
@@ -41,7 +41,7 @@ import {
41
41
  transitionState,
42
42
  uniqueId,
43
43
  yieldToMain
44
- } from "./chunk-AAHT6AKT.js";
44
+ } from "./chunk-TBYTO6BS.js";
45
45
  import {
46
46
  VERSION,
47
47
  bundlerMetadata,
@@ -88,7 +88,7 @@ import {
88
88
  wasm,
89
89
  worker,
90
90
  workerFn
91
- } from "./chunk-7GQIRV27.js";
91
+ } from "./chunk-RJE2BNI4.js";
92
92
  import {
93
93
  FocusTrap,
94
94
  VirtualList,
@@ -129,7 +129,7 @@ import {
129
129
  toast,
130
130
  withScopedStyle,
131
131
  zipMask
132
- } from "./chunk-GZYQNIPS.js";
132
+ } from "./chunk-2DCGACUU.js";
133
133
  import {
134
134
  RenderProp,
135
135
  assertType,
@@ -145,7 +145,7 @@ import {
145
145
  withDefaults,
146
146
  withProps,
147
147
  withWrapper
148
- } from "./chunk-VJE6DDYM.js";
148
+ } from "./chunk-R25EFXXC.js";
149
149
  import {
150
150
  accordion,
151
151
  combobox,
@@ -156,7 +156,7 @@ import {
156
156
  select,
157
157
  tabs,
158
158
  tooltip
159
- } from "./chunk-G7GPNB6N.js";
159
+ } from "./chunk-GW3SCCZG.js";
160
160
  import {
161
161
  animationFrame,
162
162
  battery,
@@ -194,7 +194,7 @@ import {
194
194
  visibility,
195
195
  wakeLock,
196
196
  windowSize
197
- } from "./chunk-UD6YE2GW.js";
197
+ } from "./chunk-OMJJM3KM.js";
198
198
  import "./chunk-H3SRKIYX.js";
199
199
  import "./chunk-52XFPGSN.js";
200
200
  import {
@@ -219,7 +219,7 @@ import {
219
219
  syncAdapter,
220
220
  throttle,
221
221
  withRetry
222
- } from "./chunk-7BPN4MXR.js";
222
+ } from "./chunk-3JZ4L5TJ.js";
223
223
  import {
224
224
  SibuError,
225
225
  checkLeaks,
@@ -257,7 +257,7 @@ import {
257
257
  trackCleanup,
258
258
  walkDependencyGraph,
259
259
  withErrorTracking
260
- } from "./chunk-ZVYNIUOG.js";
260
+ } from "./chunk-FTIR4QW2.js";
261
261
  import {
262
262
  antdAdapter,
263
263
  chakraAdapter,
@@ -267,7 +267,7 @@ import {
267
267
  mobXAdapter,
268
268
  reduxAdapter,
269
269
  zustandAdapter
270
- } from "./chunk-R4EF7V3K.js";
270
+ } from "./chunk-4PMLNECI.js";
271
271
  import {
272
272
  createPlugin,
273
273
  createPluginRegistry,
@@ -279,7 +279,7 @@ import {
279
279
  triggerPluginMount,
280
280
  triggerPluginUnmount
281
281
  } from "./chunk-WWV3SJ3L.js";
282
- import "./chunk-7UK6BSAT.js";
282
+ import "./chunk-PCT43HW3.js";
283
283
  import {
284
284
  collectStream,
285
285
  deserializeState,
@@ -300,15 +300,15 @@ import {
300
300
  suspenseSwapScript,
301
301
  trustHTML
302
302
  } from "./chunk-NIOYEGBQ.js";
303
- import "./chunk-IYHM4FWD.js";
303
+ import "./chunk-7LN645I6.js";
304
304
  import "./chunk-CCSJMTRN.js";
305
- import "./chunk-L4B3Y3OM.js";
306
- import "./chunk-XGCZ45NH.js";
307
- import "./chunk-7UBG6LDP.js";
308
- import "./chunk-3E5YNK2F.js";
305
+ import "./chunk-VUF4ALSW.js";
306
+ import "./chunk-KEISJXBU.js";
307
+ import "./chunk-ONOHFDLG.js";
308
+ import "./chunk-RBTPLM32.js";
309
309
  import "./chunk-IXKSNWV5.js";
310
310
  import "./chunk-7ZHH77QA.js";
311
- import "./chunk-7BJLKDBI.js";
311
+ import "./chunk-RIXRAYIU.js";
312
312
  import "./chunk-5DXA2J44.js";
313
313
  import {
314
314
  TransitionGroup,
@@ -332,10 +332,10 @@ import {
332
332
  stagger,
333
333
  transition,
334
334
  viewTransition
335
- } from "./chunk-RE6KLGMV.js";
335
+ } from "./chunk-B3WHI2QA.js";
336
336
  import "./chunk-QKRPLZ2V.js";
337
- import "./chunk-MYA5HEK5.js";
338
- import "./chunk-TSL64O5L.js";
337
+ import "./chunk-XZZOBQAY.js";
338
+ import "./chunk-UGRX3S57.js";
339
339
  import "./chunk-2WLZ6757.js";
340
340
  export {
341
341
  DOMPool,
package/dist/index.cjs CHANGED
@@ -729,6 +729,14 @@ function setSafeAttribute(el, name, value, options = {}) {
729
729
  const html3 = isHtmlElement(el);
730
730
  const idlName = html3 ? name.toLowerCase() : name;
731
731
  if (typeof value === "boolean") {
732
+ if (name.length > 5 && name.slice(0, 5).toLowerCase() === "aria-") {
733
+ const token = value ? "true" : "false";
734
+ if ((ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name)) !== token) {
735
+ if (ns) el.setAttributeNS(ns, name, token);
736
+ else el.setAttribute(name, token);
737
+ }
738
+ return true;
739
+ }
732
740
  if (html3 && BOOLEAN_IDL_ATTRS.has(idlName) && idlName in el) {
733
741
  setProp(el, idlName, value);
734
742
  } else if (value) {
@@ -901,6 +909,15 @@ function untracked(fn) {
901
909
  var subscriberEpochCounter = 0;
902
910
  function retrack(effectFn, subscriber) {
903
911
  const prev = currentSubscriber;
912
+ let savedDepth = 0;
913
+ let savedSuspendSub = null;
914
+ if (trackingSuspended) {
915
+ savedDepth = suspendDepth;
916
+ savedSuspendSub = suspendSavedSub;
917
+ suspendDepth = 0;
918
+ suspendSavedSub = null;
919
+ trackingSuspended = false;
920
+ }
904
921
  currentSubscriber = subscriber;
905
922
  const sub2 = subscriber;
906
923
  const epoch = ++subscriberEpochCounter;
@@ -915,6 +932,11 @@ function retrack(effectFn, subscriber) {
915
932
  effectFn();
916
933
  } finally {
917
934
  currentSubscriber = prev;
935
+ if (savedDepth !== 0) {
936
+ suspendDepth = savedDepth;
937
+ suspendSavedSub = savedSuspendSub;
938
+ trackingSuspended = true;
939
+ }
918
940
  let node = sub2.depsHead ?? null;
919
941
  while (node !== null) {
920
942
  const next = node.subNext;
@@ -934,11 +956,25 @@ function track(effectFn, subscriber) {
934
956
  if (!subscriber) return reactiveBinding(effectFn);
935
957
  cleanup(subscriber);
936
958
  const prev = currentSubscriber;
959
+ let savedDepth = 0;
960
+ let savedSuspendSub = null;
961
+ if (trackingSuspended) {
962
+ savedDepth = suspendDepth;
963
+ savedSuspendSub = suspendSavedSub;
964
+ suspendDepth = 0;
965
+ suspendSavedSub = null;
966
+ trackingSuspended = false;
967
+ }
937
968
  currentSubscriber = subscriber;
938
969
  try {
939
970
  effectFn();
940
971
  } finally {
941
972
  currentSubscriber = prev;
973
+ if (savedDepth !== 0) {
974
+ suspendDepth = savedDepth;
975
+ suspendSavedSub = savedSuspendSub;
976
+ trackingSuspended = true;
977
+ }
942
978
  const sub3 = subscriber;
943
979
  for (let n = sub3.depsHead ?? null; n !== null; n = n.subNext) {
944
980
  const sig = n.sig;
@@ -1109,8 +1145,9 @@ function propagateDirty(sub2) {
1109
1145
  if (s2._c) {
1110
1146
  const nSig = s2._sig;
1111
1147
  if (nSig) {
1112
- if (!nSig._d) {
1148
+ if (!nSig._d || nSig._f === true) {
1113
1149
  nSig._d = true;
1150
+ nSig._f = false;
1114
1151
  stack.push(nSig);
1115
1152
  }
1116
1153
  } else {
@@ -1210,7 +1247,7 @@ function forEachSubscriber(signal2, visit) {
1210
1247
  }
1211
1248
 
1212
1249
  // src/reactivity/track.ts
1213
- var _runtimeVersion = true ? "4.3.0" : "dev";
1250
+ var _runtimeVersion = true ? "4.5.0" : "dev";
1214
1251
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1215
1252
  function resolveReactiveApi() {
1216
1253
  const g2 = globalThis;
@@ -3612,7 +3649,7 @@ function show(condition, element) {
3612
3649
  const update = () => {
3613
3650
  resolved.style.display = condition() ? "" : "none";
3614
3651
  };
3615
- registerDisposer(resolved, track2(update));
3652
+ registerDisposer(resolved, reactiveBinding2(update, resolved));
3616
3653
  return resolved;
3617
3654
  }
3618
3655
  function attachBranch(parent, anchor, branch, attachedOnce, where) {
@@ -3657,7 +3694,7 @@ function when(condition, thenBranch, elseBranch) {
3657
3694
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "when");
3658
3695
  initialized = true;
3659
3696
  };
3660
- registerDisposer(anchor, track2(update));
3697
+ registerDisposer(anchor, reactiveBinding2(update, anchor));
3661
3698
  if (!initialized) {
3662
3699
  queueMicrotask(() => {
3663
3700
  if (!initialized && anchor.parentNode) update();
@@ -3691,7 +3728,7 @@ function match(value, cases, fallback) {
3691
3728
  restoreFocusWithin(focused, currentNode ? [currentNode] : [], "match");
3692
3729
  initialized = true;
3693
3730
  };
3694
- registerDisposer(anchor, track2(update));
3731
+ registerDisposer(anchor, reactiveBinding2(update, anchor));
3695
3732
  if (!initialized) {
3696
3733
  queueMicrotask(() => {
3697
3734
  if (!initialized && anchor.parentNode) update();
@@ -3846,7 +3883,12 @@ function each(getArray, render, options) {
3846
3883
  const [indexGetter, setIndex] = signal(i2);
3847
3884
  let node;
3848
3885
  try {
3849
- node = resolveNodeChild(render(itemGetter, indexGetter));
3886
+ suspendTracking2();
3887
+ try {
3888
+ node = resolveNodeChild(render(itemGetter, indexGetter));
3889
+ } finally {
3890
+ resumeTracking2();
3891
+ }
3850
3892
  } catch (err) {
3851
3893
  const key2 = newKeys[i2];
3852
3894
  node = document.createComment(`each:error:${i2}`);
@@ -4889,10 +4931,14 @@ function derived(getter, options) {
4889
4931
  const cs = {};
4890
4932
  cs._d = false;
4891
4933
  cs._init = false;
4934
+ cs._f = false;
4892
4935
  cs._g = getter;
4893
4936
  cs.__v = 0;
4937
+ let evaluating = false;
4938
+ let disposed = false;
4939
+ let pendingError;
4894
4940
  const markDirty = () => {
4895
- if (cs._d) return;
4941
+ if (cs._d || disposed) return;
4896
4942
  cs._d = true;
4897
4943
  };
4898
4944
  markDirty._c = 1;
@@ -4915,33 +4961,53 @@ function derived(getter, options) {
4915
4961
  }
4916
4962
  }, markDirty);
4917
4963
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
4918
- let evaluating = false;
4919
4964
  const validate = () => {
4920
- if (!cs._d) return;
4965
+ if (!cs._d || disposed || pendingError !== void 0) return;
4921
4966
  const oldValue = cs._v;
4922
4967
  evaluating = true;
4923
4968
  try {
4924
4969
  retrack2(recompute, markDirty);
4925
4970
  if (!Object.is(oldValue, cs._v)) cs.__v++;
4971
+ } catch (err) {
4972
+ pendingError = { error: err };
4973
+ cs.__v++;
4974
+ if (disposed) cs._d = true;
4975
+ else cs._f = true;
4926
4976
  } finally {
4927
4977
  evaluating = false;
4978
+ if (disposed) cleanup2(markDirty);
4928
4979
  }
4929
- if (hook && !Object.is(oldValue, cs._v)) {
4980
+ if (hook && !disposed && !Object.is(oldValue, cs._v)) {
4930
4981
  hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
4931
4982
  }
4932
4983
  };
4933
4984
  cs._validate = validate;
4985
+ const throwPending = () => {
4986
+ const { error } = pendingError;
4987
+ pendingError = void 0;
4988
+ if (disposed) cs._d = false;
4989
+ throw error;
4990
+ };
4934
4991
  function computedGetter() {
4935
4992
  if (evaluating) {
4936
4993
  throw new Error(
4937
4994
  `[SibuJS] Circular dependency detected in derived${debugName ? ` "${debugName}"` : ""}. A derived signal cannot read itself (directly or through a chain).`
4938
4995
  );
4939
4996
  }
4940
- if (isTrackingSuspended2()) {
4941
- if (cs._d) validate();
4997
+ if (isTrackingSuspended2() || disposed) {
4998
+ if (cs._d) {
4999
+ validate();
5000
+ if (pendingError !== void 0) throwPending();
5001
+ }
4942
5002
  return cs._v;
4943
5003
  }
4944
- if (cs._d) validate();
5004
+ if (cs._d) {
5005
+ validate();
5006
+ if (pendingError !== void 0) {
5007
+ recordDependency2(cs);
5008
+ throwPending();
5009
+ }
5010
+ }
4945
5011
  recordDependency2(cs);
4946
5012
  return cs._v;
4947
5013
  }
@@ -4950,6 +5016,19 @@ function derived(getter, options) {
4950
5016
  cs.__name = debugName;
4951
5017
  }
4952
5018
  computedGetter.__signal = cs;
5019
+ computedGetter.dispose = () => {
5020
+ if (disposed) return;
5021
+ disposed = true;
5022
+ cs._d = pendingError !== void 0;
5023
+ cleanup2(markDirty);
5024
+ const h = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
5025
+ if (h) {
5026
+ try {
5027
+ h.emit("computed:destroy", { signal: cs, getter: computedGetter });
5028
+ } catch {
5029
+ }
5030
+ }
5031
+ };
4953
5032
  if (hook) hook.emit("computed:create", { signal: cs, name: debugName, getter: computedGetter });
4954
5033
  return computedGetter;
4955
5034
  }
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { N as NodeChild, a as NodeChildren, T as TagProps } from './tagFactory-Bzupt4Pj.cjs';
2
- export { D as Dispose, S as SVG_NS, t as tagFactory } from './tagFactory-Bzupt4Pj.cjs';
1
+ import { N as NodeChild, a as NodeChildren, T as TagProps, A as Accessor, D as DerivedAccessor } from './tagFactory-DVoDpHye.cjs';
2
+ export { b as Dispose, E as ExternalSource, S as SVG_NS, c as SignalOptions, d as derived, e as external, s as signal, t as tagFactory } from './tagFactory-DVoDpHye.cjs';
3
3
  export { T as TrustedHTML, t as trustHTML } from './ssr-BiPRdZ6n.cjs';
4
4
  import { R as ReactiveSignal } from './signal-BnWpq6WB.cjs';
5
5
 
@@ -667,12 +667,22 @@ declare function DynamicComponent(is: () => string | Component$1): HTMLElement;
667
667
  * assigns that row a new item or position.
668
668
  *
669
669
  * Identity is not value freshness: a row keeps its DOM node when its key is
670
- * unchanged, and still updates its contents when the item behind that key is
671
- * replaced.
672
- *
673
- * Reading `item()` subscribes to the ROW's cell, not to the whole-array signal,
674
- * so a row only re-renders when its own item/index actually changes — mutating
675
- * an unrelated row does not disturb it.
670
+ * unchanged, and its bindings still update when the item behind that key is
671
+ * replaced — provided they read the getter rather than a value captured when
672
+ * `render` ran.
673
+ *
674
+ * `render` runs untracked, whether the row appears in the first pass or in a
675
+ * later update: a signal read directly in its body — `item()` and `index()`
676
+ * included — is a one-time read that never subscribes anything and goes stale
677
+ * when the key later receives a replacement item or moves. Pass the getters
678
+ * down (`Row({ item, index })`) or read them inside bindings
679
+ * (`() => item().name`) and effects created by the row.
680
+ *
681
+ * A binding that reads `item()` subscribes to the ROW's cell, not to the
682
+ * whole-array signal. `render` never re-runs for an existing key; only the
683
+ * bindings and effects that read that row's `item()` / `index()` re-run, and
684
+ * only when its own item or position actually changes — mutating an unrelated
685
+ * row does not disturb it.
676
686
  *
677
687
  * @param getArray A reactive getter returning an array.
678
688
  * @param render A function that receives reactive item and index getters and returns a NodeChild.
@@ -1199,106 +1209,6 @@ type Slots = Record<string, SlotFn>;
1199
1209
  */
1200
1210
  declare function getSlot(slots: Slots | undefined, name?: string): SlotFn | undefined;
1201
1211
 
1202
- declare const __accessor: unique symbol;
1203
- /**
1204
- * A reactive signal getter returned by signal(), derived(), and similar primitives.
1205
- *
1206
- * Pass an Accessor directly into reactive prop positions — never call it there:
1207
- * ```ts
1208
- * const [count, setCount] = signal(0);
1209
- *
1210
- * div(count) // ✓ reactive — Accessor passed directly
1211
- * div(() => count()) // ✓ reactive — explicit arrow wrapper
1212
- * div(count()) // ✗ static — evaluated once, not reactive
1213
- * ```
1214
- */
1215
- type Accessor<T> = (() => T) & {
1216
- readonly [__accessor]?: never;
1217
- };
1218
- type SetState<T> = (next: T | ((prev: T) => T)) => void;
1219
- type StateTuple<T> = [Accessor<T>, SetState<T>];
1220
- /** Options for signal */
1221
- interface SignalOptions<T = unknown> {
1222
- /** Debug name for devtools inspection. Only used in development. */
1223
- name?: string;
1224
- /** Custom equality function. Defaults to Object.is(). */
1225
- equals?: (prev: T, next: T) => boolean;
1226
- }
1227
- /**
1228
- * signal creates a reactive signal that holds a value of type T.
1229
- * Returns a tuple: [getter, setter].
1230
- *
1231
- * @param initial Initial value
1232
- * @param options Optional config: `{ name: "count" }` for devtools labeling
1233
- * @returns A `[getter, setter]` tuple. Calling the getter inside a reactive
1234
- * context subscribes to the signal; the setter accepts a value or an updater.
1235
- */
1236
- declare function signal<T>(initial: T, options?: SignalOptions<T>): StateTuple<T>;
1237
- /**
1238
- * A valueless reactive token standing in for state SibuJS does not own.
1239
- *
1240
- * See {@link external}.
1241
- */
1242
- interface ExternalSource {
1243
- /**
1244
- * Declare, from inside a reactive computation, that it reads the external
1245
- * state this source represents. Call it in the same places you would read a
1246
- * signal — the top of a binding getter, a `derived()` body, an `effect()`.
1247
- *
1248
- * Outside a tracking context it is a no-op, exactly like reading a signal.
1249
- */
1250
- track(): void;
1251
- /**
1252
- * Declare that the external state changed. Every consumer that called
1253
- * {@link ExternalSource.track} is invalidated.
1254
- *
1255
- * Participates in `batch()` like any signal write: inside a batch, consumers
1256
- * are notified once when the outermost batch flushes.
1257
- */
1258
- invalidate(): void;
1259
- }
1260
- /**
1261
- * Create a reactive source for state that lives outside SibuJS — a domain
1262
- * engine, a media element, a canvas scene, an editor document, a cache a
1263
- * socket writes into.
1264
- *
1265
- * The pattern is two lines: `track()` where you read, `invalidate()` after you
1266
- * mutate.
1267
- *
1268
- * ```ts
1269
- * import { Chess } from "chess.js";
1270
- * import { external } from "sibujs";
1271
- *
1272
- * const game = new Chess(); // owns the rules and the mutable state
1273
- * const moved = external(); // owns "something changed"
1274
- *
1275
- * ctx.text("@status", () => {
1276
- * moved.track(); // this binding reads the engine
1277
- * return game.isCheckmate() ? "Checkmate" : `${game.turn()} to move`;
1278
- * });
1279
- *
1280
- * game.move({ from: "e2", to: "e4" });
1281
- * moved.invalidate(); // every consumer above re-reads
1282
- * ```
1283
- *
1284
- * **One source is one invalidation domain.** Every consumer of a source
1285
- * re-runs on every `invalidate()`, so the granularity of your updates is
1286
- * exactly the granularity of your sources: one for a whole engine is the
1287
- * cheapest to write, several (`board`, `clock`, `history`) let an update touch
1288
- * only what it affects. See `docs/architecture/external-state.md` for the
1289
- * trade-offs and when subdividing is worth it.
1290
- *
1291
- * Ownership, disposal and error routing are the consumer's, not the source's:
1292
- * a disposed binding or effect is never invalidated, and a consumer that
1293
- * throws is reported through the normal runtime error pipeline with its own
1294
- * phase and node.
1295
- *
1296
- * @param options `name` labels the source in devtools (development only).
1297
- */
1298
- declare function external(options?: {
1299
- name?: string;
1300
- }): ExternalSource;
1301
-
1302
1212
  /**
1303
1213
  * Reactive array hook. Provides common array operations that
1304
1214
  * automatically trigger reactive updates.
@@ -1498,45 +1408,6 @@ declare function deepEqual(a: unknown, b: unknown, seen?: Map<object, Set<object
1498
1408
  */
1499
1409
  declare function deepSignal<T>(initial: T): [Accessor<T>, (next: T | ((prev: T) => T)) => void];
1500
1410
 
1501
- /**
1502
- * derived creates a derived reactive signal whose value updates when dependencies change.
1503
- *
1504
- * Uses lazy pull-based evaluation with a single dirty flag:
1505
- * - When a dependency changes, the computed is marked dirty (no re-evaluation).
1506
- * - Dirtiness propagates downstream via propagateDirty.
1507
- * - The getter only re-evaluates when actually read (pull-based).
1508
- * - On re-evaluation, dependencies are re-tracked via retrack() so that
1509
- * derived-of-derived chains propagate correctly without paying the full
1510
- * Set-delete + re-add cost of track()'s cleanup phase.
1511
- *
1512
- * STABILIZATION — why a dirty flag is enough:
1513
- *
1514
- * A dirty computed does NOT imply a changed value. Downstream effects are
1515
- * enqueued by `propagateDirty` at write time, before this computed has had a
1516
- * chance to recompute and compare. Rather than adding a three-color
1517
- * (CLEAN/CHECK/DIRTY) propagation pass — which an earlier revision measured as
1518
- * a regression on every benchmark, because the extra state has nothing to skip
1519
- * when values genuinely change — the engine settles the question lazily at
1520
- * DRAIN time: `cs._validate` recomputes a dirty computed and `cs.__v` is bumped
1521
- * ONLY when the new value differs under this computed's comparator. The
1522
- * scheduler compares that version against what each subscriber last observed
1523
- * and suppresses the run when nothing changed (see `depsChanged` in
1524
- * ../../reactivity/track-core.ts).
1525
- *
1526
- * That keeps the cheap boolean dirty flag AND makes `equals` actually stop
1527
- * propagation, with recomputation still fully lazy: `_validate` only ever runs
1528
- * when an effect is genuinely about to observe the value.
1529
- *
1530
- * @returns An accessor for the computed value. It recomputes lazily on read
1531
- * after any dependency changes.
1532
- */
1533
- declare function derived<T>(getter: () => T, options?: {
1534
- name?: string;
1535
- /** Custom equality — when the recomputed value equals the previous,
1536
- * downstream subscribers are not notified. Defaults to `Object.is`. */
1537
- equals?: (a: T, b: T) => boolean;
1538
- }): Accessor<T>;
1539
-
1540
1411
  /** Options for effect */
1541
1412
  interface EffectOptions {
1542
1413
  /** Error handler for exceptions thrown during effect execution. */
@@ -1668,7 +1539,9 @@ declare function watch<T>(getter: () => T, callback: (value: T, prev: T | undefi
1668
1539
  * dependency-tracked). The setter typically updates upstream signals,
1669
1540
  * and the derived value recomputes on the next read.
1670
1541
  *
1671
- * Returns a `[getter, setter]` tuple, matching the `signal()` API.
1542
+ * Returns a `[getter, setter]` tuple, matching the `signal()` API. The getter
1543
+ * is the underlying `derived()` accessor, so `getter.dispose()` releases its
1544
+ * upstream subscriptions when the writable is discarded before its sources.
1672
1545
  *
1673
1546
  * @param get Computed getter — reads reactive dependencies
1674
1547
  * @param set Setter — called with the new value, typically updates upstream signals
@@ -1695,11 +1568,11 @@ declare function watch<T>(getter: () => T, callback: (value: T, prev: T | undefi
1695
1568
  * fullName(); // "Jane Smith"
1696
1569
  * ```
1697
1570
  *
1698
- * @returns A store handle with `subscribe`, `set` and `update`.
1571
+ * @returns A `[getter, setter]` tuple; the getter carries `dispose()`.
1699
1572
  */
1700
1573
  declare function writable<T>(get: () => T, set: (value: T) => void, options?: {
1701
1574
  name?: string;
1702
- }): [Accessor<T>, (value: T) => void];
1575
+ }): [DerivedAccessor<T>, (value: T) => void];
1703
1576
 
1704
1577
  /**
1705
1578
  * SSR context for SibuJS.
@@ -2306,4 +2179,4 @@ declare const untracked: ReactiveApi["untracked"];
2306
2179
  declare const retrack: ReactiveApi["retrack"];
2307
2180
  declare const setMaxDrainIterations: ReactiveApi["setMaxDrainIterations"];
2308
2181
 
2309
- export { type Accessor, type ActionFn, type AnchorProps, type ArrayActions, type AsyncDerivedContext, type AsyncDerivedState, type AudioProps, type ButtonProps, type Context, DynamicComponent, type EachBindings, type EachEventBindings, type EffectBody, type EffectOptions, type EnhanceContext, type EnhanceSetup, ErrorBoundary, type ErrorBoundaryOptions, type ErrorBoundaryProps, ErrorDisplay, type ErrorDisplayProps, type ErrorSeverity, type ExternalSource, type FormProps, Fragment, type ImgProps, type InputProps, type InputType, type IslandLoader, type IslandRegistration, type IslandStrategy, KeepAlive, type KeepAliveOptions, type LabelProps, type LazyIslandLoader, Loading, type LoadingProps, type LongPressOptions, MAX_DRAIN_TEARDOWNS, type MediaProps, type MountIslandsOptions, NodeChild, NodeChildren, type OnCleanup, type OptionProps, Portal, type Ref, type RuntimeErrorContext, type RuntimeErrorHandler, type RuntimeErrorPhase, type SSRStore, type SelectProps, type SignalOptions, type SlotFn, type Slots, type StoreActions, Suspense, type SuspenseProps, TagProps, type TextareaProps, type TypedTagFunction, type VideoProps, __resetIdCounter, a, abbr, action, address, area, array, article, aside, asyncDerived, audio, autoResize, b, base, batch, bdi, bdo, bindDynamic, blockquote, body, br, button, canvas, caption, catchError, catchErrorAsync, center, checkLeaks, circle, cite, clickOutside, clipPath, code, col, colgroup, context, copyOnClick, createId, customElement, data, datalist, dd, deepEqual, deepSignal, defer, defs, del, derived, details, dfn, dialog, disableSSR, dispose, div, dl, dt, each, effect, ellipse, em, embed, enableSSR, enhance, enhanceAll, enqueueBatchedSignal, external, fieldset, figcaption, figure, font, footer, form, g, getAction, getRequestScopedCache, getRuntimeErrorHandler, getSSRStore, getSlot, h1, h2, h3, h4, h5, h6, head, header, hr, html, i, iframe, img, input, ins, isBatching, isSSR, kbd, label, lazy, lazyIsland, legend, li, line, linearGradient, link, longPress, main, map, mark, marker, marquee, mask, match, math, menu, meta, meter, mount, mountIslands, nav, nextTick, noscript, object, ol, on, onCleanup, onMount, onUnmount, optgroup, option, output, p, param, path, pattern, picture, polygon, polyline, portal, pre, progress, q, radialGradient, reactiveArray, rect, ref, registerAction, registerComponent, registerDisposer, registerIsland, replaceChildrenSafely, reportDrainRunaway, reportError, resolveComponent, retrack, rp, rt, ruby, runInSSRContext, s, samp, script, section, select, setGlobalErrorHandler, setMaxDrainIterations, setRuntimeErrorHandler, show, signal, slot, small, source, span, stop, store, strict, strictEffect, strong, style, sub, summary, sup, svg, symbol, table, takePendingError, tbody, td, template, text, textarea, tfoot, th, thead, time, title, tr, track$1 as track, transition, trapFocus, tspan, u, ul, unregisterComponent, unregisterDisposer, unregisterIsland, untracked, use, var_, video, watch, when, withSSR, writable };
2182
+ export { Accessor, type ActionFn, type AnchorProps, type ArrayActions, type AsyncDerivedContext, type AsyncDerivedState, type AudioProps, type ButtonProps, type Context, DerivedAccessor, DynamicComponent, type EachBindings, type EachEventBindings, type EffectBody, type EffectOptions, type EnhanceContext, type EnhanceSetup, ErrorBoundary, type ErrorBoundaryOptions, type ErrorBoundaryProps, ErrorDisplay, type ErrorDisplayProps, type ErrorSeverity, type FormProps, Fragment, type ImgProps, type InputProps, type InputType, type IslandLoader, type IslandRegistration, type IslandStrategy, KeepAlive, type KeepAliveOptions, type LabelProps, type LazyIslandLoader, Loading, type LoadingProps, type LongPressOptions, MAX_DRAIN_TEARDOWNS, type MediaProps, type MountIslandsOptions, NodeChild, NodeChildren, type OnCleanup, type OptionProps, Portal, type Ref, type RuntimeErrorContext, type RuntimeErrorHandler, type RuntimeErrorPhase, type SSRStore, type SelectProps, type SlotFn, type Slots, type StoreActions, Suspense, type SuspenseProps, TagProps, type TextareaProps, type TypedTagFunction, type VideoProps, __resetIdCounter, a, abbr, action, address, area, array, article, aside, asyncDerived, audio, autoResize, b, base, batch, bdi, bdo, bindDynamic, blockquote, body, br, button, canvas, caption, catchError, catchErrorAsync, center, checkLeaks, circle, cite, clickOutside, clipPath, code, col, colgroup, context, copyOnClick, createId, customElement, data, datalist, dd, deepEqual, deepSignal, defer, defs, del, details, dfn, dialog, disableSSR, dispose, div, dl, dt, each, effect, ellipse, em, embed, enableSSR, enhance, enhanceAll, enqueueBatchedSignal, fieldset, figcaption, figure, font, footer, form, g, getAction, getRequestScopedCache, getRuntimeErrorHandler, getSSRStore, getSlot, h1, h2, h3, h4, h5, h6, head, header, hr, html, i, iframe, img, input, ins, isBatching, isSSR, kbd, label, lazy, lazyIsland, legend, li, line, linearGradient, link, longPress, main, map, mark, marker, marquee, mask, match, math, menu, meta, meter, mount, mountIslands, nav, nextTick, noscript, object, ol, on, onCleanup, onMount, onUnmount, optgroup, option, output, p, param, path, pattern, picture, polygon, polyline, portal, pre, progress, q, radialGradient, reactiveArray, rect, ref, registerAction, registerComponent, registerDisposer, registerIsland, replaceChildrenSafely, reportDrainRunaway, reportError, resolveComponent, retrack, rp, rt, ruby, runInSSRContext, s, samp, script, section, select, setGlobalErrorHandler, setMaxDrainIterations, setRuntimeErrorHandler, show, slot, small, source, span, stop, store, strict, strictEffect, strong, style, sub, summary, sup, svg, symbol, table, takePendingError, tbody, td, template, text, textarea, tfoot, th, thead, time, title, tr, track$1 as track, transition, trapFocus, tspan, u, ul, unregisterComponent, unregisterDisposer, unregisterIsland, untracked, use, var_, video, watch, when, withSSR, writable };