sibujs 1.5.0 → 2.1.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 (208) hide show
  1. package/dist/browser.cjs +332 -121
  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 +1049 -344
  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-BMPL52BF.js → chunk-3DZP6OIT.js} +118 -66
  11. package/dist/chunk-3JHCYHWN.js +125 -0
  12. package/dist/{chunk-CZUGLNJS.js → chunk-45YP72ZQ.js} +3 -3
  13. package/dist/{chunk-JCDUJN2F.js → chunk-AMK2TYNW.js} +490 -153
  14. package/dist/{chunk-NHUC2QWH.js → chunk-CWBVQML6.js} +1 -1
  15. package/dist/{chunk-XHK6BDAJ.js → chunk-DRUZZAK4.js} +25 -8
  16. package/dist/{chunk-RJ46C3CS.js → chunk-GWWURC5M.js} +71 -20
  17. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  18. package/dist/{chunk-2BYQDGN3.js → chunk-KGYT6UO6.js} +234 -63
  19. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  20. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  21. package/dist/{chunk-XUEEGU5O.js → chunk-NASX6ST2.js} +16 -4
  22. package/dist/{chunk-VQDZK23A.js → chunk-O6EFQ3KT.js} +181 -66
  23. package/dist/{chunk-BGN5ZMP4.js → chunk-OJ3P4ECI.js} +14 -2
  24. package/dist/chunk-ON5MMR2J.js +1327 -0
  25. package/dist/{chunk-SFKNRVCU.js → chunk-P2HSJDDN.js} +135 -79
  26. package/dist/chunk-QO3WC6FS.js +384 -0
  27. package/dist/{chunk-WZSPOOER.js → chunk-RDTDJCAB.js} +8 -5
  28. package/dist/{chunk-7GRNSCFT.js → chunk-TH2ILCYW.js} +312 -185
  29. package/dist/chunk-UCS6AMJ7.js +79 -0
  30. package/dist/{chunk-VAPYJN4X.js → chunk-V6C4FADE.js} +93 -23
  31. package/dist/{chunk-OUZZEE4S.js → chunk-WANSMF2L.js} +17 -11
  32. package/dist/{chunk-23VV7YD3.js → chunk-WIPZPFBQ.js} +25 -30
  33. package/dist/chunk-WZA53FXU.js +149 -0
  34. package/dist/{chunk-BGTHZHJ5.js → chunk-ZAQSMOED.js} +188 -44
  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 +536 -151
  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 +613 -266
  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 +602 -197
  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 +3500 -1608
  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 +1055 -344
  54. package/dist/index.d.cts +85 -8
  55. package/dist/index.d.ts +85 -8
  56. package/dist/index.js +32 -16
  57. package/dist/{introspect-BumjnBKr.d.cts → introspect-2TOlQ7oa.d.cts} +25 -3
  58. package/dist/{introspect-CZrlcaYy.d.ts → introspect-DnIpHQQz.d.ts} +25 -3
  59. package/dist/motion.cjs +122 -63
  60. package/dist/motion.js +4 -4
  61. package/dist/patterns.cjs +450 -110
  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 +373 -149
  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 +729 -301
  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 +736 -274
  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 +303 -76
  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 +589 -178
  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 +1103 -146
  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-K4G4ZQNR.js +0 -286
  136. package/dist/chunk-K5ZUMYVS.js +0 -89
  137. package/dist/chunk-KQPDEVVS.js +0 -398
  138. package/dist/chunk-L6JRBDNS.js +0 -60
  139. package/dist/chunk-LA6KQEDU.js +0 -712
  140. package/dist/chunk-MB6QFH3I.js +0 -2776
  141. package/dist/chunk-MDVXJWFN.js +0 -304
  142. package/dist/chunk-MEZVEBPN.js +0 -2008
  143. package/dist/chunk-MK4ERFYL.js +0 -2249
  144. package/dist/chunk-MLKGABMK.js +0 -9
  145. package/dist/chunk-MQ5GOYPH.js +0 -2249
  146. package/dist/chunk-MYRV7VDM.js +0 -742
  147. package/dist/chunk-N6IZB6KJ.js +0 -567
  148. package/dist/chunk-NEKUBFPT.js +0 -60
  149. package/dist/chunk-NMRUZALC.js +0 -1097
  150. package/dist/chunk-NYVAC6P5.js +0 -37
  151. package/dist/chunk-NZIIMDWI.js +0 -84
  152. package/dist/chunk-OF7UZIVB.js +0 -725
  153. package/dist/chunk-P3XWXJZU.js +0 -282
  154. package/dist/chunk-P6W3STU4.js +0 -2249
  155. package/dist/chunk-PBHF5WKN.js +0 -616
  156. package/dist/chunk-PDZQY43A.js +0 -616
  157. package/dist/chunk-PTQJDMRT.js +0 -146
  158. package/dist/chunk-PZEGYCF5.js +0 -61
  159. package/dist/chunk-QBMDLBU2.js +0 -975
  160. package/dist/chunk-QWZG56ET.js +0 -2744
  161. package/dist/chunk-RQGQSLQK.js +0 -725
  162. package/dist/chunk-SDLZDHKP.js +0 -107
  163. package/dist/chunk-TDGZL5CU.js +0 -365
  164. package/dist/chunk-TNQWPPE6.js +0 -37
  165. package/dist/chunk-TSOKIX5Z.js +0 -654
  166. package/dist/chunk-UHNL42EF.js +0 -2730
  167. package/dist/chunk-UNXCEF6S.js +0 -21
  168. package/dist/chunk-V2XTI523.js +0 -347
  169. package/dist/chunk-VAU366PN.js +0 -2241
  170. package/dist/chunk-VMVDTCXB.js +0 -712
  171. package/dist/chunk-VQNQZCWJ.js +0 -61
  172. package/dist/chunk-VRW3FULF.js +0 -725
  173. package/dist/chunk-WADYRCO2.js +0 -304
  174. package/dist/chunk-WILQZRO4.js +0 -282
  175. package/dist/chunk-WR5D4EGH.js +0 -26
  176. package/dist/chunk-WUHJISPP.js +0 -298
  177. package/dist/chunk-XYU6TZOW.js +0 -182
  178. package/dist/chunk-Y6GP4QGG.js +0 -276
  179. package/dist/chunk-YECR7UIA.js +0 -347
  180. package/dist/chunk-YUTWTI4B.js +0 -654
  181. package/dist/chunk-Z65KYU7I.js +0 -26
  182. package/dist/chunk-Z6POF5YC.js +0 -975
  183. package/dist/chunk-ZBJP6WFL.js +0 -482
  184. package/dist/chunk-ZD6OAMTH.js +0 -277
  185. package/dist/chunk-ZWKZCBO6.js +0 -317
  186. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  187. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  188. package/dist/contracts-DOrhwbke.d.cts +0 -245
  189. package/dist/contracts-DOrhwbke.d.ts +0 -245
  190. package/dist/contracts-xo5ckdRP.d.cts +0 -240
  191. package/dist/contracts-xo5ckdRP.d.ts +0 -240
  192. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  193. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  194. package/dist/customElement-D2DJp_xn.d.cts +0 -313
  195. package/dist/customElement-D2DJp_xn.d.ts +0 -313
  196. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  197. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  198. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  199. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  200. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  201. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  202. package/dist/ssr-3RXHP5ES.js +0 -38
  203. package/dist/ssr-6GIMY5MX.js +0 -38
  204. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  205. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  206. package/dist/ssr-WKUPVSSK.js +0 -36
  207. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  208. 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,26 +210,39 @@ 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
 
