sibujs 1.4.0 → 1.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 (79) hide show
  1. package/README.md +105 -119
  2. package/dist/browser.cjs +53 -14
  3. package/dist/browser.d.cts +14 -9
  4. package/dist/browser.d.ts +14 -9
  5. package/dist/browser.js +4 -4
  6. package/dist/build.cjs +124 -42
  7. package/dist/build.d.cts +1 -1
  8. package/dist/build.d.ts +1 -1
  9. package/dist/build.js +10 -10
  10. package/dist/cdn.global.js +7 -7
  11. package/dist/chunk-5ZYQ6KDD.js +154 -0
  12. package/dist/chunk-6BMPXPUW.js +26 -0
  13. package/dist/chunk-7GRNSCFT.js +1097 -0
  14. package/dist/chunk-BGTHZHJ5.js +1016 -0
  15. package/dist/chunk-BMPL52BF.js +654 -0
  16. package/dist/chunk-GJPXRJ45.js +37 -0
  17. package/dist/chunk-JCDUJN2F.js +2779 -0
  18. package/dist/chunk-K4G4ZQNR.js +286 -0
  19. package/dist/chunk-MB6QFH3I.js +2776 -0
  20. package/dist/chunk-MYRV7VDM.js +742 -0
  21. package/dist/chunk-NZIIMDWI.js +84 -0
  22. package/dist/chunk-P3XWXJZU.js +282 -0
  23. package/dist/chunk-PDZQY43A.js +616 -0
  24. package/dist/chunk-RJ46C3CS.js +1293 -0
  25. package/dist/chunk-SFKNRVCU.js +292 -0
  26. package/dist/chunk-TDGZL5CU.js +365 -0
  27. package/dist/chunk-VAPYJN4X.js +368 -0
  28. package/dist/chunk-VQDZK23A.js +1023 -0
  29. package/dist/chunk-VQNQZCWJ.js +61 -0
  30. package/dist/chunk-XHK6BDAJ.js +76 -0
  31. package/dist/chunk-XUEEGU5O.js +409 -0
  32. package/dist/contracts-ey_Qh8ef.d.cts +239 -0
  33. package/dist/contracts-ey_Qh8ef.d.ts +239 -0
  34. package/dist/customElement-BL3Uo8dL.d.cts +318 -0
  35. package/dist/customElement-BL3Uo8dL.d.ts +318 -0
  36. package/dist/data.cjs +52 -11
  37. package/dist/data.js +6 -6
  38. package/dist/devtools.cjs +22 -24
  39. package/dist/devtools.js +26 -28
  40. package/dist/ecosystem.cjs +31 -6
  41. package/dist/ecosystem.d.cts +4 -4
  42. package/dist/ecosystem.d.ts +4 -4
  43. package/dist/ecosystem.js +7 -7
  44. package/dist/extras.cjs +304 -108
  45. package/dist/extras.d.cts +3 -3
  46. package/dist/extras.d.ts +3 -3
  47. package/dist/extras.js +19 -19
  48. package/dist/index.cjs +124 -42
  49. package/dist/index.d.cts +58 -48
  50. package/dist/index.d.ts +58 -48
  51. package/dist/index.js +10 -10
  52. package/dist/motion.cjs +13 -2
  53. package/dist/motion.d.cts +1 -1
  54. package/dist/motion.d.ts +1 -1
  55. package/dist/motion.js +3 -3
  56. package/dist/patterns.cjs +91 -24
  57. package/dist/patterns.d.cts +46 -12
  58. package/dist/patterns.d.ts +46 -12
  59. package/dist/patterns.js +5 -5
  60. package/dist/performance.cjs +97 -12
  61. package/dist/performance.d.cts +6 -1
  62. package/dist/performance.d.ts +6 -1
  63. package/dist/performance.js +5 -3
  64. package/dist/plugins.cjs +19 -13
  65. package/dist/plugins.d.cts +3 -3
  66. package/dist/plugins.d.ts +3 -3
  67. package/dist/plugins.js +16 -18
  68. package/dist/ssr.cjs +9 -0
  69. package/dist/ssr.d.cts +1 -1
  70. package/dist/ssr.d.ts +1 -1
  71. package/dist/ssr.js +7 -7
  72. package/dist/testing.js +2 -2
  73. package/dist/ui.cjs +130 -48
  74. package/dist/ui.d.cts +13 -16
  75. package/dist/ui.d.ts +13 -16
  76. package/dist/ui.js +6 -6
  77. package/dist/widgets.cjs +31 -6
  78. package/dist/widgets.js +5 -5
  79. package/package.json +1 -1
