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
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  derived
3
- } from "./chunk-XHK6BDAJ.js";
3
+ } from "./chunk-54EDRCEF.js";
4
4
  import {
5
5
  effect
6
- } from "./chunk-VQNQZCWJ.js";
6
+ } from "./chunk-HB24TBAF.js";
7
7
  import {
8
+ batch,
8
9
  signal
9
- } from "./chunk-NZIIMDWI.js";
10
+ } from "./chunk-CC65Y57T.js";
10
11
 
11
12
  // src/patterns/machine.ts
12
13
  function machine(config) {
@@ -74,7 +75,11 @@ function machine(config) {
74
75
  function persisted(key, initial, options = {}) {
75
76
  const storage = options.session ? sessionStorage : localStorage;
76
77
  const serialize = options.serialize || JSON.stringify;
77
- const deserialize = options.deserialize || JSON.parse;
78
+ const safeReviver = (k, v) => {
79
+ if (k === "__proto__" || k === "constructor" || k === "prototype") return void 0;
80
+ return v;
81
+ };
82
+ const deserialize = options.deserialize || ((raw) => JSON.parse(raw, safeReviver));
78
83
  const encrypt = options.encrypt;
79
84
  const decrypt = options.decrypt;
80
85
  const syncTabs = options.session ? false : options.syncTabs ?? true;
@@ -178,6 +183,27 @@ function optimisticList(initialValue) {
178
183
  const [pending, setPending] = signal(false);
179
184
  let inflightCount = 0;
180
185
  let version = 0;
186
+ let tempIdCounter = 0;
187
+ const itemIds = /* @__PURE__ */ new WeakMap();
188
+ const idToItem = /* @__PURE__ */ new Map();
189
+ function tagItem(item) {
190
+ const id = ++tempIdCounter;
191
+ if (item !== null && typeof item === "object") {
192
+ itemIds.set(item, id);
193
+ }
194
+ idToItem.set(id, item);
195
+ return id;
196
+ }
197
+ function findIndexById(list, id) {
198
+ for (let i = 0; i < list.length; i++) {
199
+ const it = list[i];
200
+ if (it !== null && typeof it === "object" && itemIds.get(it) === id) {
201
+ return i;
202
+ }
203
+ if (Object.is(it, idToItem.get(id))) return i;
204
+ }
205
+ return -1;
206
+ }
181
207
  function begin() {
182
208
  const v = ++version;
183
209
  inflightCount++;
@@ -193,12 +219,13 @@ function optimisticList(initialValue) {
193
219
  }
194
220
  async function add(item, asyncAction) {
195
221
  const prev = items();
222
+ const id = tagItem(item);
196
223
  setItems([...prev, item]);
197
224
  const myVersion = begin();
198
225
  try {
199
226
  const result = await asyncAction();
200
227
  setItems((current) => {
201
- const idx = current.lastIndexOf(item);
228
+ const idx = findIndexById(current, id);
202
229
  if (idx >= 0) {
203
230
  const next = [...current];
204
231
  next[idx] = result;
@@ -206,8 +233,10 @@ function optimisticList(initialValue) {
206
233
  }
207
234
  return [...current, result];
208
235
  });
236
+ idToItem.delete(id);
209
237
  end(myVersion);
210
238
  } catch {
239
+ idToItem.delete(id);
211
240
  end(myVersion, () => setItems(prev));
212
241
  }
213
242
  }
@@ -224,12 +253,13 @@ function optimisticList(initialValue) {
224
253
  }
225
254
  async function updateItem(predicate, patch, asyncAction) {
226
255
  const prev = items();
227
- const patchedRefs = [];
256
+ const patchedIds = [];
228
257
  setItems(
229
258
  prev.map((item) => {
230
259
  if (predicate(item)) {
231
260
  const patched = { ...item, ...patch };
232
- patchedRefs.push(patched);
261
+ const id = tagItem(patched);
262
+ patchedIds.push(id);
233
263
  return patched;
234
264
  }
235
265
  return item;
@@ -238,9 +268,19 @@ function optimisticList(initialValue) {
238
268
  const myVersion = begin();
239
269
  try {
240
270
  const result = await asyncAction();
241
- setItems((current) => current.map((item) => patchedRefs.includes(item) ? result : item));
271
+ setItems(
272
+ (current) => current.map((item) => {
273
+ if (item !== null && typeof item === "object") {
274
+ const existingId = itemIds.get(item);
275
+ if (existingId !== void 0 && patchedIds.includes(existingId)) return result;
276
+ }
277
+ return item;
278
+ })
279
+ );
280
+ for (const id of patchedIds) idToItem.delete(id);
242
281
  end(myVersion);
243
282
  } catch {
283
+ for (const id of patchedIds) idToItem.delete(id);
244
284
  end(myVersion, () => setItems(prev));
245
285
  }
246
286
  }
@@ -249,10 +289,7 @@ function optimisticList(initialValue) {
249
289
  pending,
250
290
  add,
251
291
  remove,
252
- update: updateItem,
253
- addOptimistic: add,
254
- removeOptimistic: remove,
255
- updateOptimistic: updateItem
292
+ update: updateItem
256
293
  };
257
294
  }
258
295
 
@@ -271,14 +308,16 @@ function timeline(initial, maxHistory = 100) {
271
308
  const idx = index();
272
309
  const newHistory = hist.slice(0, idx + 1);
273
310
  newHistory.push(newValue);
274
- if (newHistory.length > maxHistory) {
275
- newHistory.shift();
276
- setHistory(newHistory);
277
- setIndex(newHistory.length - 1);
278
- } else {
279
- setHistory(newHistory);
280
- setIndex(idx + 1);
281
- }
311
+ batch(() => {
312
+ if (newHistory.length > maxHistory) {
313
+ newHistory.shift();
314
+ setHistory(newHistory);
315
+ setIndex(newHistory.length - 1);
316
+ } else {
317
+ setHistory(newHistory);
318
+ setIndex(idx + 1);
319
+ }
320
+ });
282
321
  }
283
322
  function undo() {
284
323
  if (canUndo()) {
@@ -291,8 +330,10 @@ function timeline(initial, maxHistory = 100) {
291
330
  }
292
331
  }
293
332
  function reset() {
294
- setHistory([initial]);
295
- setIndex(0);
333
+ batch(() => {
334
+ setHistory([initial]);
335
+ setIndex(0);
336
+ });
296
337
  }
297
338
  function jumpTo(targetIndex) {
298
339
  const hist = history();
@@ -304,8 +345,37 @@ function timeline(initial, maxHistory = 100) {
304
345
  }
305
346
 
306
347
  // src/patterns/globalStore.ts
348
+ function deepClone(value) {
349
+ if (typeof structuredClone === "function") {
350
+ return structuredClone(value);
351
+ }
352
+ const seen = /* @__PURE__ */ new WeakSet();
353
+ const clone = (v) => {
354
+ if (v === null || typeof v !== "object") return v;
355
+ if (seen.has(v)) throw new Error("deepClone: circular reference");
356
+ seen.add(v);
357
+ if (v instanceof Date) return new Date(v.getTime());
358
+ if (v instanceof Map) {
359
+ const out2 = /* @__PURE__ */ new Map();
360
+ for (const [k, val] of v) out2.set(clone(k), clone(val));
361
+ return out2;
362
+ }
363
+ if (v instanceof Set) {
364
+ const out2 = /* @__PURE__ */ new Set();
365
+ for (const val of v) out2.add(clone(val));
366
+ return out2;
367
+ }
368
+ if (Array.isArray(v)) return v.map(clone);
369
+ const out = {};
370
+ for (const k of Object.keys(v)) {
371
+ out[k] = clone(v[k]);
372
+ }
373
+ return out;
374
+ };
375
+ return clone(value);
376
+ }
307
377
  function globalStore(config) {
308
- const initialState = JSON.parse(JSON.stringify(config.state));
378
+ const initialState = deepClone(config.state);
309
379
  const [getState, setState] = signal({ ...initialState });
310
380
  const listeners = /* @__PURE__ */ new Set();
311
381
  const middlewares = config.middleware || [];
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  effect
3
- } from "./chunk-VQNQZCWJ.js";
3
+ } from "./chunk-HB24TBAF.js";
4
4
  import {
5
5
  batch,
6
6
  signal
7
- } from "./chunk-NZIIMDWI.js";
7
+ } from "./chunk-CC65Y57T.js";
8
8
 
9
9
  // src/browser/media.ts
10
10
  function media(query) {
@@ -399,7 +399,10 @@ function dropZone(element, options) {
399
399
  const raw = e.dataTransfer.getData("application/json");
400
400
  if (raw) {
401
401
  try {
402
- transferData = JSON.parse(raw);
402
+ transferData = JSON.parse(
403
+ raw,
404
+ (k, v) => k === "__proto__" || k === "constructor" || k === "prototype" ? void 0 : v
405
+ );
403
406
  } catch {
404
407
  transferData = raw;
405
408
  }
@@ -779,13 +782,21 @@ function wakeLock() {
779
782
  }
780
783
  const onVisibility = () => {
781
784
  if (sentinel?.released && !document.hidden) {
782
- void request();
785
+ request().catch((err) => {
786
+ if (typeof console !== "undefined") {
787
+ console.warn("[SibuJS wakeLock] re-acquire failed:", err);
788
+ }
789
+ });
783
790
  }
784
791
  };
785
792
  document.addEventListener("visibilitychange", onVisibility);
786
793
  function dispose() {
787
794
  document.removeEventListener("visibilitychange", onVisibility);
788
- void release();
795
+ release().catch((err) => {
796
+ if (typeof console !== "undefined") {
797
+ console.warn("[SibuJS wakeLock] release failed:", err);
798
+ }
799
+ });
789
800
  }
790
801
  return { active, request, release, dispose };
791
802
  }
@@ -981,11 +992,21 @@ function speech() {
981
992
  };
982
993
  }
983
994
  const synth = window.speechSynthesis;
984
- const interval = setInterval(() => {
985
- setSpeaking(synth.speaking);
986
- setPaused(synth.paused);
987
- }, 200);
995
+ let interval = null;
996
+ function startPolling() {
997
+ if (interval !== null) return;
998
+ interval = setInterval(() => {
999
+ setSpeaking(synth.speaking);
1000
+ setPaused(synth.paused);
1001
+ if (!synth.speaking && !synth.paused) {
1002
+ clearInterval(interval);
1003
+ interval = null;
1004
+ }
1005
+ }, 200);
1006
+ }
1007
+ let disposed = false;
988
1008
  function speak(text, options = {}) {
1009
+ if (disposed) return;
989
1010
  const u = new SpeechSynthesisUtterance(text);
990
1011
  if (options.lang) u.lang = options.lang;
991
1012
  if (options.rate != null) u.rate = options.rate;
@@ -996,19 +1017,41 @@ function speech() {
996
1017
  const match = voices.find((v) => v.name === options.voice);
997
1018
  if (match) u.voice = match;
998
1019
  }
999
- u.addEventListener("start", () => setSpeaking(true));
1000
- u.addEventListener("end", () => {
1001
- setSpeaking(false);
1002
- setPaused(false);
1003
- });
1004
- u.addEventListener("error", () => {
1005
- setSpeaking(false);
1006
- setPaused(false);
1007
- });
1020
+ u.addEventListener(
1021
+ "start",
1022
+ () => {
1023
+ if (!disposed) setSpeaking(true);
1024
+ },
1025
+ { once: true }
1026
+ );
1027
+ u.addEventListener(
1028
+ "end",
1029
+ () => {
1030
+ if (disposed) return;
1031
+ setSpeaking(false);
1032
+ setPaused(false);
1033
+ },
1034
+ { once: true }
1035
+ );
1036
+ u.addEventListener(
1037
+ "error",
1038
+ () => {
1039
+ if (disposed) return;
1040
+ setSpeaking(false);
1041
+ setPaused(false);
1042
+ },
1043
+ { once: true }
1044
+ );
1008
1045
  synth.speak(u);
1046
+ setSpeaking(true);
1047
+ startPolling();
1009
1048
  }
1010
1049
  function dispose() {
1011
- clearInterval(interval);
1050
+ disposed = true;
1051
+ if (interval !== null) {
1052
+ clearInterval(interval);
1053
+ interval = null;
1054
+ }
1012
1055
  synth.cancel();
1013
1056
  }
1014
1057
  return {
@@ -1237,13 +1280,21 @@ function imageLoader(src) {
1237
1280
  };
1238
1281
  img.src = url;
1239
1282
  }
1283
+ let srcEffectTeardown = null;
1240
1284
  if (typeof src === "function") {
1241
- start(src());
1285
+ srcEffectTeardown = effect(() => {
1286
+ const url = src();
1287
+ start(url);
1288
+ });
1242
1289
  } else {
1243
1290
  start(src);
1244
1291
  }
1245
1292
  function dispose() {
1246
1293
  disposed = true;
1294
+ if (srcEffectTeardown) {
1295
+ srcEffectTeardown();
1296
+ srcEffectTeardown = null;
1297
+ }
1247
1298
  if (current) {
1248
1299
  current.onload = null;
1249
1300
  current.onerror = null;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  signal
3
- } from "./chunk-NZIIMDWI.js";
3
+ } from "./chunk-CC65Y57T.js";
4
4
 
5
5
  // src/ui/transition.ts
6
6
  function transition(element, options = {}) {
@@ -345,15 +345,24 @@ function springSignal(initial, options) {
345
345
  let velocity = 0;
346
346
  let target = initial;
347
347
  let rafId = null;
348
- function tick() {
348
+ let lastTime = 0;
349
+ const REF_DT_MS = 1e3 / 60;
350
+ const MAX_STEP_RATIO = 4;
351
+ function tick(now) {
352
+ if (lastTime === 0) lastTime = now;
353
+ const rawDt = now - lastTime;
354
+ lastTime = now;
355
+ const dt = Number.isFinite(rawDt) && rawDt > 0 ? rawDt : REF_DT_MS;
356
+ const ratio = Math.min(MAX_STEP_RATIO, Math.max(0.1, dt / REF_DT_MS));
349
357
  const force = -stiffness * (current - target);
350
358
  const dampingForce = -damping * velocity;
351
- velocity += force + dampingForce;
352
- current += velocity;
359
+ velocity += (force + dampingForce) * ratio;
360
+ current += velocity * ratio;
353
361
  if (Math.abs(current - target) < precision && Math.abs(velocity) < precision) {
354
362
  current = target;
355
363
  velocity = 0;
356
364
  rafId = null;
365
+ lastTime = 0;
357
366
  setValue(current);
358
367
  return;
359
368
  }
@@ -369,10 +378,12 @@ function springSignal(initial, options) {
369
378
  cancelAnimationFrame(rafId);
370
379
  rafId = null;
371
380
  }
381
+ lastTime = 0;
372
382
  setValue(current);
373
383
  return;
374
384
  }
375
385
  if (rafId === null) {
386
+ lastTime = 0;
376
387
  rafId = requestAnimationFrame(tick);
377
388
  }
378
389
  }
@@ -381,6 +392,7 @@ function springSignal(initial, options) {
381
392
  cancelAnimationFrame(rafId);
382
393
  rafId = null;
383
394
  }
395
+ lastTime = 0;
384
396
  }
385
397
  return [value, set, dispose];
386
398
  }
@@ -1,16 +1,18 @@
1
1
  import {
2
2
  recordDependency,
3
+ retrack,
3
4
  track,
4
5
  trackingSuspended
5
- } from "./chunk-K4G4ZQNR.js";
6
+ } from "./chunk-VLPPXTYG.js";
6
7
  import {
7
8
  devAssert
8
- } from "./chunk-5X6PP2UK.js";
9
+ } from "./chunk-LMLD24FC.js";
9
10
 
10
11
  // src/core/signals/derived.ts
11
12
  function derived(getter, options) {
12
13
  devAssert(typeof getter === "function", "derived: argument must be a getter function.");
13
14
  const debugName = options?.name;
15
+ const equals = options?.equals;
14
16
  const cs = {};
15
17
  cs._d = false;
16
18
  cs._g = getter;
@@ -21,8 +23,14 @@ function derived(getter, options) {
21
23
  markDirty._c = 1;
22
24
  markDirty._sig = cs;
23
25
  track(() => {
24
- cs._d = false;
25
- cs._v = getter();
26
+ let threw = true;
27
+ try {
28
+ cs._v = getter();
29
+ cs._d = false;
30
+ threw = false;
31
+ } finally {
32
+ if (threw) cs._d = true;
33
+ }
26
34
  }, markDirty);
27
35
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
28
36
  let evaluating = false;
@@ -35,11 +43,16 @@ function derived(getter, options) {
35
43
  if (trackingSuspended) {
36
44
  if (cs._d) {
37
45
  evaluating = true;
46
+ let threw = true;
38
47
  try {
39
- cs._d = false;
40
- cs._v = getter();
48
+ retrack(() => {
49
+ cs._v = getter();
50
+ cs._d = false;
51
+ threw = false;
52
+ }, markDirty);
41
53
  } finally {
42
54
  evaluating = false;
55
+ if (threw) cs._d = true;
43
56
  }
44
57
  }
45
58
  return cs._v;
@@ -48,13 +61,17 @@ function derived(getter, options) {
48
61
  if (cs._d) {
49
62
  const oldValue = cs._v;
50
63
  evaluating = true;
64
+ let threw = true;
51
65
  try {
52
- track(() => {
66
+ retrack(() => {
67
+ const next = getter();
68
+ cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
53
69
  cs._d = false;
54
- cs._v = getter();
70
+ threw = false;
55
71
  }, markDirty);
56
72
  } finally {
57
73
  evaluating = false;
74
+ if (threw) cs._d = true;
58
75
  }
59
76
  if (hook && oldValue !== cs._v) {
60
77
  hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });