sibujs 3.4.0 → 4.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 (98) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +118 -15
  3. package/dist/browser.cjs +410 -101
  4. package/dist/browser.d.cts +50 -5
  5. package/dist/browser.d.ts +50 -5
  6. package/dist/browser.js +8 -6
  7. package/dist/build.cjs +777 -385
  8. package/dist/build.js +15 -15
  9. package/dist/cdn.global.js +11 -7
  10. package/dist/{chunk-JCO7AHNU.js → chunk-3EKJK5FZ.js} +73 -34
  11. package/dist/chunk-4MFZMLUU.js +147 -0
  12. package/dist/chunk-52XFPGSN.js +123 -0
  13. package/dist/chunk-5INI7D2L.js +194 -0
  14. package/dist/{chunk-OAVXAFAY.js → chunk-6LG2T7LO.js} +5 -5
  15. package/dist/{chunk-OOUQUCNN.js → chunk-ACBT6UZS.js} +57 -22
  16. package/dist/{chunk-F7HW2NI5.js → chunk-AW6HPJ3L.js} +1 -1
  17. package/dist/chunk-DHDZ7IVN.js +109 -0
  18. package/dist/{chunk-JNGGM2XE.js → chunk-DQVUBVNX.js} +16 -25
  19. package/dist/{chunk-AXFWGY32.js → chunk-DR7H6UGM.js} +232 -67
  20. package/dist/{chunk-WSGLJYFI.js → chunk-E62UADKL.js} +9 -3
  21. package/dist/{chunk-3Z2NGWQI.js → chunk-ES2GERY2.js} +1 -1
  22. package/dist/{chunk-S3V6ZXPI.js → chunk-EWEE7NBF.js} +115 -41
  23. package/dist/{chunk-3DVGCW7O.js → chunk-F64ZPCFE.js} +8 -8
  24. package/dist/{chunk-APFRCIRI.js → chunk-GCSGGA3Q.js} +295 -198
  25. package/dist/{chunk-EX77FXTT.js → chunk-HYCCIYNS.js} +228 -51
  26. package/dist/{chunk-ELXMRSVN.js → chunk-NF3LYCQH.js} +259 -124
  27. package/dist/chunk-O3QQ3XOL.js +61 -0
  28. package/dist/{chunk-BUKYCWHX.js → chunk-PBQEW5VW.js} +14 -10
  29. package/dist/{chunk-H5FI5WDP.js → chunk-RRIDJQ5C.js} +3 -3
  30. package/dist/{chunk-S3NFJO6L.js → chunk-TIRZCERI.js} +36 -5
  31. package/dist/{chunk-ODXVQ3CS.js → chunk-VFHIVEPF.js} +309 -188
  32. package/dist/chunk-VPP2FONR.js +142 -0
  33. package/dist/{chunk-KZBEVFXZ.js → chunk-W55YHPEP.js} +5 -3
  34. package/dist/{chunk-FKQG7FTY.js → chunk-WN6WDFCB.js} +4 -4
  35. package/dist/{chunk-CEBWDD63.js → chunk-WOOMUJFT.js} +228 -86
  36. package/dist/{chunk-ITWCTZYH.js → chunk-Z2CE42DB.js} +19 -25
  37. package/dist/{contracts-ey_Qh8ef.d.cts → contracts-Hg6ITAEF.d.cts} +6 -6
  38. package/dist/{contracts-ey_Qh8ef.d.ts → contracts-Hg6ITAEF.d.ts} +6 -6
  39. package/dist/{customElement-CPfIrbvg.d.ts → customElement-CKLoO63w.d.cts} +73 -11
  40. package/dist/{customElement-CPfIrbvg.d.cts → customElement-CKLoO63w.d.ts} +73 -11
  41. package/dist/data.cjs +483 -205
  42. package/dist/data.d.cts +139 -7
  43. package/dist/data.d.ts +139 -7
  44. package/dist/data.js +9 -9
  45. package/dist/devtools.cjs +222 -87
  46. package/dist/devtools.js +8 -8
  47. package/dist/dispose-4FZ6OFXR.js +19 -0
  48. package/dist/ecosystem.cjs +419 -175
  49. package/dist/ecosystem.js +11 -11
  50. package/dist/extras.cjs +1981 -765
  51. package/dist/extras.d.cts +7 -7
  52. package/dist/extras.d.ts +7 -7
  53. package/dist/extras.js +29 -26
  54. package/dist/index.cjs +784 -385
  55. package/dist/index.d.cts +299 -28
  56. package/dist/index.d.ts +299 -28
  57. package/dist/index.js +33 -18
  58. package/dist/motion.cjs +180 -50
  59. package/dist/motion.d.cts +26 -0
  60. package/dist/motion.d.ts +26 -0
  61. package/dist/motion.js +5 -5
  62. package/dist/patterns.cjs +437 -170
  63. package/dist/patterns.d.cts +60 -13
  64. package/dist/patterns.d.ts +60 -13
  65. package/dist/patterns.js +7 -7
  66. package/dist/performance.cjs +333 -148
  67. package/dist/performance.d.cts +55 -7
  68. package/dist/performance.d.ts +55 -7
  69. package/dist/performance.js +9 -9
  70. package/dist/plugins.cjs +1374 -576
  71. package/dist/plugins.d.cts +227 -9
  72. package/dist/plugins.d.ts +227 -9
  73. package/dist/plugins.js +613 -321
  74. package/dist/{ssr-D62yFwuw.d.cts → ssr-BiPRdZ6n.d.cts} +44 -15
  75. package/dist/{ssr-D62yFwuw.d.ts → ssr-BiPRdZ6n.d.ts} +44 -15
  76. package/dist/{ssr-2PPULEK2.js → ssr-JFP5535P.js} +5 -4
  77. package/dist/ssr.cjs +1104 -443
  78. package/dist/ssr.d.cts +230 -20
  79. package/dist/ssr.d.ts +230 -20
  80. package/dist/ssr.js +15 -12
  81. package/dist/{startup-0Qv6aosO.d.cts → startup-BMpaiMhP.d.cts} +1 -1
  82. package/dist/{startup-0Qv6aosO.d.ts → startup-BMpaiMhP.d.ts} +1 -1
  83. package/dist/testing.cjs +205 -63
  84. package/dist/testing.d.cts +1 -1
  85. package/dist/testing.d.ts +1 -1
  86. package/dist/testing.js +8 -10
  87. package/dist/ui.cjs +640 -199
  88. package/dist/ui.d.cts +2 -2
  89. package/dist/ui.d.ts +2 -2
  90. package/dist/ui.js +10 -10
  91. package/dist/widgets.cjs +207 -82
  92. package/dist/widgets.js +9 -9
  93. package/package.json +12 -7
  94. package/dist/chunk-5VGSK6D2.js +0 -80
  95. package/dist/chunk-COY6PUD2.js +0 -34
  96. package/dist/chunk-K35BAR4P.js +0 -96
  97. package/dist/chunk-L3GAGWCC.js +0 -111
  98. package/dist/chunk-RT3IYFN2.js +0 -38