package/dist/extras.d.cts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { InfiniteQueryOptions, InfiniteQueryResult, LoaderRoute, MutationOptions, MutationResult, OfflineStore, OfflineStoreOptions, QueryOptions, QueryResult, Resource, ResourceOptions, RetryOptions, RouteLoaderFn, SyncAdapter, SyncChange, SyncResult, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, resource, setQueryData, socket, stream, syncAdapter, throttle, withRetry } from './data.cjs';
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.cjs';
3
- export { GlobalStore, MachineConfig, MachineReturn, Middleware, OptimisticAction, PersistOptions, Selector, TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline } from './patterns.cjs';
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-xo5ckdRP.cjs';
3
+ export { GlobalStore, MachineConfig, MachineReturn, Middleware, PersistOptions, Selector, TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline } from './patterns.cjs';
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-ey_Qh8ef.cjs';
5
5
  export { AnimationPreset, PresetOptions, SlideDirection, SpringOptions, TransitionGroup, TransitionGroupOptions, TransitionOptions, animate, bounceIn, bounceOut, fadeIn, fadeOut, flipIn, pulse, reducedMotion, scaleDown, scaleUp, sequence, shake, slideIn, slideOut, spring, springSignal, stagger, transition, viewTransition } from './motion.cjs';
6
- export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-D2DJp_xn.cjs';
6
+ export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-BL3Uo8dL.cjs';
7
7
  export { ChunkConfig, DOMPool, Features, NormalizeResult, NormalizedEntities, NormalizedSchema, NormalizedState, NormalizedStoreActions, Priority, PriorityLevel, block, cloneTemplate, conditional, createChunkRegistry, deferredValue, denormalize, devOnly, domPool, flushScheduler, hoistable, lazyChunk, noSideEffect, normalize, normalizedStore, pendingTasks, precompile, prefetch, preloadImage, preloadModule, preloadModules, preloadResource, processInChunks, pure, resetIdCounter, scheduleUpdate, setIdPrefix, startTransition, staticTemplate, transitionState, uniqueId, yieldToMain } from './performance.cjs';