203
222
  // src/reactivity/track.ts
204
223
  var _isDev2 = isDev();
205
- var subscriberStack = new Array(32);
206
- var stackCapacity = 32;
224
+ var STACK_INITIAL = 32;
225
+ var STACK_SHRINK_THRESHOLD = 128;
226
+ var subscriberStack = new Array(STACK_INITIAL);
227
+ var stackCapacity = STACK_INITIAL;
207
228
  var stackTop = -1;
208
229
  var currentSubscriber = null;
209
- var signalSubscribers = /* @__PURE__ */ new WeakMap();
210
230
  var SUBS = "__s";
231
+ function syncFastPath(signal2, subs) {
232
+ const size = subs.size;
233
+ if (size === 0) {
234
+ signal2.__f = void 0;
235
+ delete signal2[SUBS];
236
+ } else if (size === 1) {
237
+ signal2.__f = subs.values().next().value;
238
+ } else {
239
+ signal2.__f = void 0;
240
+ }
241
+ }
211
242
  var notifyDepth = 0;
212
243
  var pendingQueue = [];
213
244
  var pendingSet = /* @__PURE__ */ new Set();
245
+ var propagateStack = [];
214
246
  function safeInvoke(sub) {
215
247
  try {
216
248
  sub();
@@ -233,75 +265,133 @@ function track(effectFn, subscriber) {
233
265
  } finally {
234
266
  stackTop--;
235
267
  currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
268
+ if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
269
+ stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
270
+ subscriberStack.length = stackCapacity;
271
+ }
236
272
  }
237
273
  return () => cleanup(subscriber);
238
274
  }