@@ -117,7 +117,12 @@ declare function permissions(name: string): {
117
117
  * Tracks the last copied text and provides a `copied` indicator
118
118
  * that resets after 2 seconds.
119
119
  *
120
- * @returns Object with reactive text getter, copy function, copied indicator, and dispose
120
+ * OWNERSHIP: `navigator.clipboard.writeText()` is an unbounded async gap it
121
+ * can sit on a permission prompt indefinitely. A write that resolves after
122
+ * `dispose()` must not touch state or arm a timer: the component that owned
123
+ * this controller is gone, so a `copied` flash it schedules fires against a
124
+ * torn-down subtree and keeps the controller (and its closure) alive for two
125
+ * more seconds for nothing.
121
126
  */
122
127
  declare function clipboard(): {
123
128
  text: () => string;
@@ -161,10 +166,16 @@ declare function dropZone(element: ElementTarget, options: {
161
166
  /**
162
167
  * title sets `document.title` reactively. Accepts a static string
163
168
  * or a reactive getter function. Returns a dispose function that
164
- * restores the previous document title.
169
+ * hands the title back to its previous owner.
165
170
  *
166
- * @param title Static string or reactive getter for the document title
167
- * @returns Dispose function that restores the original title
171
+ * Ownership is a STACK shared with `Head({ title })` see
172
+ * `utils/documentResources`. A per-instance "previous title" snapshot, which is
173
+ * what this used to keep, restores a stale value whenever three owners overlap
174
+ * and the middle one is disposed first: it writes back the title that was
175
+ * current when IT mounted, overwriting the owner that is actually visible.
176
+ *
177
+ * @param value Static string or reactive getter for the document title
178
+ * @returns Dispose function that releases this owner's claim
168
179
  */
169
180
  declare function title(value: string | (() => string)): () => void;
170
181
 
@@ -435,12 +446,46 @@ declare function fullscreen(): {
435
446
  * wakeLock wraps the Screen Wake Lock API to keep the screen awake while the
436
447
  * app is doing something the user is watching (video, timer, recipe, nav).
437
448
  *
438
- * Returns a reactive `active` boolean plus `request` / `release` actions.
449
+ * Returns a reactive `active` boolean plus `request` / `release` / `dispose`.
439
450
  * The lock is automatically re-requested if the page becomes visible again
440
451
  * after being hidden (browsers auto-release wake locks on tab hide).
441
452
  *
442
453
  * Gracefully degrades on browsers without the API.
443
454
  *
455
+ * OWNERSHIP MODEL
456
+ * ---------------
457
+ * A wake lock is a native handle, and the previous implementation kept exactly
458
+ * one mutable reference to it with no notion of which request that reference
459
+ * belonged to. Three things followed, all of them reproducible:
460
+ *
461
+ * - two overlapping `request()` calls acquired two sentinels; the second to
462
+ * arrive overwrote the first, and `release()` then released only the
463
+ * survivor. The other sentinel stayed held by the platform with no reference
464
+ * left to release it — a leaked native handle.
465
+ * - `release()` set the reference to null but did nothing about a request
466
+ * still in flight, so a sentinel arriving afterwards installed itself and
467
+ * the screen stayed awake after the caller had explicitly asked it not to.
468
+ * - the `release` listener called `setActive(false)` unconditionally, so an
469
+ * *old* sentinel being released by the platform cleared the state belonging
470
+ * to the current one.
471
+ *
472
+ * The model is therefore explicit:
473
+ *
474
+ * - `desire` is whether the controller currently wants a lock at all.
475
+ * - `generation` is bumped by `request()`, `release()` and `dispose()`. A
476
+ * completing request compares generations and, if it has lost ownership,
477
+ * releases the sentinel it was handed immediately rather than storing it.
478
+ * That is what makes a leak structurally impossible: every sentinel this
479
+ * module ever receives is either the current one or released on arrival.
480
+ * - concurrent `request()` calls share one in-flight acquisition, so the API
481
+ * is never asked for two sentinels at once, and `request()` while an
482
+ * unreleased sentinel is held is a no-op.
483
+ * - `active()` is true exactly when a current, unreleased sentinel is held.
484
+ * - `release()` and `dispose()` revoke the desire *before* awaiting anything,
485
+ * so a request already in flight is superseded rather than raced.
486
+ * - `dispose()` is idempotent and publishes `active(false)` exactly once, as
487
+ * its final act; nothing is published afterwards.
488
+ *
444
489
  * @example
445
490
  * ```ts
446
491
  * const lock = wakeLock();
package/dist/browser.d.ts CHANGED
@@ -117,7 +117,12 @@ declare function permissions(name: string): {
117
117
  * Tracks the last copied text and provides a `copied` indicator
118
118
  * that resets after 2 seconds.
119
119
  *
120
- * @returns Object with reactive text getter, copy function, copied indicator, and dispose
120
+ * OWNERSHIP: `navigator.clipboard.writeText()` is an unbounded async gap it
121
+ * can sit on a permission prompt indefinitely. A write that resolves after
122
+ * `dispose()` must not touch state or arm a timer: the component that owned
123
+ * this controller is gone, so a `copied` flash it schedules fires against a
124
+ * torn-down subtree and keeps the controller (and its closure) alive for two
125
+ * more seconds for nothing.
121
126
  */
122
127
  declare function clipboard(): {
123
128
  text: () => string;
@@ -161,10 +166,16 @@ declare function dropZone(element: ElementTarget, options: {
161
166
  /**
162
167
  * title sets `document.title` reactively. Accepts a static string
163
168
  * or a reactive getter function. Returns a dispose function that
164
- * restores the previous document title.
169
+ * hands the title back to its previous owner.
165
170
  *
166
- * @param title Static string or reactive getter for the document title
167
- * @returns Dispose function that restores the original title
171
+ * Ownership is a STACK shared with `Head({ title })` see
172
+ * `utils/documentResources`. A per-instance "previous title" snapshot, which is
173
+ * what this used to keep, restores a stale value whenever three owners overlap
174
+ * and the middle one is disposed first: it writes back the title that was
175
+ * current when IT mounted, overwriting the owner that is actually visible.
176
+ *
177
+ * @param value Static string or reactive getter for the document title
178
+ * @returns Dispose function that releases this owner's claim
168
179
  */
169
180
  declare function title(value: string | (() => string)): () => void;
170
181
 
@@ -435,12 +446,46 @@ declare function fullscreen(): {
435
446
  * wakeLock wraps the Screen Wake Lock API to keep the screen awake while the
436
447
  * app is doing something the user is watching (video, timer, recipe, nav).
437
448
  *
438
- * Returns a reactive `active` boolean plus `request` / `release` actions.
449
+ * Returns a reactive `active` boolean plus `request` / `release` / `dispose`.
439
450
  * The lock is automatically re-requested if the page becomes visible again
440
451
  * after being hidden (browsers auto-release wake locks on tab hide).
441
452
  *
442
453
  * Gracefully degrades on browsers without the API.
443
454
  *
455
+ * OWNERSHIP MODEL
456
+ * ---------------
457
+ * A wake lock is a native handle, and the previous implementation kept exactly
458
+ * one mutable reference to it with no notion of which request that reference
459
+ * belonged to. Three things followed, all of them reproducible:
460
+ *
461
+ * - two overlapping `request()` calls acquired two sentinels; the second to
462
+ * arrive overwrote the first, and `release()` then released only the
463
+ * survivor. The other sentinel stayed held by the platform with no reference
464
+ * left to release it — a leaked native handle.
465
+ * - `release()` set the reference to null but did nothing about a request
466
+ * still in flight, so a sentinel arriving afterwards installed itself and
467
+ * the screen stayed awake after the caller had explicitly asked it not to.
468
+ * - the `release` listener called `setActive(false)` unconditionally, so an
469
+ * *old* sentinel being released by the platform cleared the state belonging
470
+ * to the current one.
471
+ *
472
+ * The model is therefore explicit:
473
+ *
474
+ * - `desire` is whether the controller currently wants a lock at all.
475
+ * - `generation` is bumped by `request()`, `release()` and `dispose()`. A
476
+ * completing request compares generations and, if it has lost ownership,
477
+ * releases the sentinel it was handed immediately rather than storing it.
478
+ * That is what makes a leak structurally impossible: every sentinel this
479
+ * module ever receives is either the current one or released on arrival.
480
+ * - concurrent `request()` calls share one in-flight acquisition, so the API
481
+ * is never asked for two sentinels at once, and `request()` while an
482
+ * unreleased sentinel is held is a no-op.
483
+ * - `active()` is true exactly when a current, unreleased sentinel is held.
484
+ * - `release()` and `dispose()` revoke the desire *before* awaiting anything,
485
+ * so a request already in flight is superseded rather than raced.
486
+ * - `dispose()` is idempotent and publishes `active(false)` exactly once, as
487
+ * its final act; nothing is published afterwards.
488
+ *
444
489
  * @example
445
490
  * ```ts
446
491
  * const lock = wakeLock();
package/dist/browser.js CHANGED
@@ -35,13 +35,15 @@ import {
35
35
  visibility,
36
36
  wakeLock,
37
37
  windowSize
38
- } from "./chunk-S3V6ZXPI.js";
38
+ } from "./chunk-EWEE7NBF.js";
39
39
  import "./chunk-H3SRKIYX.js";
40
- import "./chunk-BUKYCWHX.js";
41
- import "./chunk-S3NFJO6L.js";
42
- import "./chunk-KZBEVFXZ.js";
43
- import "./chunk-OOUQUCNN.js";
44
- import "./chunk-COY6PUD2.js";
40
+ import "./chunk-52XFPGSN.js";
41
+ import "./chunk-7ZHH77QA.js";
42
+ import "./chunk-PBQEW5VW.js";
43
+ import "./chunk-TIRZCERI.js";
44
+ import "./chunk-W55YHPEP.js";
45
+ import "./chunk-ACBT6UZS.js";
46
+ import "./chunk-VPP2FONR.js";
45
47
  export {
46
48
  animationFrame,
47
49
  battery,