8
8
  export { ActionFn, ActionResult, Head, ISROptions, 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, preloadWasm, scrollRestoration, serviceWorker, setCanonical, setStructuredData, wasm, worker, workerFn } from './ssr.cjs';
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 island, r as renderToDocument, g as renderToReadableStream, j as renderToStream, k as renderToString, l as renderToSuspenseStream, m as resetSSRState, s as serializeState, n as ssrSuspense, o as suspenseSwapScript, t as trustHTML } from './ssr-Do_SiVoL.cjs';
package/dist/extras.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export { InfiniteQueryOptions, InfiniteQueryResult, LoaderRoute, MutationOptions, MutationResult, OfflineStore, OfflineStoreOptions, QueryOptions, QueryResult, Resource, ResourceOptions, RetryOptions, RouteLoaderFn, SyncAdapter, SyncChange, SyncResult, 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
- export { GlobalStore, MachineConfig, MachineReturn, Middleware, OptimisticAction, PersistOptions, Selector, 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-xo5ckdRP.js';
3
+ export { GlobalStore, MachineConfig, MachineReturn, Middleware, PersistOptions, Selector, 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-ey_Qh8ef.js';
5
5
  export { AnimationPreset, PresetOptions, SlideDirection, SpringOptions, TransitionGroup, TransitionGroupOptions, TransitionOptions, animate, bounceIn, bounceOut, fadeIn, fadeOut, flipIn, pulse, reducedMotion, scaleDown, scaleUp, sequence, shake, slideIn, slideOut, spring, springSignal, stagger, transition, viewTransition } from './motion.js';
6
- export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-D2DJp_xn.js';
6
+ export { B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, a as FocusTrap, b as FormConfig, c as FormField, d as FormReturn, I as IntersectionResult, M as MaskOptions, T as Toast, e as ToastInstance, V as ValidatorFn, f as VirtualList, g as VirtualListProps, h as announce, i as aria, j as bindAttrs, k as bindBoolAttr, l as bindData, m as bindField, n as creditCardMask, o as custom, p as dateMask, q as defineElement, r as dialog, s as email, t as eventBus, u as focus, v as form, w as hotkey, x as infiniteScroll, y as inputMask, z as intersection, A as lazyLoad, D as matchesPattern, E as max, G as maxLength, H as min, J as minLength, K as pagination, L as phoneMask, N as removeScopedStyle, O as required, P as scopedStyle, Q as ssnMask, R as svgElement, S as timeMask, U as toast, W as withScopedStyle, X as zipMask } from './customElement-BL3Uo8dL.js';
7
7
  export { ChunkConfig, DOMPool, Features, NormalizeResult, NormalizedEntities, NormalizedSchema, NormalizedState, NormalizedStoreActions, Priority, PriorityLevel, block, cloneTemplate, conditional, createChunkRegistry, deferredValue, denormalize, devOnly, domPool, flushScheduler, 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, 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, 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 island, r as renderToDocument, g as renderToReadableStream, j as renderToStream, k as renderToString, l as renderToSuspenseStream, m as resetSSRState, s as serializeState, n as ssrSuspense, o as suspenseSwapScript, t as trustHTML } from './ssr-Do_SiVoL.js';
package/dist/extras.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  optimisticList,
6
6
  persisted,
7
7
  timeline
8
- } from "./chunk-ZWKZCBO6.js";
8
+ } from "./chunk-VAPYJN4X.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-TSOKIX5Z.js";
44
+ } from "./chunk-BMPL52BF.js";
45
45
  import {
46
46
  VERSION,
47
47
  bundlerMetadata,
@@ -87,7 +87,7 @@ import {
87
87
  wasm,
88
88
  worker,
89
89
  workerFn
90
- } from "./chunk-2BYQDGN3.js";
90
+ } from "./chunk-MYRV7VDM.js";
91
91
  import {
92
92
  FocusTrap,
93
93
  VirtualList,
@@ -127,7 +127,7 @@ import {
127
127
  toast,
128
128
  withScopedStyle,
129
129
  zipMask
130
- } from "./chunk-JCI5M6U6.js";
130
+ } from "./chunk-VQDZK23A.js";
131
131
  import {
132
132
  RenderProp,
133
133
  assertType,
@@ -154,7 +154,7 @@ import {
154
154
  select,
155
155
  tabs,
156
156
  tooltip
157
- } from "./chunk-EBGIRKQY.js";
157
+ } from "./chunk-PDZQY43A.js";
158
158
  import {
159
159
  collectStream,
160
160
  deserializeState,
@@ -211,7 +211,7 @@ import {
211
211
  visibility,
212
212
  wakeLock,
213
213
  windowSize
214
- } from "./chunk-3AIRKM3B.js";
214
+ } from "./chunk-RJ46C3CS.js";
215
215
  import {
216
216
  calculateDelay,
217
217
  clearQueryCache,
@@ -233,7 +233,7 @@ import {
233
233
  syncAdapter,
234
234
  throttle,
235
235
  withRetry
236
- } from "./chunk-JAKHTMQU.js";
236
+ } from "./chunk-BGTHZHJ5.js";
237
237
  import {
238
238
  SibuError,
239
239
  checkLeaks,
@@ -269,7 +269,7 @@ import {
269
269
  trackCleanup,
270
270
  walkDependencyGraph,
271
271
  withErrorTracking
272
- } from "./chunk-77L6NL3X.js";
272
+ } from "./chunk-7GRNSCFT.js";
273
273
  import {
274
274
  antdAdapter,
275
275
  chakraAdapter,
@@ -279,7 +279,7 @@ import {
279
279
  mobXAdapter,
280
280
  reduxAdapter,
281
281
  zustandAdapter
282
- } from "./chunk-BTU3TJDS.js";
282
+ } from "./chunk-TDGZL5CU.js";
283
283
  import {
284
284
  createPlugin,
285
285
  inject,
@@ -289,14 +289,14 @@ import {
289
289
  triggerPluginMount,
290
290
  triggerPluginUnmount
291
291
  } from "./chunk-K5ZUMYVS.js";
292
- import "./chunk-32DY64NT.js";
293
- import "./chunk-NYVAC6P5.js";
294
- import "./chunk-BGN5ZMP4.js";
295
- import "./chunk-F3FA4F32.js";
296
- import "./chunk-PTQJDMRT.js";
297
- import "./chunk-NEKUBFPT.js";
292
+ import "./chunk-P3XWXJZU.js";
293
+ import "./chunk-GJPXRJ45.js";
294
+ import "./chunk-6BMPXPUW.js";
295
+ import "./chunk-SFKNRVCU.js";
296
+ import "./chunk-5ZYQ6KDD.js";
297
+ import "./chunk-XHK6BDAJ.js";
298
298
  import "./chunk-CMBFNA7L.js";
299
- import "./chunk-CHF5OHIA.js";
299
+ import "./chunk-VQNQZCWJ.js";
300
300
  import "./chunk-EUZND3CB.js";
301
301
  import {
302
302
  TransitionGroup,
@@ -319,9 +319,9 @@ import {
319
319
  stagger,
320
320
  transition,
321
321
  viewTransition
322
- } from "./chunk-KQPDEVVS.js";
323
- import "./chunk-WZSPOOER.js";
324
- import "./chunk-ZD6OAMTH.js";
322
+ } from "./chunk-XUEEGU5O.js";
323
+ import "./chunk-NZIIMDWI.js";
324
+ import "./chunk-K4G4ZQNR.js";
325
325
  import "./chunk-5X6PP2UK.js";
326
326
  export {
327
327
  DOMPool,
package/dist/index.cjs CHANGED
@@ -372,12 +372,21 @@ function queueSignalNotification(signal2) {
372
372
  }
373
373
  }
374
374
  }
