@buoy-gg/shared-ui 7.0.32 → 7.0.34

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 (237) hide show
  1. package/lib/commonjs/JsModal.js +70 -28
  2. package/lib/commonjs/hooks/index.js +26 -0
  3. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  4. package/lib/commonjs/hooks/useChangeLog.js +55 -0
  5. package/lib/commonjs/hooks/useEventStoreEvents.js +65 -0
  6. package/lib/commonjs/hooks/usePersistedState.js +45 -10
  7. package/lib/commonjs/index.js +143 -0
  8. package/lib/commonjs/storage/definePersistedSetting.js +67 -0
  9. package/lib/commonjs/storage/devToolsStorageKeys.js +12 -0
  10. package/lib/commonjs/storage/index.js +8 -1
  11. package/lib/commonjs/stores/ChangeLog.js +197 -0
  12. package/lib/commonjs/stores/createToolStore.js +175 -0
  13. package/lib/commonjs/stores/index.js +15 -1
  14. package/lib/commonjs/sync/toolSyncAdapter.js +63 -0
  15. package/lib/commonjs/sync/wireForm.js +172 -0
  16. package/lib/commonjs/tools/defineTool.js +79 -0
  17. package/lib/commonjs/ui/components/ChangeRow.js +110 -0
  18. package/lib/commonjs/ui/components/ChipStrip.js +94 -0
  19. package/lib/commonjs/ui/components/DetailViewToggle.js +130 -0
  20. package/lib/commonjs/ui/components/DevToolsCard.js +3 -1
  21. package/lib/commonjs/ui/components/EmptyState.js +10 -2
  22. package/lib/commonjs/ui/components/EntityFilterView.js +354 -0
  23. package/lib/commonjs/ui/components/ExportPreview.js +174 -0
  24. package/lib/commonjs/ui/components/InfoRow.js +90 -0
  25. package/lib/commonjs/ui/components/ModalHeader.js +40 -7
  26. package/lib/commonjs/ui/components/Pill.js +114 -0
  27. package/lib/commonjs/ui/components/ToggleRow.js +116 -0
  28. package/lib/commonjs/ui/components/ToolEmptyState.js +154 -0
  29. package/lib/commonjs/ui/components/ToolFooter.js +204 -0
  30. package/lib/commonjs/ui/components/WindowControls.js +8 -5
  31. package/lib/commonjs/ui/components/index.js +113 -1
  32. package/lib/commonjs/ui/index.js +36 -2
  33. package/lib/commonjs/ui/listPresets.js +43 -0
  34. package/lib/commonjs/ui/night/primitives.js +3 -1
  35. package/lib/commonjs/ui/otto/OttoSprite.js +510 -0
  36. package/lib/commonjs/ui/otto/index.js +38 -0
  37. package/lib/commonjs/ui/otto/ottoEngine.js +2734 -0
  38. package/lib/commonjs/ui/otto/ottoSheet.js +191 -0
  39. package/lib/commonjs/utils/snapshotProviderKit.js +167 -0
  40. package/lib/commonjs/utils/stateTools.js +160 -0
  41. package/lib/module/JsModal.js +70 -28
  42. package/lib/module/hooks/index.js +3 -1
  43. package/lib/module/hooks/safe-area-impl.js +1 -1
  44. package/lib/module/hooks/useChangeLog.js +50 -0
  45. package/lib/module/hooks/useEventStoreEvents.js +61 -0
  46. package/lib/module/hooks/usePersistedState.js +44 -10
  47. package/lib/module/index.js +11 -1
  48. package/lib/module/storage/definePersistedSetting.js +63 -0
  49. package/lib/module/storage/devToolsStorageKeys.js +12 -0
  50. package/lib/module/storage/index.js +2 -1
  51. package/lib/module/stores/ChangeLog.js +192 -0
  52. package/lib/module/stores/createToolStore.js +171 -0
  53. package/lib/module/stores/index.js +3 -1
  54. package/lib/module/sync/toolSyncAdapter.js +58 -0
  55. package/lib/module/sync/wireForm.js +159 -0
  56. package/lib/module/tools/defineTool.js +74 -0
  57. package/lib/module/ui/components/ChangeRow.js +105 -0
  58. package/lib/module/ui/components/ChipStrip.js +91 -0
  59. package/lib/module/ui/components/DetailViewToggle.js +125 -0
  60. package/lib/module/ui/components/DevToolsCard.js +3 -1
  61. package/lib/module/ui/components/EmptyState.js +10 -2
  62. package/lib/module/ui/components/EntityFilterView.js +350 -0
  63. package/lib/module/ui/components/ExportPreview.js +169 -0
  64. package/lib/module/ui/components/InfoRow.js +86 -0
  65. package/lib/module/ui/components/ModalHeader.js +40 -7
  66. package/lib/module/ui/components/Pill.js +110 -0
  67. package/lib/module/ui/components/ToggleRow.js +112 -0
  68. package/lib/module/ui/components/ToolEmptyState.js +149 -0
  69. package/lib/module/ui/components/ToolFooter.js +196 -0
  70. package/lib/module/ui/components/WindowControls.js +8 -5
  71. package/lib/module/ui/components/index.js +13 -1
  72. package/lib/module/ui/index.js +7 -1
  73. package/lib/module/ui/listPresets.js +39 -0
  74. package/lib/module/ui/night/primitives.js +3 -1
  75. package/lib/module/ui/otto/OttoSprite.js +496 -0
  76. package/lib/module/ui/otto/index.js +20 -0
  77. package/lib/module/ui/otto/ottoEngine.js +2726 -0
  78. package/lib/module/ui/otto/ottoSheet.js +180 -0
  79. package/lib/module/utils/snapshotProviderKit.js +156 -0
  80. package/lib/module/utils/stateTools.js +154 -0
  81. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/hooks/index.d.ts +3 -1
  83. package/lib/typescript/commonjs/hooks/index.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  85. package/lib/typescript/commonjs/hooks/useChangeLog.d.ts +38 -0
  86. package/lib/typescript/commonjs/hooks/useChangeLog.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/hooks/useEventStoreEvents.d.ts +25 -0
  88. package/lib/typescript/commonjs/hooks/useEventStoreEvents.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts +34 -5
  90. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/index.d.ts +6 -1
  92. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/storage/definePersistedSetting.d.ts +39 -0
  94. package/lib/typescript/commonjs/storage/definePersistedSetting.d.ts.map +1 -0
  95. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +12 -0
  96. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/storage/index.d.ts +1 -0
  98. package/lib/typescript/commonjs/storage/index.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/stores/ChangeLog.d.ts +100 -0
  100. package/lib/typescript/commonjs/stores/ChangeLog.d.ts.map +1 -0
  101. package/lib/typescript/commonjs/stores/createToolStore.d.ts +92 -0
  102. package/lib/typescript/commonjs/stores/createToolStore.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/stores/index.d.ts +2 -0
  104. package/lib/typescript/commonjs/stores/index.d.ts.map +1 -1
  105. package/lib/typescript/commonjs/sync/toolSyncAdapter.d.ts +66 -0
  106. package/lib/typescript/commonjs/sync/toolSyncAdapter.d.ts.map +1 -0
  107. package/lib/typescript/commonjs/sync/wireForm.d.ts +100 -0
  108. package/lib/typescript/commonjs/sync/wireForm.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/tools/defineTool.d.ts +100 -0
  110. package/lib/typescript/commonjs/tools/defineTool.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/ui/components/ChangeRow.d.ts +52 -0
  112. package/lib/typescript/commonjs/ui/components/ChangeRow.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/ui/components/ChipStrip.d.ts +41 -0
  114. package/lib/typescript/commonjs/ui/components/ChipStrip.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/ui/components/DetailViewToggle.d.ts +36 -0
  116. package/lib/typescript/commonjs/ui/components/DetailViewToggle.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts +8 -1
  118. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts +14 -1
  120. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/ui/components/EntityFilterView.d.ts +51 -0
  122. package/lib/typescript/commonjs/ui/components/EntityFilterView.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/ui/components/ExportPreview.d.ts +48 -0
  124. package/lib/typescript/commonjs/ui/components/ExportPreview.d.ts.map +1 -0
  125. package/lib/typescript/commonjs/ui/components/InfoRow.d.ts +33 -0
  126. package/lib/typescript/commonjs/ui/components/InfoRow.d.ts.map +1 -0
  127. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts +31 -1
  128. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts.map +1 -1
  129. package/lib/typescript/commonjs/ui/components/Pill.d.ts +38 -0
  130. package/lib/typescript/commonjs/ui/components/Pill.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/ui/components/ToggleRow.d.ts +33 -0
  132. package/lib/typescript/commonjs/ui/components/ToggleRow.d.ts.map +1 -0
  133. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts +113 -0
  134. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/ui/components/ToolFooter.d.ts +69 -0
  136. package/lib/typescript/commonjs/ui/components/ToolFooter.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts +7 -1
  138. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
  139. package/lib/typescript/commonjs/ui/components/index.d.ts +11 -0
  140. package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/ui/index.d.ts +2 -0
  142. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/ui/listPresets.d.ts +28 -0
  144. package/lib/typescript/commonjs/ui/listPresets.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/ui/night/primitives.d.ts +3 -1
  146. package/lib/typescript/commonjs/ui/night/primitives.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts +103 -0
  148. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts.map +1 -0
  149. package/lib/typescript/commonjs/ui/otto/index.d.ts +19 -0
  150. package/lib/typescript/commonjs/ui/otto/index.d.ts.map +1 -0
  151. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts +2205 -0
  152. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts +73 -0
  154. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/utils/snapshotProviderKit.d.ts +81 -0
  156. package/lib/typescript/commonjs/utils/snapshotProviderKit.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/utils/stateTools.d.ts +44 -0
  158. package/lib/typescript/commonjs/utils/stateTools.d.ts.map +1 -0
  159. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  160. package/lib/typescript/module/hooks/index.d.ts +3 -1
  161. package/lib/typescript/module/hooks/index.d.ts.map +1 -1
  162. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  163. package/lib/typescript/module/hooks/useChangeLog.d.ts +38 -0
  164. package/lib/typescript/module/hooks/useChangeLog.d.ts.map +1 -0
  165. package/lib/typescript/module/hooks/useEventStoreEvents.d.ts +25 -0
  166. package/lib/typescript/module/hooks/useEventStoreEvents.d.ts.map +1 -0
  167. package/lib/typescript/module/hooks/usePersistedState.d.ts +34 -5
  168. package/lib/typescript/module/hooks/usePersistedState.d.ts.map +1 -1
  169. package/lib/typescript/module/index.d.ts +6 -1
  170. package/lib/typescript/module/index.d.ts.map +1 -1
  171. package/lib/typescript/module/storage/definePersistedSetting.d.ts +39 -0
  172. package/lib/typescript/module/storage/definePersistedSetting.d.ts.map +1 -0
  173. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +12 -0
  174. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  175. package/lib/typescript/module/storage/index.d.ts +1 -0
  176. package/lib/typescript/module/storage/index.d.ts.map +1 -1
  177. package/lib/typescript/module/stores/ChangeLog.d.ts +100 -0
  178. package/lib/typescript/module/stores/ChangeLog.d.ts.map +1 -0
  179. package/lib/typescript/module/stores/createToolStore.d.ts +92 -0
  180. package/lib/typescript/module/stores/createToolStore.d.ts.map +1 -0
  181. package/lib/typescript/module/stores/index.d.ts +2 -0
  182. package/lib/typescript/module/stores/index.d.ts.map +1 -1
  183. package/lib/typescript/module/sync/toolSyncAdapter.d.ts +66 -0
  184. package/lib/typescript/module/sync/toolSyncAdapter.d.ts.map +1 -0
  185. package/lib/typescript/module/sync/wireForm.d.ts +100 -0
  186. package/lib/typescript/module/sync/wireForm.d.ts.map +1 -0
  187. package/lib/typescript/module/tools/defineTool.d.ts +100 -0
  188. package/lib/typescript/module/tools/defineTool.d.ts.map +1 -0
  189. package/lib/typescript/module/ui/components/ChangeRow.d.ts +52 -0
  190. package/lib/typescript/module/ui/components/ChangeRow.d.ts.map +1 -0
  191. package/lib/typescript/module/ui/components/ChipStrip.d.ts +41 -0
  192. package/lib/typescript/module/ui/components/ChipStrip.d.ts.map +1 -0
  193. package/lib/typescript/module/ui/components/DetailViewToggle.d.ts +36 -0
  194. package/lib/typescript/module/ui/components/DetailViewToggle.d.ts.map +1 -0
  195. package/lib/typescript/module/ui/components/DevToolsCard.d.ts +8 -1
  196. package/lib/typescript/module/ui/components/DevToolsCard.d.ts.map +1 -1
  197. package/lib/typescript/module/ui/components/EmptyState.d.ts +14 -1
  198. package/lib/typescript/module/ui/components/EmptyState.d.ts.map +1 -1
  199. package/lib/typescript/module/ui/components/EntityFilterView.d.ts +51 -0
  200. package/lib/typescript/module/ui/components/EntityFilterView.d.ts.map +1 -0
  201. package/lib/typescript/module/ui/components/ExportPreview.d.ts +48 -0
  202. package/lib/typescript/module/ui/components/ExportPreview.d.ts.map +1 -0
  203. package/lib/typescript/module/ui/components/InfoRow.d.ts +33 -0
  204. package/lib/typescript/module/ui/components/InfoRow.d.ts.map +1 -0
  205. package/lib/typescript/module/ui/components/ModalHeader.d.ts +31 -1
  206. package/lib/typescript/module/ui/components/ModalHeader.d.ts.map +1 -1
  207. package/lib/typescript/module/ui/components/Pill.d.ts +38 -0
  208. package/lib/typescript/module/ui/components/Pill.d.ts.map +1 -0
  209. package/lib/typescript/module/ui/components/ToggleRow.d.ts +33 -0
  210. package/lib/typescript/module/ui/components/ToggleRow.d.ts.map +1 -0
  211. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts +113 -0
  212. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts.map +1 -0
  213. package/lib/typescript/module/ui/components/ToolFooter.d.ts +69 -0
  214. package/lib/typescript/module/ui/components/ToolFooter.d.ts.map +1 -0
  215. package/lib/typescript/module/ui/components/WindowControls.d.ts +7 -1
  216. package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/components/index.d.ts +11 -0
  218. package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
  219. package/lib/typescript/module/ui/index.d.ts +2 -0
  220. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  221. package/lib/typescript/module/ui/listPresets.d.ts +28 -0
  222. package/lib/typescript/module/ui/listPresets.d.ts.map +1 -0
  223. package/lib/typescript/module/ui/night/primitives.d.ts +3 -1
  224. package/lib/typescript/module/ui/night/primitives.d.ts.map +1 -1
  225. package/lib/typescript/module/ui/otto/OttoSprite.d.ts +103 -0
  226. package/lib/typescript/module/ui/otto/OttoSprite.d.ts.map +1 -0
  227. package/lib/typescript/module/ui/otto/index.d.ts +19 -0
  228. package/lib/typescript/module/ui/otto/index.d.ts.map +1 -0
  229. package/lib/typescript/module/ui/otto/ottoEngine.d.ts +2205 -0
  230. package/lib/typescript/module/ui/otto/ottoEngine.d.ts.map +1 -0
  231. package/lib/typescript/module/ui/otto/ottoSheet.d.ts +73 -0
  232. package/lib/typescript/module/ui/otto/ottoSheet.d.ts.map +1 -0
  233. package/lib/typescript/module/utils/snapshotProviderKit.d.ts +81 -0
  234. package/lib/typescript/module/utils/snapshotProviderKit.d.ts.map +1 -0
  235. package/lib/typescript/module/utils/stateTools.d.ts +44 -0
  236. package/lib/typescript/module/utils/stateTools.d.ts.map +1 -0
  237. package/package.json +4 -4
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Otto's precomputed animation.
5
+ *
6
+ * Every state is a short loop (48 ticks at most). This module renders that
7
+ * loop once, splits it into a BODY layer and a 7-frame WATER layer (they
8
+ * composite back pixel-for-pixel: compose() only paints water into empty
9
+ * cells and blanks a submerged body below the waterline), dedupes the
10
+ * frames, and turns each distinct frame into merged rectangles. The shipping
11
+ * <Otto/> mounts those rectangles ONCE as a strip of static Views and slides
12
+ * a window over the strip on the UI thread.
13
+ *
14
+ * Why: the buoy-optimize rounds in OTTO_PERF_PLAN.md showed that any renderer
15
+ * re-creating Views per tick pegs the JS thread (5 FPS at 34 sprites, dropped
16
+ * UI frames even at 1 sprite), while "mount once, move a window natively"
17
+ * costs nothing per tick and keeps moving while JS is blocked.
18
+ *
19
+ * Everything here is pure `react-native`-free TypeScript, cached per state.
20
+ */
21
+ import { OTTO_GRID, OTTO_PALETTE, ottoWaterRows, renderOttoFrame } from "./ottoEngine.js";
22
+ export const CELLS = OTTO_GRID * OTTO_GRID;
23
+ export const WATER_ROW0 = 13;
24
+ export const WATER_ROWS = OTTO_GRID - WATER_ROW0;
25
+ export const WATER_CELLS = WATER_ROWS * OTTO_GRID;
26
+ /** The wave is a function of floor(t/2) mod 7. */
27
+ export const WATER_FRAMES = 7;
28
+ export const TRANSPARENT = "transparent";
29
+ /** Longest state cycle in ticks (idle and sleep are 48). */
30
+ export const MAX_PERIOD = 48;
31
+ export function gridKey(grid) {
32
+ return grid.map(r => r.join("")).join("|");
33
+ }
34
+
35
+ /** Flat 256 colours, row-major, `transparent` for empty cells. */
36
+ export function flatColors(grid) {
37
+ const out = new Array(CELLS);
38
+ for (let y = 0; y < OTTO_GRID; y++) {
39
+ const row = grid[y];
40
+ for (let x = 0; x < OTTO_GRID; x++) out[y * OTTO_GRID + x] = OTTO_PALETTE[row[x]] ?? TRANSPARENT;
41
+ }
42
+ return out;
43
+ }
44
+
45
+ // ---------------------------------------------------------------- cycle ---
46
+
47
+ const cycleCache = new Map();
48
+ export function ottoCycle(state, keyline) {
49
+ const cacheKey = `${state}|${keyline ? 1 : 0}`;
50
+ const hit = cycleCache.get(cacheKey);
51
+ if (hit) return hit;
52
+ const keys = [];
53
+ const grids = [];
54
+ for (let t = 0; t < MAX_PERIOD * 2; t++) {
55
+ const g = renderOttoFrame(state, t, {
56
+ water: false,
57
+ keyline
58
+ });
59
+ grids.push(g);
60
+ keys.push(gridKey(g));
61
+ }
62
+ let period = MAX_PERIOD;
63
+ for (let P = 1; P <= MAX_PERIOD; P++) {
64
+ let ok = true;
65
+ for (let t = 0; t < MAX_PERIOD; t++) {
66
+ if (keys[t] !== keys[t + P]) {
67
+ ok = false;
68
+ break;
69
+ }
70
+ }
71
+ if (ok) {
72
+ period = P;
73
+ break;
74
+ }
75
+ }
76
+ const body = grids.slice(0, period).map(flatColors);
77
+ const water = [];
78
+ for (let w = 0; w < WATER_FRAMES; w++) {
79
+ const flat = [];
80
+ for (const row of ottoWaterRows(w * 2)) for (const k of row) flat.push(OTTO_PALETTE[k] ?? TRANSPARENT);
81
+ water.push(flat);
82
+ }
83
+ const cycle = {
84
+ period,
85
+ body,
86
+ water
87
+ };
88
+ cycleCache.set(cacheKey, cycle);
89
+ return cycle;
90
+ }
91
+
92
+ /** Frame indexes for a cycle at local tick `t`. */
93
+ export function cycleIndexes(t, period) {
94
+ const local = Math.max(0, t);
95
+ return {
96
+ bi: local % period,
97
+ wi: Math.floor(local / 2) % WATER_FRAMES
98
+ };
99
+ }
100
+
101
+ // ---------------------------------------------------------------- rects ---
102
+
103
+ /**
104
+ * Same-colour runs per row, then runs merged with the identical run directly
105
+ * below them — roughly a third fewer Views than row runs alone. Covers
106
+ * exactly the non-transparent cells, never overlaps (proved offline over
107
+ * every frame of every state).
108
+ */
109
+ export function rectsOf(colors, cols, rows) {
110
+ const open = [];
111
+ const done = [];
112
+ for (let y = 0; y < rows; y++) {
113
+ const rowRuns = [];
114
+ let x = 0;
115
+ while (x < cols) {
116
+ const color = colors[y * cols + x];
117
+ let w = 1;
118
+ while (x + w < cols && colors[y * cols + x + w] === color) w++;
119
+ if (color !== TRANSPARENT) rowRuns.push({
120
+ x,
121
+ y,
122
+ w,
123
+ h: 1,
124
+ color
125
+ });
126
+ x += w;
127
+ }
128
+ const next = [];
129
+ for (const r of rowRuns) {
130
+ const above = open.find(o => o.x === r.x && o.w === r.w && o.color === r.color && o.y + o.h === r.y);
131
+ if (above) {
132
+ above.h += 1;
133
+ next.push(above);
134
+ } else {
135
+ next.push(r);
136
+ }
137
+ }
138
+ for (const o of open) if (!next.includes(o)) done.push(o);
139
+ open.length = 0;
140
+ open.push(...next);
141
+ }
142
+ done.push(...open);
143
+ return done;
144
+ }
145
+
146
+ // ---------------------------------------------------------------- sheets --
147
+
148
+ /** One layer as a strip of distinct frames, and which frame each tick shows. */
149
+
150
+ const sheetCache = new Map();
151
+ function stripOf(frames, cols, rows) {
152
+ const keys = frames.map(f => f.join(","));
153
+ const indexOf = new Map();
154
+ const distinct = [];
155
+ keys.forEach((k, i) => {
156
+ if (!indexOf.has(k)) {
157
+ indexOf.set(k, distinct.length);
158
+ distinct.push(rectsOf(frames[i], cols, rows));
159
+ }
160
+ });
161
+ return {
162
+ colOf: keys.map(k => indexOf.get(k) ?? 0),
163
+ frames: distinct
164
+ };
165
+ }
166
+
167
+ /** Both layers of a state as strips of rectangles. Pure; cached per state. */
168
+ export function ottoSheets(state, keyline) {
169
+ const key = `${state}|${keyline ? 1 : 0}`;
170
+ const hit = sheetCache.get(key);
171
+ if (hit) return hit;
172
+ const cycle = ottoCycle(state, keyline);
173
+ const built = {
174
+ period: cycle.period,
175
+ body: stripOf(cycle.body, OTTO_GRID, OTTO_GRID),
176
+ water: stripOf(cycle.water, OTTO_GRID, WATER_ROWS)
177
+ };
178
+ sheetCache.set(key, built);
179
+ return built;
180
+ }
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * snapshotProviderKit — the parts of a Time Machine `StateSnapshotProvider`
5
+ * that are the same for every source.
6
+ *
7
+ * storage, redux, zustand, jotai and react-query each register a provider
8
+ * (see stateSnapshotRegistry.ts). What differs is how they read and write
9
+ * their source. What was copied five times is:
10
+ *
11
+ * - the restore SCOPE gate: `excludeKeys` (touch all but these) and
12
+ * `includeKeys` (touch only these), the "N item(s) excluded by you"
13
+ * warning, and the empty `StateSnapshotRestoreResult`;
14
+ * - the preview VERDICT ladder: removed → added → unchanged → too-large →
15
+ * changed, with the 256 KB per-item render cap;
16
+ * - the "won't apply" override: a difference restore cannot apply must say
17
+ * so instead of rendering as a green change.
18
+ *
19
+ * The parts that stay per-tool are the ones that matter: redux verifies the
20
+ * jump by reference identity, zustand grafts action functions back, jotai
21
+ * leaves derived atoms to recompute, storage gates MMKV buffers and
22
+ * biometric keys, react-query diffs a comparable projection.
23
+ */
24
+
25
+ import { boundedDeepEqual, jsonLikelyLargerThan } from "../dataViewer/objectDiff.js";
26
+ /** Beyond this a preview item is "too-large": restore still applies it, the diff isn't drawn. */
27
+ export const PREVIEW_ITEM_RENDER_BYTE_LIMIT = 256 * 1024;
28
+ /**
29
+ * Both option lists use preview item keys, and both mean "leave everything
30
+ * else untouched in BOTH directions". `includeKeys` wins when present;
31
+ * `excludeKeys` still applies on top.
32
+ */
33
+ export function createRestoreScope(options) {
34
+ const excludedSet = new Set(options?.excludeKeys ?? []);
35
+ const includedSet = options?.includeKeys ? new Set(options.includeKeys) : null;
36
+ let excludedHits = 0;
37
+ const touch = key => !excludedSet.has(key) && (!includedSet || includedSet.has(key));
38
+ return {
39
+ touch,
40
+ allows(key) {
41
+ if (touch(key)) return true;
42
+ excludedHits += 1;
43
+ return false;
44
+ },
45
+ countExcluded(n) {
46
+ excludedHits += n;
47
+ },
48
+ get excludedHits() {
49
+ return excludedHits;
50
+ },
51
+ excludedWarning(noun) {
52
+ return excludedHits > 0 ? `${excludedHits} ${noun} excluded by you` : null;
53
+ }
54
+ };
55
+ }
56
+
57
+ /** A fresh, successful, empty result to accumulate into. */
58
+ export function emptyRestoreResult() {
59
+ return {
60
+ ok: true,
61
+ applied: 0,
62
+ skipped: [],
63
+ warnings: []
64
+ };
65
+ }
66
+
67
+ /** A failed result with one warning (an empty or unusable snapshot). */
68
+ export function failedRestore(warning) {
69
+ return {
70
+ ok: false,
71
+ applied: 0,
72
+ skipped: [],
73
+ warnings: [warning]
74
+ };
75
+ }
76
+
77
+ /** A failed result with one skipped item and its reason. */
78
+ export function skippedRestore(id, reason) {
79
+ return {
80
+ ok: false,
81
+ applied: 0,
82
+ skipped: [{
83
+ id,
84
+ reason
85
+ }],
86
+ warnings: []
87
+ };
88
+ }
89
+ /**
90
+ * The verdict ladder: removed → added → unchanged → too-large → changed.
91
+ * Callers layer source-specific verdicts (`wont-apply`, `recomputes`) on top
92
+ * with `wontApply()`.
93
+ */
94
+ export function classifyPreviewItem(input, options = {}) {
95
+ const {
96
+ key,
97
+ label,
98
+ oldValue,
99
+ newValue,
100
+ inOld,
101
+ inNew
102
+ } = input;
103
+ if (!inNew) return {
104
+ key,
105
+ label,
106
+ verdict: "removed",
107
+ oldValue
108
+ };
109
+ if (!inOld) return {
110
+ key,
111
+ label,
112
+ verdict: "added",
113
+ newValue
114
+ };
115
+ const equal = options.equal ?? boundedDeepEqual;
116
+ if (equal(oldValue, newValue)) return {
117
+ key,
118
+ label,
119
+ verdict: "unchanged"
120
+ };
121
+ const tooLarge = options.tooLarge ?? (value => jsonLikelyLargerThan(value, PREVIEW_ITEM_RENDER_BYTE_LIMIT));
122
+ if (tooLarge(oldValue) || tooLarge(newValue)) {
123
+ return {
124
+ key,
125
+ label,
126
+ verdict: "too-large",
127
+ reason: options.tooLargeReason ?? "value too large to render a diff — restore still applies it"
128
+ };
129
+ }
130
+ return {
131
+ key,
132
+ label,
133
+ verdict: "changed",
134
+ oldValue,
135
+ newValue
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Mark an item as something restore cannot apply. An unchanged item is left
141
+ * alone — there is nothing to apply, so nothing is being refused.
142
+ */
143
+ export function wontApply(item, reason) {
144
+ if (item.verdict === "unchanged") return item;
145
+ return {
146
+ ...item,
147
+ verdict: "wont-apply",
148
+ reason
149
+ };
150
+ }
151
+
152
+ /** Every key present in either record, once. */
153
+ export function unionKeys(a, b) {
154
+ const keysOf = r => r === undefined ? [] : r instanceof Map ? Array.from(r.keys()) : Object.keys(r);
155
+ return new Set([...keysOf(a), ...keysOf(b)]);
156
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * stateTools — helpers the state tools (redux / zustand / jotai) each carried
5
+ * a private copy of. Pure functions; no React, no RN.
6
+ */
7
+
8
+ // ============================================
9
+ // Entity color
10
+ // ============================================
11
+
12
+ /**
13
+ * Consistent color for a named entity (a zustand store, a jotai atom, a redux
14
+ * slice). Exact match on `known` wins, then a substring match, then a stable
15
+ * HSL hash of the name rendered as `#rrggbb` so the "color + alpha hex"
16
+ * pattern works everywhere.
17
+ */
18
+ export function entityColor(name, known = {}) {
19
+ const lower = name.toLowerCase();
20
+ if (known[lower]) return known[lower];
21
+ for (const [key, color] of Object.entries(known)) {
22
+ if (lower.includes(key)) return color;
23
+ }
24
+ const hash = name.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0);
25
+ const hue = hash * 137 % 360;
26
+ const s = 0.7;
27
+ const l = 0.6;
28
+ const c = (1 - Math.abs(2 * l - 1)) * s;
29
+ const x = c * (1 - Math.abs(hue / 60 % 2 - 1));
30
+ const m = l - c / 2;
31
+ let r = 0;
32
+ let g = 0;
33
+ let b = 0;
34
+ if (hue < 60) {
35
+ r = c;
36
+ g = x;
37
+ } else if (hue < 120) {
38
+ r = x;
39
+ g = c;
40
+ } else if (hue < 180) {
41
+ g = c;
42
+ b = x;
43
+ } else if (hue < 240) {
44
+ g = x;
45
+ b = c;
46
+ } else if (hue < 300) {
47
+ r = x;
48
+ b = c;
49
+ } else {
50
+ r = c;
51
+ b = x;
52
+ }
53
+ const toHex = v => Math.round((v + m) * 255).toString(16).padStart(2, "0");
54
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
55
+ }
56
+
57
+ // ============================================
58
+ // Value preview
59
+ // ============================================
60
+
61
+ /**
62
+ * One-line preview of an arbitrary value for a list row: strings quoted and
63
+ * truncated, arrays and objects stringified when short, otherwise collapsed
64
+ * to `[N items]` / `{ N keys }`. Never throws.
65
+ */
66
+ export function formatValuePreview(value, options = {}) {
67
+ const maxLength = options.maxLength ?? 40;
68
+ if (value === undefined) return options.undefinedLabel ?? "undefined";
69
+ if (value === null) return "null";
70
+ try {
71
+ if (typeof value === "function") return options.functionLabel ?? "(fn)";
72
+ if (typeof value === "string") {
73
+ return value.length > maxLength ? `"${value.slice(0, maxLength - 3)}..."` : `"${value}"`;
74
+ }
75
+ if (typeof value === "number" || typeof value === "boolean") {
76
+ return String(value);
77
+ }
78
+ if (Array.isArray(value)) {
79
+ if (value.length === 0) return "[]";
80
+ const preview = JSON.stringify(value);
81
+ return preview.length > maxLength ? `[${value.length} items]` : preview;
82
+ }
83
+ if (typeof value === "object") {
84
+ const keys = Object.keys(value);
85
+ if (keys.length === 0) return "{}";
86
+ const preview = JSON.stringify(value);
87
+ if (preview.length <= maxLength) return preview;
88
+ return `{ ${keys.length} keys }`;
89
+ }
90
+ return String(value).slice(0, maxLength);
91
+ } catch {
92
+ return "[complex]";
93
+ }
94
+ }
95
+
96
+ // ============================================
97
+ // Shallow diff summary
98
+ // ============================================
99
+
100
+ /**
101
+ * Top-level, reference-equality diff between two states. Enough for a list
102
+ * row ("+1 ~2 keys"); the detail view runs the real tree diff.
103
+ *
104
+ * A state object that was REPLACED without any top-level value moving —
105
+ * exactly what zustand's persist middleware does when it rehydrates — is
106
+ * reported as `"nested change"` with no keys, never as one changed key with
107
+ * none named.
108
+ */
109
+ export function shallowDiffSummary(prev, next) {
110
+ if (prev === next) {
111
+ return {
112
+ summary: "no change",
113
+ changedKeys: [],
114
+ changedCount: 0
115
+ };
116
+ }
117
+ if (typeof prev !== "object" || typeof next !== "object" || prev === null || next === null) {
118
+ return {
119
+ summary: "changed",
120
+ changedKeys: [],
121
+ changedCount: 0
122
+ };
123
+ }
124
+ const prevRecord = prev;
125
+ const nextRecord = next;
126
+ const prevKeys = Object.keys(prevRecord);
127
+ const nextKeys = Object.keys(nextRecord);
128
+ const added = nextKeys.filter(k => !prevKeys.includes(k));
129
+ const removed = prevKeys.filter(k => !nextKeys.includes(k));
130
+ const changed = [];
131
+ for (const key of prevKeys) {
132
+ if (nextKeys.includes(key) && prevRecord[key] !== nextRecord[key]) {
133
+ changed.push(key);
134
+ }
135
+ }
136
+ const changedKeys = [...added, ...removed, ...changed];
137
+ const parts = [];
138
+ if (added.length > 0) parts.push(`+${added.length}`);
139
+ if (removed.length > 0) parts.push(`-${removed.length}`);
140
+ if (changed.length > 0) parts.push(`~${changed.length}`);
141
+ if (parts.length === 0) {
142
+ return {
143
+ summary: "nested change",
144
+ changedKeys: [],
145
+ changedCount: 0
146
+ };
147
+ }
148
+ const total = changedKeys.length;
149
+ return {
150
+ summary: `${parts.join(" ")} ${total === 1 ? "key" : "keys"}`,
151
+ changedKeys,
152
+ changedCount: total
153
+ };
154
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"JsModal.d.ts","sourceRoot":"","sources":["../../../src/JsModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAUL,SAAS,EAEV,MAAM,OAAO,CAAC;AACf,OAAO,EAML,QAAQ,EAGR,SAAS,EAEV,MAAM,cAAc,CAAC;AAyHtB,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,kBAAkB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACxD;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAChC;;;+BAG2B;IAC3B,WAAW,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,cAAc,GAAG,YAAY,CAAC;IACtE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,uBAAuB,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAErD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,yFAAyF;IACzF,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gIAAgI;IAChI,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AA6xDD,eAAO,MAAM,OAAO,oDAAyB,CAAC"}
1
+ {"version":3,"file":"JsModal.d.ts","sourceRoot":"","sources":["../../../src/JsModal.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAUL,SAAS,EAEV,MAAM,OAAO,CAAC;AACf,OAAO,EAML,QAAQ,EAGR,SAAS,EAEV,MAAM,cAAc,CAAC;AAyHtB,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/C,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,kBAAkB,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACxD;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;IAChC;;;+BAG2B;IAC3B,WAAW,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,cAAc,GAAG,YAAY,CAAC;IACtE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,uBAAuB,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAErD,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,yFAAyF;IACzF,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC9C,0EAA0E;IAC1E,sBAAsB,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,UAAU,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gIAAgI;IAChI,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAo0DD,eAAO,MAAM,OAAO,oDAAyB,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export { useFilterManager } from "./useFilterManager";
2
- export { usePersistedState } from "./usePersistedState";
2
+ export { usePersistedState, resetPersistedStateCache, type PersistedStateOptions, type PersistedStateStorage, } from "./usePersistedState";
3
+ export { useChangeLog, useSubscribedValue, type UseChangeLogOptions, type UseChangeLogResult, } from "./useChangeLog";
4
+ export { useEventStoreEvents, type UseEventStoreEventsOptions, type UseEventStoreEventsResult, } from "./useEventStoreEvents";
3
5
  export { useSafeAreaInsets } from "./useSafeAreaInsets";
4
6
  export { getSafeAreaInsets } from "./useSafeAreaInsets";
5
7
  export { useDeviceInfo, getDeviceInfo, logDeviceInfo, type DeviceInfo, type PlatformInfo, type DisplayInfo, type AccessibilitySettings, type AppearanceInfo, type LocaleInfo, type StatusBarInfo, type KeyboardInfo, type AppStateInfo, type UniqueIdentifiers, type SettingsInfo, } from "./useDeviceInfo";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Auto-generated safe area implementation
3
3
  * Detected: none
4
- * Generated at: 2026-09-01T17:57:34.045Z
4
+ * Generated at: 2026-09-04T01:21:28.486Z
5
5
  *
6
6
  * DO NOT EDIT - This file is generated by scripts/detect-safe-area.js
7
7
  *
@@ -0,0 +1,38 @@
1
+ /**
2
+ * React bindings for `ChangeLog` — what useReduxActions, useZustandStateChanges
3
+ * and useJotaiAtomChanges each re-derived: seed state from the log, subscribe
4
+ * for the lifetime of the component, hold a filter, memoize the filtered
5
+ * list, and expose clear / pause / lookup.
6
+ *
7
+ * Tool-specific stats and registries (stores, atoms) compose on top — see
8
+ * `useSubscribedValue` for the registry half.
9
+ */
10
+ import type { ChangeLog, Identified } from "../stores/ChangeLog";
11
+ export interface UseChangeLogOptions<T, F> {
12
+ /** Initial filter value. Default `{}`. */
13
+ initialFilter?: F;
14
+ /** Derive the filtered list. Default: identity (no filtering). */
15
+ filterItems?: (items: T[], filter: F) => T[];
16
+ }
17
+ export interface UseChangeLogResult<T, F> {
18
+ /** All recorded items, newest first. */
19
+ items: T[];
20
+ /** `items` after `filterItems`. */
21
+ filteredItems: T[];
22
+ filter: F;
23
+ setFilter: React.Dispatch<React.SetStateAction<F>>;
24
+ /** Whether recording is enabled (the pause button's state). */
25
+ isEnabled: boolean;
26
+ /** Flip recording on/off. */
27
+ toggleCapture: () => void;
28
+ /** Empty the log (fires the desktop mirror's clear forwarding). */
29
+ clear: () => void;
30
+ getById: (id: string) => T | undefined;
31
+ }
32
+ export declare function useChangeLog<T extends Identified, F extends object = Record<string, never>>(log: ChangeLog<T>, options?: UseChangeLogOptions<T, F>): UseChangeLogResult<T, F>;
33
+ /**
34
+ * Hold a value that a store pushes through a `(value) => void` listener —
35
+ * a registry of stores, atoms, sources. Seeded synchronously from `read`.
36
+ */
37
+ export declare function useSubscribedValue<V>(read: () => V, subscribe: (listener: (value: V) => void) => () => void): V;
38
+ //# sourceMappingURL=useChangeLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChangeLog.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useChangeLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,WAAW,mBAAmB,CAAC,CAAC,EAAE,CAAC;IACvC,0CAA0C;IAC1C,aAAa,CAAC,EAAE,CAAC,CAAC;IAClB,kEAAkE;IAClE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,EAAE,CAAC;IACtC,wCAAwC;IACxC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,mCAAmC;IACnC,aAAa,EAAE,CAAC,EAAE,CAAC;IACnB,MAAM,EAAE,CAAC,CAAC;IACV,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,mEAAmE;IACnE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;CACxC;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACzF,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,EACjB,OAAO,GAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAM,GACtC,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CA0B1B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,CAAC,EACb,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,KAAK,MAAM,IAAI,GACtD,CAAC,CAIH"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * React bindings for a `BaseEventStore` — what useRouteEvents and
3
+ * useStorageEvents each hand-rolled: subscribe while enabled (which
4
+ * auto-starts the store's capture), coalesce bursts onto one animation
5
+ * frame so a storm of writes is one commit instead of one per emission,
6
+ * select/limit the list, and report whether capture is live.
7
+ */
8
+ import type { BaseEventStore } from "../stores/BaseEventStore";
9
+ export interface UseEventStoreEventsOptions<T> {
10
+ /** Subscribe at all? `false` unsubscribes (and lets the store stop capturing). Default true. */
11
+ enabled?: boolean;
12
+ /** Cap the list handed to React. Default 500. */
13
+ maxEvents?: number;
14
+ /** Narrow the list before capping (a storage-type filter, say). */
15
+ select?: (events: T[]) => T[];
16
+ }
17
+ export interface UseEventStoreEventsResult<T> {
18
+ /** Newest first. */
19
+ events: T[];
20
+ clearEvents: () => void;
21
+ /** True while this hook holds a live subscription. */
22
+ isActive: boolean;
23
+ }
24
+ export declare function useEventStoreEvents<T>(store: BaseEventStore<T>, options?: UseEventStoreEventsOptions<T>): UseEventStoreEventsResult<T>;
25
+ //# sourceMappingURL=useEventStoreEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEventStoreEvents.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useEventStoreEvents.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,gGAAgG;IAChG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,oBAAoB;IACpB,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE,0BAA0B,CAAC,CAAC,CAAM,GAC1C,yBAAyB,CAAC,CAAC,CAAC,CA8C9B"}
@@ -1,16 +1,45 @@
1
+ /** The two calls a backend needs. `persistentStorage` and AsyncStorage both fit. */
2
+ export interface PersistedStateStorage {
3
+ getItem(key: string): Promise<string | null>;
4
+ setItem(key: string, value: string): Promise<void>;
5
+ }
6
+ export interface PersistedStateOptions<T> {
7
+ /**
8
+ * Turn the stored string into a value. Return `undefined` to reject it
9
+ * (corrupt, or a value the UI no longer offers) and keep the default.
10
+ * Default: `JSON.parse`.
11
+ */
12
+ parse?: (raw: string) => T | undefined;
13
+ /** Turn a value into the stored string. Default: `JSON.stringify`. */
14
+ serialize?: (value: T) => string;
15
+ /**
16
+ * Where the value lives. Default: `persistentStorage` (FileSystem →
17
+ * AsyncStorage → memory). A tool whose keys were always written straight to
18
+ * AsyncStorage keeps reading them by passing AsyncStorage here.
19
+ */
20
+ storage?: PersistedStateStorage;
21
+ }
1
22
  /**
2
23
  * `useState` persisted through `persistentStorage` (FileSystem → AsyncStorage
3
24
  * → memory). Replaces the load-then-`hasLoaded`-guard `useEffect` pattern
4
25
  * every tool used to hand-roll.
5
26
  *
6
- * Values are JSON-serialized; the default is returned until hydration
7
- * completes (subsequent mounts of the same key hydrate synchronously from an
8
- * in-memory cache). The third tuple element reports hydration so callers can
9
- * defer writes that must not clobber a not-yet-loaded value.
27
+ * Values are JSON-serialized by default; the default is returned until
28
+ * hydration completes (subsequent mounts of the same key hydrate synchronously
29
+ * from an in-memory cache). The third tuple element reports hydration so
30
+ * callers can defer writes that must not clobber a not-yet-loaded value.
10
31
  *
11
32
  * ```tsx
12
33
  * const [tab, setTab, tabHydrated] = usePersistedState("@react_buoy_custom_flags_tab", "flags");
34
+ *
35
+ * // A Set, stored as an array:
36
+ * const [pins, setPins] = usePersistedState(key, new Set<string>(), {
37
+ * parse: (raw) => new Set(JSON.parse(raw) as string[]),
38
+ * serialize: (set) => JSON.stringify([...set]),
39
+ * });
13
40
  * ```
14
41
  */
15
- export declare function usePersistedState<T>(key: string, defaultValue: T): [T, (next: T | ((prev: T) => T)) => void, boolean];
42
+ export declare function usePersistedState<T>(key: string, defaultValue: T, options?: PersistedStateOptions<T>): [T, (next: T | ((prev: T) => T)) => void, boolean];
43
+ /** Test seam: forget every hydrated value. */
44
+ export declare function resetPersistedStateCache(): void;
16
45
  //# sourceMappingURL=usePersistedState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usePersistedState.d.ts","sourceRoot":"","sources":["../../../../src/hooks/usePersistedState.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,GACd,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,CAAC,CAoDpD"}
1
+ {"version":3,"file":"usePersistedState.d.ts","sourceRoot":"","sources":["../../../../src/hooks/usePersistedState.ts"],"names":[],"mappings":"AAUA,oFAAoF;AACpF,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;IACvC,sEAAsE;IACtE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,EACf,OAAO,GAAE,qBAAqB,CAAC,CAAC,CAAM,GACrC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,CAAC,CA+DpD;AAED,8CAA8C;AAC9C,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}