239
275
  function recordDependency(signal2) {
240
276
  if (!currentSubscriber) return;
241
277
  const sub = currentSubscriber;
242
- if (sub._dep === signal2) return;
278
+ const epoch = sub._epoch;
279
+ if (sub._dep === signal2) {
280
+ sub._depEpoch = epoch;
281
+ return;
282
+ }
243
283
  const deps = sub._deps;
244
284
  if (deps) {
245
- if (deps.has(signal2)) return;
246
- deps.add(signal2);
285
+ deps.set(signal2, epoch);
247
286
  } else if (sub._dep !== void 0) {
248
- const set = /* @__PURE__ */ new Set();
249
- set.add(sub._dep);
250
- set.add(signal2);
251
- sub._deps = set;
287
+ const map = /* @__PURE__ */ new Map();
288
+ map.set(sub._dep, sub._depEpoch);
289
+ map.set(signal2, epoch);
290
+ sub._deps = map;
252
291
  sub._dep = void 0;
292
+ sub._depEpoch = void 0;
253
293
  } else {
254
294
  sub._dep = signal2;
295
+ sub._depEpoch = epoch;
255
296
  }
256
- let subs = signal2[SUBS];
297
+ const sig = signal2;
298
+ let subs = sig[SUBS];
257
299
  if (!subs) {
258
300
  subs = /* @__PURE__ */ new Set();
259
- signalSubscribers.set(signal2, subs);
260
- signal2[SUBS] = subs;
301
+ sig[SUBS] = subs;
261
302
  }
303
+ const prevSize = subs.size;
262
304
  subs.add(currentSubscriber);
263
- if (subs.size === 1) {
264
- signal2.__f = currentSubscriber;
265
- } else if (signal2.__f !== void 0) {
266
- signal2.__f = void 0;
305
+ if (subs.size !== prevSize) {
306
+ if (subs.size === 1) {
307
+ sig.__f = currentSubscriber;
308
+ } else if (sig.__f !== void 0) {
309
+ sig.__f = void 0;
310
+ }
311
+ }
312
+ }
313
+ var maxSubscriberRepeats = 50;
314
+ var maxDrainIterations = 1e6;
315
+ var drainEpoch = 0;
316
+ function tickRepeat(sub) {
317
+ const s = sub;
318
+ if (s._runEpoch !== drainEpoch) {
319
+ s._runEpoch = drainEpoch;
320
+ s._runs = 1;
321
+ return false;
322
+ }
323
+ return ++s._runs > maxSubscriberRepeats;
324
+ }
325
+ function cycleError(sub) {
326
+ if (typeof console !== "undefined") {
327
+ const name = sub.__name ?? "<unnamed>";
328
+ console.error(
329
+ `[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
330
+ );
331
+ }
332
+ }
333
+ function absoluteDrainError() {
334
+ if (typeof console !== "undefined") {
335
+ console.error(
336
+ `[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
337
+ );
338
+ }
339
+ }
340
+ function drainQueue() {
341
+ let i = 0;
342
+ while (i < pendingQueue.length) {
343
+ if (i >= maxDrainIterations) {
344
+ absoluteDrainError();
345
+ break;
346
+ }
347
+ const sub = pendingQueue[i++];
348
+ if (tickRepeat(sub)) {
349
+ cycleError(sub);
350
+ break;
351
+ }
352
+ pendingSet.delete(sub);
353
+ safeInvoke(sub);
267
354
  }
268
355
  }
269
356
  function propagateDirty(sub) {
270
357
  sub();
271
- let sig = sub._sig;
272
- while (sig) {
358
+ const rootSig = sub._sig;
359
+ if (!rootSig) return;
360
+ const stack = propagateStack;
361
+ const baseLen = stack.length;
362
+ stack.push(rootSig);
363
+ while (stack.length > baseLen) {
364
+ const sig = stack.pop();
273
365
  const first = sig.__f;
274
366
  if (first) {
275
367
  if (first._c) {
276
368
  const nSig = first._sig;
277
- nSig._d = true;
278
- sig = nSig;
279
- continue;
280
- }
281
- if (!pendingSet.has(first)) {
369
+ if (!nSig._d) {
370
+ nSig._d = true;
371
+ stack.push(nSig);
372
+ }
373
+ } else if (!pendingSet.has(first)) {
282
374
  pendingSet.add(first);
283
375
  pendingQueue.push(first);
284
376
  }
285
- break;
377
+ continue;
286
378
  }
287
379
  const subs = sig[SUBS];
288
- if (!subs) break;
289
- let nextSig;
380
+ if (!subs) continue;
290
381
  for (const s of subs) {
291
382
  if (s._c) {
292
- s();
293
383
  const nSig = s._sig;
294
- if (nSig && !nextSig) {
295
- nextSig = nSig;
296
- } else if (nSig) {
297
- propagateDirty(s);
384
+ if (nSig && !nSig._d) {
385
+ nSig._d = true;
386
+ stack.push(nSig);
387
+ } else if (!nSig) {
388
+ s();
298
389
  }
299
390
  } else if (!pendingSet.has(s)) {
300
391
  pendingSet.add(s);
301
392
  pendingQueue.push(s);
302
393
  }
303
394
  }
304
- sig = nextSig;
305
395
  }
306
396
  }
307
397
  function notifySubscribers(signal2) {
@@ -317,21 +407,22 @@ function notifySubscribers(signal2) {
317
407
  return;
318
408
  }
319
409
  notifyDepth++;
410
+ drainEpoch++;
320
411
  try {
321
412
  if (first._c) {
322
413
  propagateDirty(first);
414
+ } else if (tickRepeat(first)) {
415
+ cycleError(first);
323
416
  } else {
324
417
  safeInvoke(first);
325
418
  }
326
- let i = 0;
327
- while (i < pendingQueue.length) {
328
- safeInvoke(pendingQueue[i]);
329
- i++;
330
- }
419
+ drainQueue();
331
420
  } finally {
332
- pendingQueue.length = 0;
333
- pendingSet.clear();
334
421
  notifyDepth--;
422
+ if (notifyDepth === 0) {
423
+ pendingQueue.length = 0;
424
+ pendingSet.clear();
425
+ }
335
426
  }
336
427
  return;
337
428
  }
@@ -349,66 +440,73 @@ function notifySubscribers(signal2) {
349
440
  return;
350
441
  }
351
442
  notifyDepth++;
443
+ drainEpoch++;
352
444
  try {
353
- let directCount = 0;
354
445
  for (const sub of subs) {
355
- pendingQueue[directCount++] = sub;
356
- }
357
- for (let i2 = 0; i2 < directCount; i2++) {
358
- if (pendingQueue[i2]._c) {
359
- propagateDirty(pendingQueue[i2]);
360
- }
361
- }
362
- for (let i2 = 0; i2 < directCount; i2++) {
363
- if (!pendingQueue[i2]._c) {
364
- if (!pendingSet.has(pendingQueue[i2])) {
365
- safeInvoke(pendingQueue[i2]);
366
- }
446
+ if (sub._c) {
447
+ propagateDirty(sub);
448
+ } else if (!pendingSet.has(sub)) {
449
+ pendingSet.add(sub);
450
+ pendingQueue.push(sub);
367
451
  }
368
452
  }
369
- let i = directCount;
370
- while (i < pendingQueue.length) {
371
- safeInvoke(pendingQueue[i]);
372
- i++;
373
- }
453
+ drainQueue();
374
454
  } finally {
375
- pendingQueue.length = 0;
376
- pendingSet.clear();
377
455
  notifyDepth--;
456
+ if (notifyDepth === 0) {
457
+ pendingQueue.length = 0;
458
+ pendingSet.clear();
459
+ }
378
460
  }
379
461
  }
380
462
  function cleanup(subscriber) {
381
463
  const sub = subscriber;
382
464
  const singleDep = sub._dep;
383
465
  if (singleDep !== void 0) {
384
- const subs = singleDep[SUBS];
385
- if (subs) {
386
- subs.delete(subscriber);
387
- if (singleDep.__f === subscriber) {
388
- singleDep.__f = void 0;
389
- }
466
+ const sig = singleDep;
467
+ const subs = sig[SUBS];
468
+ if (subs?.delete(subscriber)) {
469
+ syncFastPath(sig, subs);
390
470
  }
391
471
  sub._dep = void 0;
472
+ sub._depEpoch = void 0;
392
473
  return;
393
474
  }
394
475
  const deps = sub._deps;
395
476
  if (!deps || deps.size === 0) return;
396
- for (const signal2 of deps) {
397
- const subs = signal2[SUBS];
398
- if (subs) {
399
- subs.delete(subscriber);
400
- if (signal2.__f === subscriber) {
401
- signal2.__f = void 0;
402
- }
477
+ for (const signal2 of deps.keys()) {
478
+ const sig = signal2;
479
+ const subs = sig[SUBS];
480
+ if (subs?.delete(subscriber)) {
481
+ syncFastPath(sig, subs);
403
482
  }
404
483
  }
405
484
  deps.clear();
406
485
  }
407
486
 
408
487
  // src/core/ssr-context.ts
409
- var ssrMode = false;
488
+ var als = null;
489
+ try {
490
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
491
+ const req = Function("return typeof require==='function'?require:null")();
492
+ if (req) {
493
+ const mod = req("node:async_hooks");
494
+ als = new mod.AsyncLocalStorage();
495
+ }
496
+ }
497
+ } catch {
498
+ als = null;
499
+ }
500
+ var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
501
+ function getSSRStore() {
502
+ if (als) {
503
+ const s = als.getStore();
504
+ if (s) return s;
505
+ }
506
+ return fallbackStore;
507
+ }
410
508
  function isSSR() {
411
- return ssrMode;
509
+ return getSSRStore().ssr;
412
510
  }
413
511
 
414
512
  // src/core/signals/effect.ts
@@ -418,26 +516,114 @@ function effect(effectFn, options) {
418
516
  if (isSSR()) return () => {
419
517
  };
420
518
  const onError = options?.onError;
519
+ let userCleanups = [];
520
+ const onCleanup = (fn) => {
521
+ userCleanups.push(fn);
522
+ };
523
+ const runUserCleanups = () => {
524
+ if (userCleanups.length === 0) return;
525
+ const list = userCleanups;
526
+ userCleanups = [];
527
+ for (let i = list.length - 1; i >= 0; i--) {
528
+ try {
529
+ list[i]();
530
+ } catch (err) {
531
+ if (typeof console !== "undefined") {
532
+ console.warn("[SibuJS effect] onCleanup threw:", err);
533
+ }
534
+ }
535
+ }
536
+ };
537
+ const invokeBody = () => effectFn(onCleanup);
421
538
  const wrappedFn = onError ? () => {
422
539
  try {
423
- effectFn();
540
+ invokeBody();
424
541
  } catch (err) {
425
542
  onError(err);
426
543
  }
427
- } : effectFn;
544
+ } : invokeBody;
428
545
  let cleanupHandle = () => {
429
546
  };
547
+ let running = false;
548
+ let rerunPending = false;
549
+ const MAX_RERUNS = 100;
430
550
  const subscriber = () => {
431
- cleanupHandle();
432
- cleanupHandle = track(wrappedFn, subscriber);
551
+ if (running) {
552
+ rerunPending = true;
553
+ return;
554
+ }
555
+ running = true;
556
+ try {
557
+ let reruns = 0;
558
+ do {
559
+ rerunPending = false;
560
+ runUserCleanups();
561
+ cleanupHandle();
562
+ cleanupHandle = track(wrappedFn, subscriber);
563
+ if (++reruns > MAX_RERUNS) {
564
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
565
+ console.error(
566
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
567
+ );
568
+ }
569
+ rerunPending = false;
570
+ break;
571
+ }
572
+ } while (rerunPending);
573
+ } finally {
574
+ running = false;
575
+ rerunPending = false;
576
+ }
433
577
  };
434
- cleanupHandle = track(wrappedFn, subscriber);
578
+ running = true;
579
+ try {
580
+ let reruns = 0;
581
+ do {
582
+ rerunPending = false;
583
+ runUserCleanups();
584
+ cleanupHandle();
585
+ cleanupHandle = track(wrappedFn, subscriber);
586
+ if (++reruns > MAX_RERUNS) {
587
+ if (_g.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
588
+ console.error(
589
+ `[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
590
+ );
591
+ }
592
+ rerunPending = false;
593
+ break;
594
+ }
595
+ } while (rerunPending);
596
+ } finally {
597
+ running = false;
598
+ rerunPending = false;
599
+ }
435
600
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
436
601
  if (hook) hook.emit("effect:create", { effectFn });
602
+ let disposed = false;
437
603
  return () => {
604
+ if (disposed) return;
605
+ disposed = true;
438
606
  const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
439
- if (h) h.emit("effect:destroy", { effectFn });
440
- cleanupHandle();
607
+ if (h) {
608
+ try {
609
+ h.emit("effect:destroy", { effectFn });
610
+ } catch {
611
+ }
612
+ }
613
+ try {
614
+ runUserCleanups();
615
+ } catch (err) {
616
+ if (typeof console !== "undefined") {
617
+ console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
618
+ }
619
+ }
620
+ try {
621
+ cleanupHandle();
622
+ } catch (err) {
623
+ if (typeof console !== "undefined") {
624
+ console.warn("[SibuJS effect] dispose threw:", err);
625
+ }
626
+ }
441
627
  };
442
628
  }
443
629
 
@@ -528,6 +714,7 @@ function uniqueId(suffix) {
528
714
  }
529
715
 
530
716
  // src/performance/domRecycler.ts
717
+ var _isDev4 = isDev();
531
718
  var DOMPool = class {
532
719
  constructor(maxSize = 50) {
533
720
  this.pools = /* @__PURE__ */ new Map();
@@ -547,8 +734,18 @@ var DOMPool = class {
547
734
  /**
548
735
  * Return an element to the pool for reuse.
549
736
  * Clears attributes, children, and event listeners.
737
+ *
738
+ * Contract: the caller MUST detach the element from the DOM (and run any
739
+ * `dispose()` on bound reactive subscriptions) BEFORE calling `release()`.
740
+ * Releasing a connected element leaves it visible while it is mutated and
741
+ * is almost certainly a bug.
550
742
  */
551
743
  release(element) {
744
+ if (_isDev4 && element.isConnected) {
745
+ devWarn(
746
+ "DOMPool.release() called on a still-connected element. Detach it from the DOM first (remove() / dispose())."
747
+ );
748
+ }
552
749
  const tag = element.tagName.toLowerCase();
553
750
  let pool = this.pools.get(tag);
554
751
  if (!pool) {
@@ -584,7 +781,11 @@ var DOMPool = class {
584
781
  return result;
585
782
  }
586
783
  };
587
- var domPool = new DOMPool();
784
+ var _defaultPool = null;
785
+ function getDOMPool() {
786
+ if (_defaultPool === null) _defaultPool = new DOMPool();
787
+ return _defaultPool;
788
+ }
588
789
  var preloadedResources = /* @__PURE__ */ new Set();
589
790
  function preloadResource(url, type = "fetch") {
590
791
  if (preloadedResources.has(url)) return;
@@ -647,6 +848,13 @@ function noSideEffect(fn) {
647
848
  return fn;
648
849
  }
649
850
 
851
+ // src/platform/ssr.ts
852
+ var _isDev5 = isDev();
853
+ function trustHTML(html) {
854
+ return html;
855
+ }
856
+ var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
857
+
650
858
  // src/performance/compiled.ts
651
859
  function staticTemplate(html) {
652
860
  const template = document.createElement("template");
@@ -814,31 +1022,45 @@ function createChunkRegistry(config = {}) {
814
1022
  const pending = /* @__PURE__ */ new Map();
815
1023
  const preloaded = /* @__PURE__ */ new Set();
816
1024
  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;
1025
+ while (cache.size >= maxCacheSize) {
1026
+ let lru = null;
1027
+ let lruTime = Infinity;
1028
+ for (const [key, entry] of cache) {
1029
+ if (entry.lastAccess < lruTime) {
1030
+ lruTime = entry.lastAccess;
1031
+ lru = key;
1032
+ }
824
1033
  }
1034
+ if (!lru) return;
1035
+ cache.delete(lru);
825
1036
  }
826
- if (oldest) cache.delete(oldest);
827
1037
  }
828
1038
  function isValid(entry) {
829
1039
  if (cacheTTL === 0) return true;
830
1040
  return Date.now() - entry.timestamp < cacheTTL;
831
1041
  }
832
1042
  async function loadWithRetry(id, loader, attempt = 0) {
1043
+ let timeoutHandle = null;
833
1044
  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());
1045
+ const result = await (timeout > 0 ? new Promise((resolve, reject) => {
1046
+ timeoutHandle = setTimeout(
1047
+ () => reject(new Error(`Chunk '${id}' loading timed out after ${timeout}ms`)),
1048
+ timeout
1049
+ );
1050
+ loader().then(
1051
+ (v) => {
1052
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
1053
+ resolve(v);
1054
+ },
1055
+ (e) => {
1056
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
1057
+ reject(e);
1058
+ }
1059
+ );
1060
+ }) : loader());
840
1061
  return result;
841
1062
  } catch (err) {
1063
+ if (timeoutHandle !== null) clearTimeout(timeoutHandle);
842
1064
  if (attempt < retries) {
843
1065
  await new Promise((r) => setTimeout(r, retryDelay * (attempt + 1)));
844
1066
  return loadWithRetry(id, loader, attempt + 1);
@@ -846,49 +1068,48 @@ function createChunkRegistry(config = {}) {
846
1068
  throw err;
847
1069
  }
848
1070
  }
1071
+ async function loadFn(id, loader) {
1072
+ const cached = cache.get(id);
1073
+ if (cached && isValid(cached)) {
1074
+ cached.accessCount++;
1075
+ cached.lastAccess = Date.now();
1076
+ return cached.value;
1077
+ }
1078
+ const pendingLoad = pending.get(id);
1079
+ if (pendingLoad) return pendingLoad;
1080
+ onLoadStart?.(id);
1081
+ const loadPromise = loadWithRetry(id, loader).then((value) => {
1082
+ evict();
1083
+ const now = Date.now();
1084
+ cache.set(id, { value, timestamp: now, lastAccess: now, accessCount: 1 });
1085
+ pending.delete(id);
1086
+ onLoadEnd?.(id);
1087
+ return value;
1088
+ }).catch((err) => {
1089
+ pending.delete(id);
1090
+ const error = err instanceof Error ? err : new Error(String(err));
1091
+ onLoadError?.(id, error);
1092
+ throw error;
1093
+ });
1094
+ pending.set(id, loadPromise);
1095
+ return loadPromise;
1096
+ }
1097
+ function preloadFn(id, loader) {
1098
+ if (cache.has(id) || pending.has(id) || preloaded.has(id)) return;
1099
+ preloaded.add(id);
1100
+ loadFn(id, loader).catch(() => {
1101
+ preloaded.delete(id);
1102
+ });
1103
+ }
849
1104
  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
- },
1105
+ load: loadFn,
1106
+ preload: preloadFn,
886
1107
  /**
887
1108
  * Preload multiple chunks in parallel.
888
1109
  */
889
1110
  preloadAll(entries) {
890
1111
  for (const entry of entries) {
891
- this.preload(entry.id, entry.loader);
1112
+ preloadFn(entry.id, entry.loader);
892
1113
  }
893
1114
  },
894
1115
  /**
@@ -905,6 +1126,7 @@ function createChunkRegistry(config = {}) {
905
1126
  const entry = cache.get(id);
906
1127
  if (entry && isValid(entry)) {
907
1128
  entry.accessCount++;
1129
+ entry.lastAccess = Date.now();
908
1130
  return entry.value;
909
1131
  }
910
1132
  return void 0;
@@ -914,6 +1136,7 @@ function createChunkRegistry(config = {}) {
914
1136
  */
915
1137
  invalidate(id) {
916
1138
  cache.delete(id);
1139
+ preloaded.delete(id);
917
1140
  },
918
1141
  /**
919
1142
  * Clear all cached chunks.
@@ -983,8 +1206,8 @@ function preloadModules(urls) {
983
1206
  deferredValue,
984
1207
  denormalize,
985
1208
  devOnly,
986
- domPool,
987
1209
  flushScheduler,
1210
+ getDOMPool,
988
1211
  hoistable,
989
1212
  lazyChunk,
990
1213
  noSideEffect,
@@ -1005,6 +1228,7 @@ function preloadModules(urls) {
1005
1228
  startTransition,
1006
1229
  staticTemplate,
1007
1230
  transitionState,
1231
+ trustHTML,
1008
1232
  uniqueId,
1009
1233
  yieldToMain
1010
1234
  });