375
+ var MAX_DRAIN_ITERATIONS = 1e3;
375
376
  function drainNotificationQueue() {
376
377
  if (notifyDepth > 0) return;
377
378
  notifyDepth++;
378
379
  try {
379
380
  let i2 = 0;
380
381
  while (i2 < pendingQueue.length) {
382
+ if (i2 >= MAX_DRAIN_ITERATIONS) {
383
+ if (typeof console !== "undefined") {
384
+ console.error(
385
+ `[SibuJS] Notification queue exceeded ${MAX_DRAIN_ITERATIONS} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
386
+ );
387
+ }
388
+ break;
389
+ }
381
390
  safeInvoke(pendingQueue[i2]);
382
391
  i2++;
383
392
  }
@@ -707,7 +716,15 @@ function dispose(node) {
707
716
  const disposers = elementDisposers.get(current);
708
717
  if (disposers) {
709
718
  if (_isDev5) activeBindingCount -= disposers.length;
710
- for (const d of disposers) d();
719
+ for (const d of disposers) {
720
+ try {
721
+ d();
722
+ } catch (err) {
723
+ if (_isDev5 && typeof console !== "undefined") {
724
+ console.warn("[SibuJS] Disposer threw during cleanup:", err);
725
+ }
726
+ }
727
+ }
711
728
  elementDisposers.delete(current);
712
729
  }
713
730
  }
@@ -1641,19 +1658,16 @@ function Portal(nodes, target) {
1641
1658
  portalContent = nodes();
1642
1659
  container.appendChild(portalContent);
1643
1660
  } catch (err) {
1644
- console.error("[Portal] Render error:", err);
1661
+ if (typeof console !== "undefined") {
1662
+ console.error("[Portal] Render error:", err);
1663
+ }
1645
1664
  }
1646
1665
  });
1647
- const observer = new MutationObserver(() => {
1648
- if (!anchor.isConnected && portalContent) {
1666
+ registerDisposer(anchor, () => {
1667
+ if (portalContent) {
1668
+ dispose(portalContent);
1649
1669
  portalContent.remove();
1650
1670
  portalContent = null;
1651
- observer.disconnect();
1652
- }
1653
- });
1654
- queueMicrotask(() => {
1655
- if (anchor.parentNode) {
1656
- observer.observe(anchor.parentNode, { childList: true });
1657
1671
  }
1658
1672
  });
1659
1673
  return anchor;
@@ -2120,21 +2134,37 @@ function derived(getter, options) {
2120
2134
  cs._v = getter();
2121
2135
  }, markDirty);
2122
2136
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2137
+ let evaluating = false;
2123
2138
  function computedGetter() {
2139
+ if (evaluating) {
2140
+ throw new Error(
2141
+ `[SibuJS] Circular dependency detected in derived${debugName ? ` "${debugName}"` : ""}. A derived signal cannot read itself (directly or through a chain).`
2142
+ );
2143
+ }
2124
2144
  if (trackingSuspended) {
2125
2145
  if (cs._d) {
2126
- cs._d = false;
2127
- cs._v = getter();
2146
+ evaluating = true;
2147
+ try {
2148
+ cs._d = false;
2149
+ cs._v = getter();
2150
+ } finally {
2151
+ evaluating = false;
2152
+ }
2128
2153
  }
2129
2154
  return cs._v;
2130
2155
  }
2131
2156
  recordDependency(cs);
2132
2157
  if (cs._d) {
2133
2158
  const oldValue = cs._v;
2134
- track(() => {
2135
- cs._d = false;
2136
- cs._v = getter();
2137
- }, markDirty);
2159
+ evaluating = true;
2160
+ try {
2161
+ track(() => {
2162
+ cs._d = false;
2163
+ cs._v = getter();
2164
+ }, markDirty);
2165
+ } finally {
2166
+ evaluating = false;
2167
+ }
2138
2168
  if (hook && oldValue !== cs._v) {
2139
2169
  hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
2140
2170
  }
@@ -2462,21 +2492,67 @@ function deepEqual(a2, b2, seen) {
2462
2492
  if (a2 == null || b2 == null) return false;
2463
2493
  if (typeof a2 !== typeof b2) return false;
2464
2494
  if (typeof a2 !== "object") return false;
2465
- if (a2 instanceof Date && b2 instanceof Date) return a2.getTime() === b2.getTime();
2466
- if (a2 instanceof RegExp && b2 instanceof RegExp) return a2.toString() === b2.toString();
2467
- if (!seen) seen = /* @__PURE__ */ new Set();
2468
- if (seen.has(a2)) return true;
2469
- seen.add(a2);
2495
+ const objA = a2;
2496
+ const objB = b2;
2497
+ if (objA.constructor !== objB.constructor) return false;
2498
+ if (a2 instanceof Date) return a2.getTime() === b2.getTime();
2499
+ if (a2 instanceof RegExp) {
2500
+ const rb = b2;
2501
+ return a2.source === rb.source && a2.flags === rb.flags;
2502
+ }
2503
+ if (!seen) seen = /* @__PURE__ */ new Map();
2504
+ let peers = seen.get(objA);
2505
+ if (peers?.has(objB)) return true;
2506
+ if (!peers) {
2507
+ peers = /* @__PURE__ */ new Set();
2508
+ seen.set(objA, peers);
2509
+ }
2510
+ peers.add(objB);
2511
+ if (a2 instanceof Map) {
2512
+ const mb = b2;
2513
+ if (a2.size !== mb.size) return false;
2514
+ for (const [k, v] of a2) {
2515
+ if (!mb.has(k)) return false;
2516
+ if (!deepEqual(v, mb.get(k), seen)) return false;
2517
+ }
2518
+ return true;
2519
+ }
2520
+ if (a2 instanceof Set) {
2521
+ const sb = b2;
2522
+ if (a2.size !== sb.size) return false;
2523
+ for (const item of a2) {
2524
+ if (!sb.has(item)) return false;
2525
+ }
2526
+ return true;
2527
+ }
2528
+ if (a2 instanceof ArrayBuffer) {
2529
+ const viewA = new Uint8Array(a2);
2530
+ const viewB = new Uint8Array(b2);
2531
+ if (viewA.length !== viewB.length) return false;
2532
+ for (let i2 = 0; i2 < viewA.length; i2++) {
2533
+ if (viewA[i2] !== viewB[i2]) return false;
2534
+ }
2535
+ return true;
2536
+ }
2537
+ if (ArrayBuffer.isView(a2) && ArrayBuffer.isView(b2)) {
2538
+ const ta = a2;
2539
+ const tb = b2;
2540
+ if (ta.length !== tb.length) return false;
2541
+ for (let i2 = 0; i2 < ta.length; i2++) {
2542
+ if (ta[i2] !== tb[i2]) return false;
2543
+ }
2544
+ return true;
2545
+ }
2470
2546
  if (Array.isArray(a2)) {
2471
2547
  if (!Array.isArray(b2)) return false;
2472
2548
  if (a2.length !== b2.length) return false;
2473
2549
  return a2.every((val, i2) => deepEqual(val, b2[i2], seen));
2474
2550
  }
2475
- const keysA = Object.keys(a2);
2476
- const keysB = Object.keys(b2);
2551
+ const keysA = Object.keys(objA);
2552
+ const keysB = Object.keys(objB);
2477
2553
  if (keysA.length !== keysB.length) return false;
2478
2554
  return keysA.every(
2479
- (key) => deepEqual(a2[key], b2[key], seen)
2555
+ (key) => deepEqual(objA[key], objB[key], seen)
2480
2556
  );
2481
2557
  }
2482
2558
  function deepSignal(initial) {
@@ -2536,29 +2612,35 @@ function asyncDerived(factory, initial) {
2536
2612
  // src/core/rendering/lifecycle.ts
2537
2613
  function safeCall(cb, hookName) {
2538
2614
  try {
2539
- cb();
2615
+ return cb();
2540
2616
  } catch (err) {
2541
2617
  devWarn(`${hookName}: callback threw: ${err instanceof Error ? err.message : String(err)}`);
2618
+ return void 0;
2619
+ }
2620
+ }
2621
+ function runMountCallback(callback, hookName, element) {
2622
+ const cleanup2 = safeCall(callback, hookName);
2623
+ if (typeof cleanup2 === "function" && element) {
2624
+ registerDisposer(element, cleanup2);
2542
2625
  }
2543
2626
  }
2544
2627
  function onMount(callback, element) {
2545
2628
  if (typeof document === "undefined") return;
2546
2629
  if (element) {
2547
2630
  if (element.isConnected) {
2548
- queueMicrotask(() => {
2549
- safeCall(callback, "onMount");
2550
- });
2631
+ queueMicrotask(() => runMountCallback(callback, "onMount", element));
2551
2632
  return;
2552
2633
  }
2553
2634
  const observer = new MutationObserver(() => {
2554
2635
  if (element.isConnected) {
2555
2636
  observer.disconnect();
2556
- safeCall(callback, "onMount");
2637
+ runMountCallback(callback, "onMount", element);
2557
2638
  }
2558
2639
  });
2640
+ registerDisposer(element, () => observer.disconnect());
2559
2641
  queueMicrotask(() => {
2560
2642
  if (element.isConnected) {
2561
- safeCall(callback, "onMount");
2643
+ runMountCallback(callback, "onMount", element);
2562
2644
  } else {
2563
2645
  observer.observe(document.body, { childList: true, subtree: true });
2564
2646
  }
@@ -2570,6 +2652,7 @@ function onMount(callback, element) {
2570
2652
  }
2571
2653
  }
2572
2654
  function onUnmount(callback, element) {
2655
+ registerDisposer(element, () => safeCall(callback, "onUnmount"));
2573
2656
  const startObserving = () => {
2574
2657
  const observer = new MutationObserver(() => {
2575
2658
  if (!element.isConnected) {
@@ -2578,6 +2661,7 @@ function onUnmount(callback, element) {
2578
2661
  }
2579
2662
  });
2580
2663
  observer.observe(document.body, { childList: true, subtree: true });
2664
+ registerDisposer(element, () => observer.disconnect());
2581
2665
  };
2582
2666
  if (element.isConnected) {
2583
2667
  startObserving();
@@ -2728,26 +2812,24 @@ function lazy(importFn) {
2728
2812
  if (cached) {
2729
2813
  return cached();
2730
2814
  }
2731
- const [_status, setStatus] = signal("loading");
2732
- const [_error, setError] = signal(null);
2733
2815
  const container = div({ class: "sibu-lazy" });
2816
+ let disposed = false;
2734
2817
  importFn().then((mod) => {
2818
+ if (disposed) return;
2735
2819
  cached = mod.default;
2736
2820
  const rendered = cached();
2737
2821
  container.replaceChildren(rendered);
2738
- setStatus("loaded");
2739
2822
  }).catch((err) => {
2823
+ if (disposed) return;
2740
2824
  const errorObj = err instanceof Error ? err : new Error(String(err));
2741
- setError(errorObj);
2742
- setStatus("error");
2743
- container.replaceChildren(
2744
- div({
2745
- class: "sibu-lazy-error",
2746
- nodes: `Failed to load component: ${errorObj.message}`
2747
- })
2748
- );
2825
+ container.replaceChildren(div("sibu-lazy-error", `Failed to load component: ${errorObj.message}`));
2749
2826
  });
2750
- container.appendChild(span({ class: "sibu-lazy-loading", nodes: "Loading..." }));
2827
+ container.appendChild(span("sibu-lazy-loading", "Loading..."));
2828
+ const origRemove = container.remove.bind(container);
2829
+ container.remove = () => {
2830
+ disposed = true;
2831
+ origRemove();
2832
+ };
2751
2833
  return container;
2752
2834
  };
2753
2835
  }