sibujs 1.5.0 → 2.0.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 (207) hide show
  1. package/dist/browser.cjs +238 -69
  2. package/dist/browser.d.cts +5 -0
  3. package/dist/browser.d.ts +5 -0
  4. package/dist/browser.js +6 -6
  5. package/dist/build.cjs +916 -292
  6. package/dist/build.js +15 -13
  7. package/dist/cdn.global.js +17 -16
  8. package/dist/chunk-2RA7SHDA.js +65 -0
  9. package/dist/chunk-2UPRY23K.js +80 -0
  10. package/dist/chunk-3JHCYHWN.js +125 -0
  11. package/dist/{chunk-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
  12. package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
  13. package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
  14. package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
  15. package/dist/chunk-7JDB7I65.js +1327 -0
  16. package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
  17. package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
  18. package/dist/{chunk-BGN5ZMP4.js → chunk-GTBNNBJ6.js} +14 -2
  19. package/dist/chunk-HB24TBAF.js +121 -0
  20. package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
  21. package/dist/{chunk-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
  22. package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
  23. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  24. package/dist/{chunk-SFKNRVCU.js → chunk-KLRMB5ZS.js} +135 -79
  25. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  26. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  27. package/dist/{chunk-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
  28. package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
  29. package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
  30. package/dist/{chunk-NHUC2QWH.js → chunk-R73P76YZ.js} +1 -1
  31. package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
  32. package/dist/chunk-UCS6AMJ7.js +79 -0
  33. package/dist/{chunk-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
  34. package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
  35. package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
  36. package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
  37. package/dist/data.cjs +410 -99
  38. package/dist/data.d.cts +20 -2
  39. package/dist/data.d.ts +20 -2
  40. package/dist/data.js +11 -9
  41. package/dist/devtools.cjs +513 -223
  42. package/dist/devtools.d.cts +1 -1
  43. package/dist/devtools.d.ts +1 -1
  44. package/dist/devtools.js +12 -6
  45. package/dist/ecosystem.cjs +475 -144
  46. package/dist/ecosystem.d.cts +9 -7
  47. package/dist/ecosystem.d.ts +9 -7
  48. package/dist/ecosystem.js +12 -11
  49. package/dist/extras.cjs +3355 -1541
  50. package/dist/extras.d.cts +9 -9
  51. package/dist/extras.d.ts +9 -9
  52. package/dist/extras.js +58 -45
  53. package/dist/index.cjs +920 -292
  54. package/dist/index.d.cts +71 -8
  55. package/dist/index.d.ts +71 -8
  56. package/dist/index.js +28 -16
  57. package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
  58. package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
  59. package/dist/motion.cjs +77 -34
  60. package/dist/motion.js +4 -4
  61. package/dist/patterns.cjs +335 -69
  62. package/dist/patterns.d.cts +11 -12
  63. package/dist/patterns.d.ts +11 -12
  64. package/dist/patterns.js +7 -7
  65. package/dist/performance.cjs +279 -108
  66. package/dist/performance.d.cts +23 -16
  67. package/dist/performance.d.ts +23 -16
  68. package/dist/performance.js +13 -8
  69. package/dist/plugin-D30wlGW5.d.cts +71 -0
  70. package/dist/plugin-D30wlGW5.d.ts +71 -0
  71. package/dist/plugins.cjs +635 -260
  72. package/dist/plugins.d.cts +10 -3
  73. package/dist/plugins.d.ts +10 -3
  74. package/dist/plugins.js +106 -38
  75. package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
  76. package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
  77. package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
  78. package/dist/ssr.cjs +642 -222
  79. package/dist/ssr.d.cts +26 -6
  80. package/dist/ssr.d.ts +26 -6
  81. package/dist/ssr.js +12 -11
  82. package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
  83. package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
  84. package/dist/testing.cjs +252 -63
  85. package/dist/testing.d.cts +17 -4
  86. package/dist/testing.d.ts +17 -4
  87. package/dist/testing.js +100 -44
  88. package/dist/ui.cjs +463 -137
  89. package/dist/ui.d.cts +1 -1
  90. package/dist/ui.d.ts +1 -1
  91. package/dist/ui.js +20 -17
  92. package/dist/widgets.cjs +977 -94
  93. package/dist/widgets.d.cts +104 -2
  94. package/dist/widgets.d.ts +104 -2
  95. package/dist/widgets.js +9 -7
  96. package/package.json +8 -2
  97. package/dist/chunk-32DY64NT.js +0 -282
  98. package/dist/chunk-3AIRKM3B.js +0 -1263
  99. package/dist/chunk-3ARAQO7B.js +0 -398
  100. package/dist/chunk-3CRQALYP.js +0 -877
  101. package/dist/chunk-4EI4AG32.js +0 -482
  102. package/dist/chunk-4MYMUBRS.js +0 -21
  103. package/dist/chunk-5ZYQ6KDD.js +0 -154
  104. package/dist/chunk-6BMPXPUW.js +0 -26
  105. package/dist/chunk-6HLLIF3K.js +0 -398
  106. package/dist/chunk-6LSNVCS2.js +0 -937
  107. package/dist/chunk-6SA3QQES.js +0 -61
  108. package/dist/chunk-77L6NL3X.js +0 -1097
  109. package/dist/chunk-7BF6TK55.js +0 -1097
  110. package/dist/chunk-7TQKR4PP.js +0 -294
  111. package/dist/chunk-7V26P53V.js +0 -712
  112. package/dist/chunk-AZ3ISID5.js +0 -298
  113. package/dist/chunk-B7SWRFUT.js +0 -332
  114. package/dist/chunk-BTU3TJDS.js +0 -365
  115. package/dist/chunk-BW3WT46K.js +0 -937
  116. package/dist/chunk-C6KFWOFV.js +0 -616
  117. package/dist/chunk-CHF5OHIA.js +0 -61
  118. package/dist/chunk-CHJ27IGK.js +0 -26
  119. package/dist/chunk-CMBFNA7L.js +0 -27
  120. package/dist/chunk-DAHRH4ON.js +0 -331
  121. package/dist/chunk-DKOHBI74.js +0 -924
  122. package/dist/chunk-DTCOOBMX.js +0 -725
  123. package/dist/chunk-EBGIRKQY.js +0 -616
  124. package/dist/chunk-EUZND3CB.js +0 -27
  125. package/dist/chunk-EVCZO745.js +0 -365
  126. package/dist/chunk-EWFVA3TJ.js +0 -282
  127. package/dist/chunk-F3FA4F32.js +0 -292
  128. package/dist/chunk-FGOEVHY3.js +0 -60
  129. package/dist/chunk-G3BOQPVO.js +0 -365
  130. package/dist/chunk-GCOK2LC3.js +0 -282
  131. package/dist/chunk-GJPXRJ45.js +0 -37
  132. package/dist/chunk-HGMJFBC7.js +0 -654
  133. package/dist/chunk-JAKHTMQU.js +0 -1000
  134. package/dist/chunk-JCI5M6U6.js +0 -956
  135. package/dist/chunk-K5ZUMYVS.js +0 -89
  136. package/dist/chunk-KQPDEVVS.js +0 -398
  137. package/dist/chunk-L6JRBDNS.js +0 -60
  138. package/dist/chunk-LA6KQEDU.js +0 -712
  139. package/dist/chunk-MB6QFH3I.js +0 -2776
  140. package/dist/chunk-MDVXJWFN.js +0 -304
  141. package/dist/chunk-MEZVEBPN.js +0 -2008
  142. package/dist/chunk-MK4ERFYL.js +0 -2249
  143. package/dist/chunk-MLKGABMK.js +0 -9
  144. package/dist/chunk-MQ5GOYPH.js +0 -2249
  145. package/dist/chunk-MYRV7VDM.js +0 -742
  146. package/dist/chunk-N6IZB6KJ.js +0 -567
  147. package/dist/chunk-NEKUBFPT.js +0 -60
  148. package/dist/chunk-NMRUZALC.js +0 -1097
  149. package/dist/chunk-NYVAC6P5.js +0 -37
  150. package/dist/chunk-NZIIMDWI.js +0 -84
  151. package/dist/chunk-OF7UZIVB.js +0 -725
  152. package/dist/chunk-P3XWXJZU.js +0 -282
  153. package/dist/chunk-P6W3STU4.js +0 -2249
  154. package/dist/chunk-PBHF5WKN.js +0 -616
  155. package/dist/chunk-PDZQY43A.js +0 -616
  156. package/dist/chunk-PTQJDMRT.js +0 -146
  157. package/dist/chunk-PZEGYCF5.js +0 -61
  158. package/dist/chunk-QBMDLBU2.js +0 -975
  159. package/dist/chunk-QWZG56ET.js +0 -2744
  160. package/dist/chunk-RQGQSLQK.js +0 -725
  161. package/dist/chunk-SDLZDHKP.js +0 -107
  162. package/dist/chunk-TDGZL5CU.js +0 -365
  163. package/dist/chunk-TNQWPPE6.js +0 -37
  164. package/dist/chunk-TSOKIX5Z.js +0 -654
  165. package/dist/chunk-UHNL42EF.js +0 -2730
  166. package/dist/chunk-UNXCEF6S.js +0 -21
  167. package/dist/chunk-V2XTI523.js +0 -347
  168. package/dist/chunk-VAU366PN.js +0 -2241
  169. package/dist/chunk-VMVDTCXB.js +0 -712
  170. package/dist/chunk-VQNQZCWJ.js +0 -61
  171. package/dist/chunk-VRW3FULF.js +0 -725
  172. package/dist/chunk-WADYRCO2.js +0 -304
  173. package/dist/chunk-WILQZRO4.js +0 -282
  174. package/dist/chunk-WR5D4EGH.js +0 -26
  175. package/dist/chunk-WUHJISPP.js +0 -298
  176. package/dist/chunk-XYU6TZOW.js +0 -182
  177. package/dist/chunk-Y6GP4QGG.js +0 -276
  178. package/dist/chunk-YECR7UIA.js +0 -347
  179. package/dist/chunk-YUTWTI4B.js +0 -654
  180. package/dist/chunk-Z65KYU7I.js +0 -26
  181. package/dist/chunk-Z6POF5YC.js +0 -975
  182. package/dist/chunk-ZBJP6WFL.js +0 -482
  183. package/dist/chunk-ZD6OAMTH.js +0 -277
  184. package/dist/chunk-ZWKZCBO6.js +0 -317
  185. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  186. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  187. package/dist/contracts-DOrhwbke.d.cts +0 -245
  188. package/dist/contracts-DOrhwbke.d.ts +0 -245
  189. package/dist/contracts-xo5ckdRP.d.cts +0 -240
  190. package/dist/contracts-xo5ckdRP.d.ts +0 -240
  191. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  192. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  193. package/dist/customElement-D2DJp_xn.d.cts +0 -313
  194. package/dist/customElement-D2DJp_xn.d.ts +0 -313
  195. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  196. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  197. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  198. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  199. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  200. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  201. package/dist/ssr-3RXHP5ES.js +0 -38
  202. package/dist/ssr-6GIMY5MX.js +0 -38
  203. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  204. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  205. package/dist/ssr-WKUPVSSK.js +0 -36
  206. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  207. package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
@@ -30,8 +30,8 @@ __export(performance_exports, {
30
30
  deferredValue: () => deferredValue,
31
31
  denormalize: () => denormalize,
32
32
  devOnly: () => devOnly,
33
- domPool: () => domPool,
34
33
  flushScheduler: () => flushScheduler,
34
+ getDOMPool: () => getDOMPool,
35
35
  hoistable: () => hoistable,
36
36
  lazyChunk: () => lazyChunk,
37
37
  noSideEffect: () => noSideEffect,
@@ -52,6 +52,7 @@ __export(performance_exports, {
52
52
  startTransition: () => startTransition,
53
53
  staticTemplate: () => staticTemplate,
54
54
  transitionState: () => transitionState,
55
+ trustHTML: () => trustHTML,
55
56
  uniqueId: () => uniqueId,
56
57
  yieldToMain: () => yieldToMain
57
58
  });
@@ -68,7 +69,9 @@ var Priority = {
68
69
  var taskIdCounter = 0;
69
70
  var taskQueue = [];
70
71
  var isProcessing = false;
71
- var frameId = null;
72
+ var scheduledKind = null;
73
+ var scheduledHandle = null;
74
+ var microtaskScheduled = false;
72
75
  function insertTask(task) {
73
76
  let i = taskQueue.length;
74
77
  while (i > 0 && taskQueue[i - 1].priority > task.priority) {
@@ -103,30 +106,38 @@ function processQueue() {
103
106
  }
104
107
  }
105
108
  function scheduleFrame() {
106
- if (frameId !== null) return;
109
+ if (scheduledKind !== null || microtaskScheduled) return;
107
110
  const nextTask = taskQueue.find((t) => !t.cancelled);
108
111
  if (!nextTask) return;
109
112
  if (nextTask.priority <= Priority.USER_BLOCKING) {
113
+ microtaskScheduled = true;
114
+ scheduledKind = "microtask";
110
115
  queueMicrotask(() => {
111
- frameId = null;
116
+ microtaskScheduled = false;
117
+ scheduledKind = null;
112
118
  processQueue();
113
119
  });
114
- frameId = -1;
115
120
  } else if (nextTask.priority === Priority.IDLE) {
116
121
  if (typeof requestIdleCallback !== "undefined") {
117
- frameId = requestIdleCallback(() => {
118
- frameId = null;
122
+ scheduledKind = "idle";
123
+ scheduledHandle = requestIdleCallback(() => {
124
+ scheduledKind = null;
125
+ scheduledHandle = null;
119
126
  processQueue();
120
127
  });
121
128
  } else {
122
- frameId = setTimeout(() => {
123
- frameId = null;
129
+ scheduledKind = "timeout";
130
+ scheduledHandle = setTimeout(() => {
131
+ scheduledKind = null;
132
+ scheduledHandle = null;
124
133
  processQueue();
125
134
  }, 50);
126
135
  }
127
136
  } else {
128
- frameId = requestAnimationFrame(() => {
129
- frameId = null;
137
+ scheduledKind = "frame";
138
+ scheduledHandle = requestAnimationFrame(() => {
139
+ scheduledKind = null;
140
+ scheduledHandle = null;
130
141
  processQueue();
131
142
  });
132
143
  }
@@ -154,6 +165,15 @@ function scheduleUpdate(priority, callback) {
154
165
  };
155
166
  }
156
167
  function flushScheduler() {
168
+ if (scheduledHandle !== null) {
169
+ if (scheduledKind === "frame") cancelAnimationFrame(scheduledHandle);
170
+ else if (scheduledKind === "idle" && typeof cancelIdleCallback !== "undefined") {
171
+ cancelIdleCallback(scheduledHandle);
172
+ } else if (scheduledKind === "timeout") clearTimeout(scheduledHandle);
173
+ }
174
+ scheduledHandle = null;
175
+ scheduledKind = null;
176
+ microtaskScheduled = false;
157
177
  while (taskQueue.length > 0) {
158
178
  const task = taskQueue.shift();
159
179
  if (!task) break;
@@ -162,7 +182,6 @@ function flushScheduler() {
162
182
  }
163
183
  }
164
184
  isProcessing = false;
165
- frameId = null;
166
185
  }
167
186
  function pendingTasks() {
168
187
  return taskQueue.filter((t) => !t.cancelled).length;
@@ -191,12 +210,12 @@ function isDev() {
191
210
  var _isDev = isDev();
192
211
  function devAssert(condition, message) {
193
212
  if (_isDev && !condition) {
194
- throw new Error(`[Sibu] ${message}`);
213
+ throw new Error(`[SibuJS] ${message}`);
195
214
  }
196
215
  }
197
216
  function devWarn(message) {
198
217
  if (_isDev) {
199
- console.warn(`[Sibu] ${message}`);
218
+ console.warn(`[SibuJS] ${message}`);
200
219
  }
201
220
  }
202
221
 
@@ -206,11 +225,11 @@ var subscriberStack = new Array(32);
206
225
  var stackCapacity = 32;
207
226
  var stackTop = -1;
208
227
  var currentSubscriber = null;
209
- var signalSubscribers = /* @__PURE__ */ new WeakMap();
210
228
  var SUBS = "__s";
211
229
  var notifyDepth = 0;
212
230
  var pendingQueue = [];
213
231
  var pendingSet = /* @__PURE__ */ new Set();
232
+ var propagateStack = [];
214
233
  function safeInvoke(sub) {
215
234
  try {
216
235
  sub();
@@ -256,7 +275,6 @@ function recordDependency(signal2) {
256
275
  let subs = signal2[SUBS];
257
276
  if (!subs) {
258
277
  subs = /* @__PURE__ */ new Set();
259
- signalSubscribers.set(signal2, subs);
260
278
  signal2[SUBS] = subs;
261
279
  }
262
280
  subs.add(currentSubscriber);
@@ -266,42 +284,46 @@ function recordDependency(signal2) {
266
284
  signal2.__f = void 0;
267
285
  }
268
286
  }
287
+ var maxDrainIterations = 1e5;
269
288
  function propagateDirty(sub) {
270
289
  sub();
271
- let sig = sub._sig;
272
- while (sig) {
290
+ const rootSig = sub._sig;
291
+ if (!rootSig) return;
292
+ const stack = propagateStack;
293
+ const baseLen = stack.length;
294
+ stack.push(rootSig);
295
+ while (stack.length > baseLen) {
296
+ const sig = stack.pop();
273
297
  const first = sig.__f;
274
298
  if (first) {
275
299
  if (first._c) {
276
300
  const nSig = first._sig;
277
- nSig._d = true;
278
- sig = nSig;
279
- continue;
280
- }
281
- if (!pendingSet.has(first)) {
301
+ if (!nSig._d) {
302
+ nSig._d = true;
303
+ stack.push(nSig);
304
+ }
305
+ } else if (!pendingSet.has(first)) {
282
306
  pendingSet.add(first);
283
307
  pendingQueue.push(first);
284
308
  }
285
- break;
309
+ continue;
286
310
  }
287
311
  const subs = sig[SUBS];
288
- if (!subs) break;
289
- let nextSig;
312
+ if (!subs) continue;
290
313
  for (const s of subs) {
291
314
  if (s._c) {
292
- s();
293
315
  const nSig = s._sig;
294
- if (nSig && !nextSig) {
295
- nextSig = nSig;
296
- } else if (nSig) {
297
- propagateDirty(s);
316
+ if (nSig && !nSig._d) {
317
+ nSig._d = true;
318
+ stack.push(nSig);
319
+ } else if (!nSig) {
320
+ s();
298
321
  }
299
322
  } else if (!pendingSet.has(s)) {
300
323
  pendingSet.add(s);
301
324
  pendingQueue.push(s);
302
325
  }
303
326
  }
304
- sig = nextSig;
305
327
  }
306
328
  }
307
329
  function notifySubscribers(signal2) {
@@ -325,13 +347,23 @@ function notifySubscribers(signal2) {
325
347
  }
326
348
  let i = 0;
327
349
  while (i < pendingQueue.length) {
350
+ if (i >= maxDrainIterations) {
351
+ if (typeof console !== "undefined") {
352
+ console.error(
353
+ `[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
354
+ );
355
+ }
356
+ break;
357
+ }
328
358
  safeInvoke(pendingQueue[i]);
329
359
  i++;
330
360
  }
331
361
  } finally {
332
- pendingQueue.length = 0;
333
- pendingSet.clear();
334
362
  notifyDepth--;
363
+ if (notifyDepth === 0) {
364
+ pendingQueue.length = 0;
365
+ pendingSet.clear();
366
+ }
335
367
  }
336
368
  return;
337
369
  }
@@ -351,30 +383,48 @@ function notifySubscribers(signal2) {
351
383
  notifyDepth++;
352
384
  try {
353
385
  let directCount = 0;
386
+ let hasComputedSub = false;
354
387
  for (const sub of subs) {
388
+ if (sub._c) hasComputedSub = true;
355
389
  pendingQueue[directCount++] = sub;
356
390
  }
357
- for (let i2 = 0; i2 < directCount; i2++) {
358
- if (pendingQueue[i2]._c) {
359
- propagateDirty(pendingQueue[i2]);
391
+ if (!hasComputedSub) {
392
+ for (let i2 = 0; i2 < directCount; i2++) {
393
+ safeInvoke(pendingQueue[i2]);
360
394
  }
361
- }
362
- for (let i2 = 0; i2 < directCount; i2++) {
363
- if (!pendingQueue[i2]._c) {
364
- if (!pendingSet.has(pendingQueue[i2])) {
365
- safeInvoke(pendingQueue[i2]);
395
+ } else {
396
+ for (let i2 = 0; i2 < directCount; i2++) {
397
+ if (pendingQueue[i2]._c) {
398
+ propagateDirty(pendingQueue[i2]);
399
+ }
400
+ }
401
+ for (let i2 = 0; i2 < directCount; i2++) {
402
+ const sub = pendingQueue[i2];
403
+ if (!sub._c && !pendingSet.has(sub)) {
404
+ pendingSet.add(sub);
405
+ safeInvoke(sub);
366
406
  }
367
407
  }
368
408
  }
369
409
  let i = directCount;
370
410
  while (i < pendingQueue.length) {
411
+ if (i - directCount >= maxDrainIterations) {
412
+ if (typeof console !== "undefined") {
413
+ console.error(
414
+ `[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
415
+ );
416
+ }
417
+ break;
418
+ }
371
419
  safeInvoke(pendingQueue[i]);
372
420
  i++;
373
421
  }
374
422
  } finally {
375
- pendingQueue.length = 0;
376
- pendingSet.clear();
377
423
  notifyDepth--;
424
+ if (notifyDepth === 0) {
425
+ pendingQueue.length = 0;
426
+ pendingSet.clear();
427
+ }
378
428
  }
379
429
  }
380
430
  function cleanup(subscriber) {
@@ -385,7 +435,9 @@ function cleanup(subscriber) {
385
435
  if (subs) {
386
436
  subs.delete(subscriber);
387
437
  if (singleDep.__f === subscriber) {
388
- singleDep.__f = void 0;
438
+ singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
439
+ } else if (subs.size === 1 && singleDep.__f === void 0) {
440
+ singleDep.__f = subs.values().next().value;
389
441
  }
390
442
  }
391
443
  sub._dep = void 0;
@@ -398,7 +450,9 @@ function cleanup(subscriber) {
398
450
  if (subs) {
399
451
  subs.delete(subscriber);
400
452
  if (signal2.__f === subscriber) {
401
- signal2.__f = void 0;
453
+ signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
454
+ } else if (subs.size === 1 && signal2.__f === void 0) {
455
+ signal2.__f = subs.values().next().value;
402
456
  }
403
457
  }
404
458
  }
@@ -406,9 +460,28 @@ function cleanup(subscriber) {
406
460
  }
407
461
 
408
462
  // src/core/ssr-context.ts
409
- var ssrMode = false;
463
+ var als = null;
464
+ try {
465
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
466
+ const req = Function("return typeof require==='function'?require:null")();
467
+ if (req) {
468
+ const mod = req("node:async_hooks");
469
+ als = new mod.AsyncLocalStorage();
470
+ }
471
+ }
472
+ } catch {
473
+ als = null;
474
+ }
475
+ var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
476
+ function getSSRStore() {
477
+ if (als) {
478
+ const s = als.getStore();
479
+ if (s) return s;
480
+ }
481
+ return fallbackStore;
482
+ }
410
483
  function isSSR() {
411
- return ssrMode;
484
+ return getSSRStore().ssr;
412
485
  }
413
486
 
414
487
  // src/core/signals/effect.ts
@@ -418,26 +491,86 @@ function effect(effectFn, options) {
418
491
  if (isSSR()) return () => {
419
492
  };
420
493
  const onError = options?.onError;
494
+ let userCleanups = [];
495
+ const onCleanup = (fn) => {
496
+ userCleanups.push(fn);
497
+ };
498
+ const runUserCleanups = () => {
499
+ if (userCleanups.length === 0) return;
500
+ const list = userCleanups;
501
+ userCleanups = [];
502
+ for (let i = list.length - 1; i >= 0; i--) {
503
+ try {
504
+ list[i]();
505
+ } catch (err) {
506
+ if (typeof console !== "undefined") {
507
+ console.warn("[SibuJS effect] onCleanup threw:", err);
508
+ }
509
+ }
510
+ }
511
+ };
512
+ const invokeBody = () => effectFn(onCleanup);
421
513
  const wrappedFn = onError ? () => {
422
514
  try {
423
- effectFn();
515
+ invokeBody();
424
516
  } catch (err) {
425
517
  onError(err);
426
518
  }
427
- } : effectFn;
519
+ } : invokeBody;
428
520
  let cleanupHandle = () => {
429
521
  };
522
+ let running = false;
430
523
  const subscriber = () => {
431
- cleanupHandle();
432
- cleanupHandle = track(wrappedFn, subscriber);
524
+ if (running) {
525
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
526
+ console.warn(
527
+ "[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
528
+ );
529
+ }
530
+ return;
531
+ }
532
+ running = true;
533
+ try {
534
+ runUserCleanups();
535
+ cleanupHandle();
536
+ cleanupHandle = track(wrappedFn, subscriber);
537
+ } finally {
538
+ running = false;
539
+ }
433
540
  };
434
- cleanupHandle = track(wrappedFn, subscriber);
541
+ running = true;
542
+ try {
543
+ cleanupHandle = track(wrappedFn, subscriber);
544
+ } finally {
545
+ running = false;
546
+ }
435
547
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
436
548
  if (hook) hook.emit("effect:create", { effectFn });
549
+ let disposed = false;
437
550
  return () => {
551
+ if (disposed) return;
552
+ disposed = true;
438
553
  const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
439
- if (h) h.emit("effect:destroy", { effectFn });
440
- cleanupHandle();
554
+ if (h) {
555
+ try {
556
+ h.emit("effect:destroy", { effectFn });
557
+ } catch {
558
+ }
559
+ }
560
+ try {
561
+ runUserCleanups();
562
+ } catch (err) {
563
+ if (typeof console !== "undefined") {
564
+ console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
565
+ }
566
+ }
567
+ try {
568
+ cleanupHandle();
569
+ } catch (err) {
570
+ if (typeof console !== "undefined") {
571
+ console.warn("[SibuJS effect] dispose threw:", err);
572
+ }
573
+ }
441
574
  };
442
575
  }
443
576
 
@@ -528,6 +661,7 @@ function uniqueId(suffix) {
528
661
  }
529
662
 
530
663
  // src/performance/domRecycler.ts
664
+ var _isDev4 = isDev();
531
665
  var DOMPool = class {
532
666
  constructor(maxSize = 50) {
533
667
  this.pools = /* @__PURE__ */ new Map();
@@ -547,8 +681,18 @@ var DOMPool = class {
547
681
  /**
548
682
  * Return an element to the pool for reuse.
549
683
  * Clears attributes, children, and event listeners.
684
+ *
685
+ * Contract: the caller MUST detach the element from the DOM (and run any
686
+ * `dispose()` on bound reactive subscriptions) BEFORE calling `release()`.
687
+ * Releasing a connected element leaves it visible while it is mutated and
688
+ * is almost certainly a bug.
550
689
  */
551
690
  release(element) {
691
+ if (_isDev4 && element.isConnected) {
692
+ devWarn(
693
+ "DOMPool.release() called on a still-connected element. Detach it from the DOM first (remove() / dispose())."
694
+ );
695
+ }
552
696
  const tag = element.tagName.toLowerCase();
553
697
  let pool = this.pools.get(tag);
554
698
  if (!pool) {
@@ -584,7 +728,11 @@ var DOMPool = class {
584
728
  return result;
585
729
  }
586
730
  };
587
- var domPool = new DOMPool();
731
+ var _defaultPool = null;
732
+ function getDOMPool() {
733
+ if (_defaultPool === null) _defaultPool = new DOMPool();
734
+ return _defaultPool;
735
+ }
588
736
  var preloadedResources = /* @__PURE__ */ new Set();
589
737
  function preloadResource(url, type = "fetch") {
590
738
  if (preloadedResources.has(url)) return;
@@ -647,6 +795,13 @@ function noSideEffect(fn) {
647
795
  return fn;
648
796
  }
649
797
 
798
+ // src/platform/ssr.ts
799
+ var _isDev5 = isDev();
800
+ function trustHTML(html) {
801
+ return html;
802
+ }
803
+ var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
804
+
650
805
  // src/performance/compiled.ts
651
806
  function staticTemplate(html) {
652
807
  const template = document.createElement("template");
@@ -814,31 +969,45 @@ function createChunkRegistry(config = {}) {
814
969
  const pending = /* @__PURE__ */ new Map();
815
970
  const preloaded = /* @__PURE__ */ new Set();
816
971
  function evict() {
817
- if (cache.size < maxCacheSize) return;
818
- let oldest = null;
819
- let oldestTime = Infinity;
820
- for (const [key, entry] of cache) {
821
- if (entry.timestamp < oldestTime) {
822
- oldestTime = entry.timestamp;
823
- oldest = key;
972
+ while (cache.size >= maxCacheSize) {
973
+ let lru = null;
974
+ let lruTime = Infinity;
975
+ for (const [key, entry] of cache) {
976
+ if (entry.lastAccess < lruTime) {
977
+ lruTime = entry.lastAccess;
978
+ lru = key;
979
+ }
824
980
  }
981
+ if (!lru) return;
982
+ cache.delete(lru);
825
983
  }
826
- if (oldest) cache.delete(oldest);
827
984
  }
828
985
  function isValid(entry) {
829
986
  if (cacheTTL === 0) return true;
830
987
  return Date.now() - entry.timestamp < cacheTTL;
831
988
  }
832
989
  async function loadWithRetry(id, loader, attempt = 0) {
990
+ let timeoutHandle = null;
833
991
  try {
834
- const result = await (timeout > 0 ? Promise.race([
835
- loader(),
836
- new Promise(
837
- (_, reject) => setTimeout(() => reject(new Error(`Chunk '${id}' loading timed out after ${timeout}ms`)), timeout)
838
- )
839
- ]) : loader());
992
+ const result = await (timeout > 0 ? new Promise((resolve, reject) => {
993
+ timeoutHandle = setTimeout(
994
+ () => reject(new Error(`Chunk '${id}' loading timed out after ${timeout}ms`)),
995
+ timeout
996
+ );
997
+ loader().then(
998
+ (v) => {
999
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
1000
+ resolve(v);
1001
+ },
1002
+ (e) => {
1003
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
1004
+ reject(e);
1005
+ }
1006
+ );
1007
+ }) : loader());
840
1008
  return result;
841
1009
  } catch (err) {
1010
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
842
1011
  if (attempt < retries) {
843
1012
  await new Promise((r) => setTimeout(r, retryDelay * (attempt + 1)));
844
1013
  return loadWithRetry(id, loader, attempt + 1);
@@ -846,49 +1015,48 @@ function createChunkRegistry(config = {}) {
846
1015
  throw err;
847
1016
  }
848
1017
  }
1018
+ async function loadFn(id, loader) {
1019
+ const cached = cache.get(id);
1020
+ if (cached && isValid(cached)) {
1021
+ cached.accessCount++;
1022
+ cached.lastAccess = Date.now();
1023
+ return cached.value;
1024
+ }
1025
+ const pendingLoad = pending.get(id);
1026
+ if (pendingLoad) return pendingLoad;
1027
+ onLoadStart?.(id);
1028
+ const loadPromise = loadWithRetry(id, loader).then((value) => {
1029
+ evict();
1030
+ const now = Date.now();
1031
+ cache.set(id, { value, timestamp: now, lastAccess: now, accessCount: 1 });
1032
+ pending.delete(id);
1033
+ onLoadEnd?.(id);
1034
+ return value;
1035
+ }).catch((err) => {
1036
+ pending.delete(id);
1037
+ const error = err instanceof Error ? err : new Error(String(err));
1038
+ onLoadError?.(id, error);
1039
+ throw error;
1040
+ });
1041
+ pending.set(id, loadPromise);
1042
+ return loadPromise;
1043
+ }
1044
+ function preloadFn(id, loader) {
1045
+ if (cache.has(id) || pending.has(id) || preloaded.has(id)) return;
1046
+ preloaded.add(id);
1047
+ loadFn(id, loader).catch(() => {
1048
+ preloaded.delete(id);
1049
+ });
1050
+ }
849
1051
  return {
850
- /**
851
- * Load a chunk by ID. Uses cache if available, otherwise loads via the provided loader.
852
- */
853
- async load(id, loader) {
854
- const cached = cache.get(id);
855
- if (cached && isValid(cached)) {
856
- cached.accessCount++;
857
- return cached.value;
858
- }
859
- const pendingLoad = pending.get(id);
860
- if (pendingLoad) return pendingLoad;
861
- onLoadStart?.(id);
862
- const loadPromise = loadWithRetry(id, loader).then((value) => {
863
- evict();
864
- cache.set(id, { value, timestamp: Date.now(), accessCount: 1 });
865
- pending.delete(id);
866
- onLoadEnd?.(id);
867
- return value;
868
- }).catch((err) => {
869
- pending.delete(id);
870
- const error = err instanceof Error ? err : new Error(String(err));
871
- onLoadError?.(id, error);
872
- throw error;
873
- });
874
- pending.set(id, loadPromise);
875
- return loadPromise;
876
- },
877
- /**
878
- * Preload a chunk without blocking. Silently caches for later use.
879
- */
880
- preload(id, loader) {
881
- if (cache.has(id) || pending.has(id) || preloaded.has(id)) return;
882
- preloaded.add(id);
883
- this.load(id, loader).catch(() => {
884
- });
885
- },
1052
+ load: loadFn,
1053
+ preload: preloadFn,
886
1054
  /**
887
1055
  * Preload multiple chunks in parallel.
888
1056
  */
889
1057
  preloadAll(entries) {
890
1058
  for (const entry of entries) {
891
- this.preload(entry.id, entry.loader);
1059
+ preloadFn(entry.id, entry.loader);
892
1060
  }
893
1061
  },
894
1062
  /**
@@ -905,6 +1073,7 @@ function createChunkRegistry(config = {}) {
905
1073
  const entry = cache.get(id);
906
1074
  if (entry && isValid(entry)) {
907
1075
  entry.accessCount++;
1076
+ entry.lastAccess = Date.now();
908
1077
  return entry.value;
909
1078
  }
910
1079
  return void 0;
@@ -914,6 +1083,7 @@ function createChunkRegistry(config = {}) {
914
1083
  */
915
1084
  invalidate(id) {
916
1085
  cache.delete(id);
1086
+ preloaded.delete(id);
917
1087
  },
918
1088
  /**
919
1089
  * Clear all cached chunks.
@@ -983,8 +1153,8 @@ function preloadModules(urls) {
983
1153
  deferredValue,
984
1154
  denormalize,
985
1155
  devOnly,
986
- domPool,
987
1156
  flushScheduler,
1157
+ getDOMPool,
988
1158
  hoistable,
989
1159
  lazyChunk,
990
1160
  noSideEffect,
@@ -1005,6 +1175,7 @@ function preloadModules(urls) {
1005
1175
  startTransition,
1006
1176
  staticTemplate,
1007
1177
  transitionState,
1178
+ trustHTML,
1008
1179
  uniqueId,
1009
1180
  yieldToMain
1010
1181
  });