@buoy-gg/time-machine 7.0.41 → 7.0.42

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 (172) hide show
  1. package/lib/commonjs/components/HeaderActions.js +1 -91
  2. package/lib/commonjs/components/HeaderReloadButton.js +1 -58
  3. package/lib/commonjs/components/TimeMachineBody.js +1 -282
  4. package/lib/commonjs/components/TimeMachineModal.js +1 -74
  5. package/lib/commonjs/components/confirm.js +2 -38
  6. package/lib/commonjs/components/floating/NamePromptModal.js +1 -193
  7. package/lib/commonjs/components/floating/TimeMachineFloatingTool.js +1 -715
  8. package/lib/commonjs/components/floating/armedPoint.js +1 -92
  9. package/lib/commonjs/components/floating/barSettings.js +1 -66
  10. package/lib/commonjs/components/format.js +1 -24
  11. package/lib/commonjs/components/list/CaptureBar.js +1 -97
  12. package/lib/commonjs/components/list/RestoreOutcomeCard.js +1 -175
  13. package/lib/commonjs/components/list/SnapshotRow.js +1 -170
  14. package/lib/commonjs/components/list/SourcesStrip.js +1 -172
  15. package/lib/commonjs/components/list/UndoDeleteBar.js +1 -85
  16. package/lib/commonjs/components/list/WipeAllRow.js +1 -46
  17. package/lib/commonjs/components/preview/ItemDiffPanel.js +1 -79
  18. package/lib/commonjs/components/preview/PreviewFlow.js +1 -51
  19. package/lib/commonjs/components/preview/RestorePointNameRow.js +1 -83
  20. package/lib/commonjs/components/preview/RestorePreviewScreen.js +1 -1010
  21. package/lib/commonjs/components/preview/verdictMeta.js +1 -58
  22. package/lib/commonjs/components/sources.js +1 -83
  23. package/lib/commonjs/hooks/useTimeMachine.js +1 -24
  24. package/lib/commonjs/index.js +1 -161
  25. package/lib/commonjs/preset.js +1 -56
  26. package/lib/commonjs/store/routeRestore.js +1 -188
  27. package/lib/commonjs/store/snapshotVault.js +1 -186
  28. package/lib/commonjs/store/sourceIds.js +1 -9
  29. package/lib/commonjs/store/sourceSettings.js +1 -79
  30. package/lib/commonjs/store/timeMachineStore.js +1 -848
  31. package/lib/commonjs/sync/timeMachineSyncAdapter.js +1 -258
  32. package/lib/commonjs/ui/SwipeActionsRow.js +1 -178
  33. package/lib/commonjs/ui/primitives.js +1 -172
  34. package/lib/commonjs/ui/tmTheme.js +1 -118
  35. package/lib/module/components/HeaderActions.js +1 -85
  36. package/lib/module/components/HeaderReloadButton.js +1 -53
  37. package/lib/module/components/TimeMachineBody.js +1 -277
  38. package/lib/module/components/TimeMachineModal.js +1 -68
  39. package/lib/module/components/confirm.js +2 -33
  40. package/lib/module/components/floating/NamePromptModal.js +1 -188
  41. package/lib/module/components/floating/TimeMachineFloatingTool.js +1 -708
  42. package/lib/module/components/floating/armedPoint.js +1 -82
  43. package/lib/module/components/floating/barSettings.js +1 -57
  44. package/lib/module/components/format.js +1 -19
  45. package/lib/module/components/list/CaptureBar.js +1 -92
  46. package/lib/module/components/list/RestoreOutcomeCard.js +1 -169
  47. package/lib/module/components/list/SnapshotRow.js +1 -167
  48. package/lib/module/components/list/SourcesStrip.js +1 -169
  49. package/lib/module/components/list/UndoDeleteBar.js +1 -82
  50. package/lib/module/components/list/WipeAllRow.js +1 -41
  51. package/lib/module/components/preview/ItemDiffPanel.js +1 -74
  52. package/lib/module/components/preview/PreviewFlow.js +1 -46
  53. package/lib/module/components/preview/RestorePointNameRow.js +1 -78
  54. package/lib/module/components/preview/RestorePreviewScreen.js +1 -1005
  55. package/lib/module/components/preview/verdictMeta.js +1 -54
  56. package/lib/module/components/sources.js +1 -73
  57. package/lib/module/hooks/useTimeMachine.js +1 -19
  58. package/lib/module/index.js +1 -46
  59. package/lib/module/preset.js +1 -51
  60. package/lib/module/store/routeRestore.js +1 -176
  61. package/lib/module/store/snapshotVault.js +1 -170
  62. package/lib/module/store/sourceIds.js +1 -5
  63. package/lib/module/store/sourceSettings.js +1 -69
  64. package/lib/module/store/timeMachineStore.js +1 -839
  65. package/lib/module/sync/timeMachineSyncAdapter.js +1 -253
  66. package/lib/module/ui/SwipeActionsRow.js +1 -173
  67. package/lib/module/ui/primitives.js +1 -164
  68. package/lib/module/ui/tmTheme.js +1 -114
  69. package/lib/web/index.mjs +2 -3
  70. package/package.json +7 -7
  71. package/lib/commonjs/components/HeaderActions.js.map +0 -1
  72. package/lib/commonjs/components/HeaderReloadButton.js.map +0 -1
  73. package/lib/commonjs/components/TimeMachineBody.js.map +0 -1
  74. package/lib/commonjs/components/TimeMachineModal.js.map +0 -1
  75. package/lib/commonjs/components/confirm.js.map +0 -1
  76. package/lib/commonjs/components/floating/NamePromptModal.js.map +0 -1
  77. package/lib/commonjs/components/floating/TimeMachineFloatingTool.js.map +0 -1
  78. package/lib/commonjs/components/floating/armedPoint.js.map +0 -1
  79. package/lib/commonjs/components/floating/barSettings.js.map +0 -1
  80. package/lib/commonjs/components/format.js.map +0 -1
  81. package/lib/commonjs/components/list/CaptureBar.js.map +0 -1
  82. package/lib/commonjs/components/list/RestoreOutcomeCard.js.map +0 -1
  83. package/lib/commonjs/components/list/SnapshotRow.js.map +0 -1
  84. package/lib/commonjs/components/list/SourcesStrip.js.map +0 -1
  85. package/lib/commonjs/components/list/UndoDeleteBar.js.map +0 -1
  86. package/lib/commonjs/components/list/WipeAllRow.js.map +0 -1
  87. package/lib/commonjs/components/preview/ItemDiffPanel.js.map +0 -1
  88. package/lib/commonjs/components/preview/PreviewFlow.js.map +0 -1
  89. package/lib/commonjs/components/preview/RestorePointNameRow.js.map +0 -1
  90. package/lib/commonjs/components/preview/RestorePreviewScreen.js.map +0 -1
  91. package/lib/commonjs/components/preview/verdictMeta.js.map +0 -1
  92. package/lib/commonjs/components/sources.js.map +0 -1
  93. package/lib/commonjs/hooks/useTimeMachine.js.map +0 -1
  94. package/lib/commonjs/index.js.map +0 -1
  95. package/lib/commonjs/preset.js.map +0 -1
  96. package/lib/commonjs/store/routeRestore.js.map +0 -1
  97. package/lib/commonjs/store/snapshotVault.js.map +0 -1
  98. package/lib/commonjs/store/sourceIds.js.map +0 -1
  99. package/lib/commonjs/store/sourceSettings.js.map +0 -1
  100. package/lib/commonjs/store/timeMachineStore.js.map +0 -1
  101. package/lib/commonjs/sync/timeMachineSyncAdapter.js.map +0 -1
  102. package/lib/commonjs/ui/SwipeActionsRow.js.map +0 -1
  103. package/lib/commonjs/ui/primitives.js.map +0 -1
  104. package/lib/commonjs/ui/tmTheme.js.map +0 -1
  105. package/lib/module/components/HeaderActions.js.map +0 -1
  106. package/lib/module/components/HeaderReloadButton.js.map +0 -1
  107. package/lib/module/components/TimeMachineBody.js.map +0 -1
  108. package/lib/module/components/TimeMachineModal.js.map +0 -1
  109. package/lib/module/components/confirm.js.map +0 -1
  110. package/lib/module/components/floating/NamePromptModal.js.map +0 -1
  111. package/lib/module/components/floating/TimeMachineFloatingTool.js.map +0 -1
  112. package/lib/module/components/floating/armedPoint.js.map +0 -1
  113. package/lib/module/components/floating/barSettings.js.map +0 -1
  114. package/lib/module/components/format.js.map +0 -1
  115. package/lib/module/components/list/CaptureBar.js.map +0 -1
  116. package/lib/module/components/list/RestoreOutcomeCard.js.map +0 -1
  117. package/lib/module/components/list/SnapshotRow.js.map +0 -1
  118. package/lib/module/components/list/SourcesStrip.js.map +0 -1
  119. package/lib/module/components/list/UndoDeleteBar.js.map +0 -1
  120. package/lib/module/components/list/WipeAllRow.js.map +0 -1
  121. package/lib/module/components/preview/ItemDiffPanel.js.map +0 -1
  122. package/lib/module/components/preview/PreviewFlow.js.map +0 -1
  123. package/lib/module/components/preview/RestorePointNameRow.js.map +0 -1
  124. package/lib/module/components/preview/RestorePreviewScreen.js.map +0 -1
  125. package/lib/module/components/preview/verdictMeta.js.map +0 -1
  126. package/lib/module/components/sources.js.map +0 -1
  127. package/lib/module/hooks/useTimeMachine.js.map +0 -1
  128. package/lib/module/index.js.map +0 -1
  129. package/lib/module/preset.js.map +0 -1
  130. package/lib/module/store/routeRestore.js.map +0 -1
  131. package/lib/module/store/snapshotVault.js.map +0 -1
  132. package/lib/module/store/sourceIds.js.map +0 -1
  133. package/lib/module/store/sourceSettings.js.map +0 -1
  134. package/lib/module/store/timeMachineStore.js.map +0 -1
  135. package/lib/module/sync/timeMachineSyncAdapter.js.map +0 -1
  136. package/lib/module/ui/SwipeActionsRow.js.map +0 -1
  137. package/lib/module/ui/primitives.js.map +0 -1
  138. package/lib/module/ui/tmTheme.js.map +0 -1
  139. package/lib/typescript/components/HeaderActions.d.ts.map +0 -1
  140. package/lib/typescript/components/HeaderReloadButton.d.ts.map +0 -1
  141. package/lib/typescript/components/TimeMachineBody.d.ts.map +0 -1
  142. package/lib/typescript/components/TimeMachineModal.d.ts.map +0 -1
  143. package/lib/typescript/components/confirm.d.ts.map +0 -1
  144. package/lib/typescript/components/floating/NamePromptModal.d.ts.map +0 -1
  145. package/lib/typescript/components/floating/TimeMachineFloatingTool.d.ts.map +0 -1
  146. package/lib/typescript/components/floating/armedPoint.d.ts.map +0 -1
  147. package/lib/typescript/components/floating/barSettings.d.ts.map +0 -1
  148. package/lib/typescript/components/format.d.ts.map +0 -1
  149. package/lib/typescript/components/list/CaptureBar.d.ts.map +0 -1
  150. package/lib/typescript/components/list/RestoreOutcomeCard.d.ts.map +0 -1
  151. package/lib/typescript/components/list/SnapshotRow.d.ts.map +0 -1
  152. package/lib/typescript/components/list/SourcesStrip.d.ts.map +0 -1
  153. package/lib/typescript/components/list/UndoDeleteBar.d.ts.map +0 -1
  154. package/lib/typescript/components/list/WipeAllRow.d.ts.map +0 -1
  155. package/lib/typescript/components/preview/ItemDiffPanel.d.ts.map +0 -1
  156. package/lib/typescript/components/preview/PreviewFlow.d.ts.map +0 -1
  157. package/lib/typescript/components/preview/RestorePointNameRow.d.ts.map +0 -1
  158. package/lib/typescript/components/preview/RestorePreviewScreen.d.ts.map +0 -1
  159. package/lib/typescript/components/preview/verdictMeta.d.ts.map +0 -1
  160. package/lib/typescript/components/sources.d.ts.map +0 -1
  161. package/lib/typescript/hooks/useTimeMachine.d.ts.map +0 -1
  162. package/lib/typescript/index.d.ts.map +0 -1
  163. package/lib/typescript/preset.d.ts.map +0 -1
  164. package/lib/typescript/store/routeRestore.d.ts.map +0 -1
  165. package/lib/typescript/store/snapshotVault.d.ts.map +0 -1
  166. package/lib/typescript/store/sourceIds.d.ts.map +0 -1
  167. package/lib/typescript/store/sourceSettings.d.ts.map +0 -1
  168. package/lib/typescript/store/timeMachineStore.d.ts.map +0 -1
  169. package/lib/typescript/sync/timeMachineSyncAdapter.d.ts.map +0 -1
  170. package/lib/typescript/ui/SwipeActionsRow.d.ts.map +0 -1
  171. package/lib/typescript/ui/primitives.d.ts.map +0 -1
  172. package/lib/typescript/ui/tmTheme.d.ts.map +0 -1
@@ -1,258 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.timeMachineSyncAdapter = void 0;
7
- var _sharedUi = require("@buoy-gg/shared-ui");
8
- var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
9
- var _timeMachineStore = require("../store/timeMachineStore");
10
- var _snapshotVault = require("../store/snapshotVault");
11
- var _routeRestore = require("../store/routeRestore");
12
- var _sourceSettings = require("../store/sourceSettings");
13
- var _sourceIds = require("../store/sourceIds");
14
- /**
15
- * Sync adapter for the Time Machine tool, consumed by @buoy-gg/external-sync's
16
- * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
17
- * this package doesn't need a dependency on it).
18
- *
19
- * Snapshots stay ON-DEVICE — getSnapshot ships METADATA only (list, provider
20
- * statuses, last restore outcome), far under the 2MB per-tool budget. Payload
21
- * inspection goes through the `inspect` action (8MB action-result budget).
22
- *
23
- * The `restore` action uses the store's scheduleReloadApp path for reload
24
- * mode, so the action RESULT is flushed to the broker before the JS realm
25
- * dies — a remote caller always gets its answer.
26
- */
27
-
28
- function providerStatuses() {
29
- return (0, _sharedUi.getStateSnapshotProviders)().map(p => {
30
- const s = p.status();
31
- return {
32
- id: p.id,
33
- label: p.label,
34
- canCapture: s.canCapture,
35
- canRestore: s.canRestore,
36
- detail: s.detail,
37
- enabled: (0, _sourceSettings.isSourceEnabled)(p.id)
38
- };
39
- });
40
- }
41
- function metadata() {
42
- const {
43
- snapshots,
44
- busy,
45
- lastOutcome
46
- } = _timeMachineStore.timeMachineStore.getState();
47
- const current = (0, _routeRestore.currentRoute)();
48
- return {
49
- snapshots,
50
- busy,
51
- lastOutcome,
52
- providers: providerStatuses(),
53
- // Route capture/restore is a device capability, not a snapshot provider —
54
- // a dashboard has no router of its own to probe, so it's mirrored here.
55
- route: {
56
- available: (0, _routeRestore.canNavigate)(),
57
- enabled: (0, _sourceSettings.isSourceEnabled)(_sourceIds.ROUTE_SOURCE_ID),
58
- ...(current ? {
59
- current: current.href
60
- } : {})
61
- }
62
- };
63
- }
64
- const timeMachineSyncAdapter = exports.timeMachineSyncAdapter = {
65
- // v2 adds `route` (device route capability) and `snapshots[].route`.
66
- version: 2,
67
- getSnapshot: () => metadata(),
68
- subscribe: onChange => {
69
- const unsubStore = _timeMachineStore.timeMachineStore.subscribe(onChange);
70
- const unsubProviders = (0, _sharedUi.subscribeToStateSnapshotProviders)(onChange);
71
- return () => {
72
- unsubStore();
73
- unsubProviders();
74
- };
75
- },
76
- actions: {
77
- list: () => metadata(),
78
- capture: async params => {
79
- const {
80
- name = "",
81
- sourceIds
82
- } = params ?? {};
83
- const meta = await _timeMachineStore.timeMachineStore.capture(name, sourceIds);
84
- return {
85
- captured: true,
86
- snapshot: meta
87
- };
88
- },
89
- captureBaseline: async () => {
90
- const meta = await _timeMachineStore.timeMachineStore.captureBaseline();
91
- return {
92
- captured: true,
93
- snapshot: meta
94
- };
95
- },
96
- /** Wipe every clearable source to fresh-install state, then reload. */
97
- wipeAll: async () => await _timeMachineStore.timeMachineStore.wipeAll(),
98
- /** mode "live" (default) replaces state in place; "reload" restores
99
- * persisted storage then reloads the JS bundle (always the path for
100
- * baseline snapshots). */
101
- restore: async params => {
102
- const {
103
- id,
104
- mode = "live",
105
- excludeKeys,
106
- restoreRoute
107
- } = params ?? {};
108
- if (!id) throw new Error("restore requires a snapshot `id`");
109
- return await _timeMachineStore.timeMachineStore.restore(id, mode, excludeKeys, {
110
- restoreRoute
111
- });
112
- },
113
- delete: async params => {
114
- const {
115
- id
116
- } = params ?? {};
117
- if (!id) throw new Error("delete requires a snapshot `id`");
118
- await _timeMachineStore.timeMachineStore.delete(id);
119
- return {
120
- deleted: true,
121
- id
122
- };
123
- },
124
- rename: async params => {
125
- const {
126
- id,
127
- name
128
- } = params ?? {};
129
- if (!id || !name) throw new Error("rename requires `id` and `name`");
130
- await _timeMachineStore.timeMachineStore.rename(id, name);
131
- return {
132
- renamed: true,
133
- id,
134
- name
135
- };
136
- },
137
- /**
138
- * Save (or clear with null/empty) the items a restore of this snapshot
139
- * must leave alone — the persisted form of the preview's checkboxes.
140
- */
141
- setExclusions: async params => {
142
- const {
143
- id,
144
- excludedKeys
145
- } = params ?? {};
146
- if (!id) throw new Error("setExclusions requires `id`");
147
- await _timeMachineStore.timeMachineStore.setExclusions(id, excludedKeys ?? null);
148
- return {
149
- id,
150
- excluded: excludedKeys?.length ?? 0
151
- };
152
- },
153
- /** Turn a restore point's route restore on or off. */
154
- setRestoreRoute: async params => {
155
- const {
156
- id,
157
- restoreRoute
158
- } = params ?? {};
159
- if (!id) throw new Error("setRestoreRoute requires `id`");
160
- await _timeMachineStore.timeMachineStore.setRestoreRoute(id, restoreRoute !== false);
161
- return {
162
- id,
163
- restoreRoute: restoreRoute !== false
164
- };
165
- },
166
- /** Copy a restore point so a variation can start from a known base. */
167
- duplicate: async params => {
168
- const {
169
- id
170
- } = params ?? {};
171
- if (!id) throw new Error("duplicate requires `id`");
172
- const snapshot = await _timeMachineStore.timeMachineStore.duplicate(id);
173
- if (!snapshot) throw new Error(`No snapshot with id "${id}"`);
174
- return {
175
- snapshot
176
- };
177
- },
178
- /** Save (or clear with null/empty) a snapshot's targeted-restore scope. */
179
- setScope: async params => {
180
- const {
181
- id,
182
- scope
183
- } = params ?? {};
184
- if (!id) throw new Error("setScope requires a snapshot `id`");
185
- await _timeMachineStore.timeMachineStore.setScope(id, scope ?? null);
186
- return {
187
- scoped: true,
188
- id,
189
- count: scope?.length ?? 0
190
- };
191
- },
192
- /**
193
- * Item-level restore preview, computed ON-DEVICE. Values above ~4KB per
194
- * item are omitted (valueOmitted) so the result stays far under the 8MB
195
- * action budget on any app size.
196
- */
197
- preview: async params => {
198
- const {
199
- id,
200
- compareTo
201
- } = params ?? {};
202
- if (!id) throw new Error("preview requires a snapshot `id`");
203
- const right = {
204
- snapshotId: id
205
- };
206
- const left = compareTo ? {
207
- snapshotId: compareTo
208
- } : "current";
209
- await _timeMachineStore.timeMachineStore.buildPreview(right, left);
210
- const preview = _timeMachineStore.timeMachineStore.getState().preview;
211
- if (!preview) throw new Error("preview build produced no result");
212
- const VALUE_BUDGET = 4 * 1024;
213
- return {
214
- left,
215
- right,
216
- builtAt: preview.builtAt,
217
- sources: preview.sources.map(src => ({
218
- ...src,
219
- items: src.items.map(item => {
220
- const oldBig = item.oldValue !== undefined && (0, _dataViewer.jsonLikelyLargerThan)(item.oldValue, VALUE_BUDGET);
221
- const newBig = item.newValue !== undefined && (0, _dataViewer.jsonLikelyLargerThan)(item.newValue, VALUE_BUDGET);
222
- return {
223
- ...item,
224
- oldValue: oldBig ? undefined : item.oldValue,
225
- newValue: newBig ? undefined : item.newValue,
226
- ...(oldBig || newBig ? {
227
- valueOmitted: true
228
- } : {})
229
- };
230
- })
231
- }))
232
- };
233
- },
234
- /** One source's captured payload, deserialized — for remote inspection. */
235
- inspect: async params => {
236
- const {
237
- id,
238
- sourceId
239
- } = params ?? {};
240
- if (!id || !sourceId) {
241
- throw new Error("inspect requires `id` and `sourceId`");
242
- }
243
- const stored = await (0, _snapshotVault.loadSnapshot)(id);
244
- if (!stored) throw new Error(`No snapshot with id "${id}"`);
245
- const payload = stored.data[sourceId];
246
- if (!payload) {
247
- throw new Error(`Snapshot "${id}" has no "${sourceId}" source`);
248
- }
249
- return {
250
- id,
251
- sourceId,
252
- warnings: stored.meta.sources[sourceId]?.warnings ?? [],
253
- data: (0, _sharedUi.superJsonDeserialize)(payload)
254
- };
255
- }
256
- }
257
- };
258
- //# sourceMappingURL=timeMachineSyncAdapter.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.timeMachineSyncAdapter=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _timeMachineStore=require("../store/timeMachineStore");var _snapshotVault=require("../store/snapshotVault");var _routeRestore=require("../store/routeRestore");var _sourceSettings=require("../store/sourceSettings");var _sourceIds=require("../store/sourceIds");function providerStatuses(){return(0,_sharedUi.getStateSnapshotProviders)().map(t=>{const e=t.status();return{id:t.id,label:t.label,canCapture:e.canCapture,canRestore:e.canRestore,detail:e.detail,enabled:(0,_sourceSettings.isSourceEnabled)(t.id)}})}function metadata(){const{snapshots:t,busy:e,lastOutcome:r}=_timeMachineStore.timeMachineStore.getState();const s=(0,_routeRestore.currentRoute)();return{snapshots:t,busy:e,lastOutcome:r,providers:providerStatuses(),route:{available:(0,_routeRestore.canNavigate)(),enabled:(0,_sourceSettings.isSourceEnabled)(_sourceIds.ROUTE_SOURCE_ID),...s?{current:s.href}:{}}}}const timeMachineSyncAdapter=exports.timeMachineSyncAdapter={version:2,getSnapshot:()=>metadata(),subscribe:t=>{const e=_timeMachineStore.timeMachineStore.subscribe(t);const r=(0,_sharedUi.subscribeToStateSnapshotProviders)(t);return()=>{e();r()}},actions:{list:()=>metadata(),capture:async t=>{const{name:e="",sourceIds:r}=t??{};const s=await _timeMachineStore.timeMachineStore.capture(e,r);return{captured:true,snapshot:s}},captureBaseline:async()=>{const t=await _timeMachineStore.timeMachineStore.captureBaseline();return{captured:true,snapshot:t}},wipeAll:async()=>await _timeMachineStore.timeMachineStore.wipeAll(),restore:async t=>{const{id:e,mode:r="live",excludeKeys:s,restoreRoute:a}=t??{};if(!e)throw new Error("restore requires a snapshot `id`");return await _timeMachineStore.timeMachineStore.restore(e,r,s,{restoreRoute:a})},delete:async t=>{const{id:e}=t??{};if(!e)throw new Error("delete requires a snapshot `id`");await _timeMachineStore.timeMachineStore.delete(e);return{deleted:true,id:e}},rename:async t=>{const{id:e,name:r}=t??{};if(!e||!r)throw new Error("rename requires `id` and `name`");await _timeMachineStore.timeMachineStore.rename(e,r);return{renamed:true,id:e,name:r}},setExclusions:async t=>{const{id:e,excludedKeys:r}=t??{};if(!e)throw new Error("setExclusions requires `id`");await _timeMachineStore.timeMachineStore.setExclusions(e,r??null);return{id:e,excluded:r?.length??0}},setRestoreRoute:async t=>{const{id:e,restoreRoute:r}=t??{};if(!e)throw new Error("setRestoreRoute requires `id`");await _timeMachineStore.timeMachineStore.setRestoreRoute(e,r!==false);return{id:e,restoreRoute:r!==false}},duplicate:async t=>{const{id:e}=t??{};if(!e)throw new Error("duplicate requires `id`");const r=await _timeMachineStore.timeMachineStore.duplicate(e);if(!r)throw new Error(`No snapshot with id "${e}"`);return{snapshot:r}},setScope:async t=>{const{id:e,scope:r}=t??{};if(!e)throw new Error("setScope requires a snapshot `id`");await _timeMachineStore.timeMachineStore.setScope(e,r??null);return{scoped:true,id:e,count:r?.length??0}},preview:async t=>{const{id:e,compareTo:r}=t??{};if(!e)throw new Error("preview requires a snapshot `id`");const s={snapshotId:e};const a=r?{snapshotId:r}:"current";await _timeMachineStore.timeMachineStore.buildPreview(s,a);const o=_timeMachineStore.timeMachineStore.getState().preview;if(!o)throw new Error("preview build produced no result");const i=4*1024;return{left:a,right:s,builtAt:o.builtAt,sources:o.sources.map(u=>({...u,items:u.items.map(n=>{const c=n.oldValue!==void 0&&(0,_dataViewer.jsonLikelyLargerThan)(n.oldValue,i);const d=n.newValue!==void 0&&(0,_dataViewer.jsonLikelyLargerThan)(n.newValue,i);return{...n,oldValue:c?void 0:n.oldValue,newValue:d?void 0:n.newValue,...c||d?{valueOmitted:true}:{}}})}))}},inspect:async t=>{const{id:e,sourceId:r}=t??{};if(!e||!r){throw new Error("inspect requires `id` and `sourceId`")}const s=await(0,_snapshotVault.loadSnapshot)(e);if(!s)throw new Error(`No snapshot with id "${e}"`);const a=s.data[r];if(!a){throw new Error(`Snapshot "${e}" has no "${r}" source`)}return{id:e,sourceId:r,warnings:s.meta.sources[r]?.warnings??[],data:(0,_sharedUi.superJsonDeserialize)(a)}}}};
@@ -1,178 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.SwipeActionsRow = SwipeActionsRow;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _tmTheme = require("./tmTheme");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- /**
12
- * Swipe-left-to-reveal-actions wrapper for a grouped-list row.
13
- *
14
- * Deliberately dependency-free (Animated + PanResponder): the package has no
15
- * gesture-handler peer and a devtool must not add one to the host app.
16
- *
17
- * Gesture contract, in the order the checks matter:
18
- * - The pan only claims the gesture once the finger has moved LEFT past a
19
- * threshold and is travelling more horizontally than vertically, so taps
20
- * still reach the row and vertical drags still scroll the list.
21
- * - Releasing past half the action width latches open; anything less snaps
22
- * shut, so a hesitant swipe never leaves a half-open row.
23
- * - Only one row stays open at a time (module-level latch below) — matching
24
- * iOS, and it means "swipe, then tap an action" can't hit the wrong row.
25
- */
26
-
27
- const ACTION_WIDTH = 84;
28
- /** Horizontal travel before the pan takes the gesture from the scroll view. */
29
- const CLAIM_THRESHOLD = 8;
30
-
31
- /** The one open row, so opening another closes it. */
32
- let closeOpenRow = null;
33
- /**
34
- * Everything gesture-side for one row, built once. Kept out of the component
35
- * so it reads as the state machine it is: `open` is the only state, and the
36
- * pan handlers are the only writers.
37
- */
38
- function createGesture(translateX, openWidth) {
39
- let open = false;
40
- const settle = next => {
41
- open = next;
42
- if (next) {
43
- if (closeOpenRow && closeOpenRow !== close) closeOpenRow();
44
- closeOpenRow = close;
45
- } else if (closeOpenRow === close) {
46
- closeOpenRow = null;
47
- }
48
- _reactNative.Animated.spring(translateX, {
49
- toValue: next ? -openWidth : 0,
50
- useNativeDriver: true,
51
- bounciness: 0,
52
- speed: 18
53
- }).start();
54
- };
55
- const close = () => settle(false);
56
- const pan = _reactNative.PanResponder.create({
57
- onMoveShouldSetPanResponder: (_e, g) => {
58
- const horizontal = Math.abs(g.dx) > Math.abs(g.dy) * 1.5;
59
- if (!horizontal) return false;
60
- // Left to open; right only matters when there is something to close.
61
- return g.dx < -CLAIM_THRESHOLD || open && g.dx > CLAIM_THRESHOLD;
62
- },
63
- onPanResponderMove: (_e, g) => {
64
- const base = open ? -openWidth : 0;
65
- // Clamp: no rubber-banding past the actions, none past closed.
66
- translateX.setValue(Math.min(0, Math.max(-openWidth, base + g.dx)));
67
- },
68
- onPanResponderRelease: (_e, g) => {
69
- const resting = (open ? -openWidth : 0) + g.dx;
70
- // A fast flick decides on velocity; a slow drag on distance.
71
- settle(g.vx < -0.5 ? true : g.vx > 0.5 ? false : resting < -openWidth / 2);
72
- },
73
- onPanResponderTerminate: () => settle(open)
74
- });
75
- return {
76
- pan,
77
- close
78
- };
79
- }
80
- function SwipeActionsRow({
81
- children,
82
- actions,
83
- testID
84
- }) {
85
- const openWidth = ACTION_WIDTH * actions.length;
86
- const translateX = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
87
- const gestureRef = (0, _react.useRef)(null);
88
- if (gestureRef.current === null) gestureRef.current = createGesture(translateX, openWidth);
89
- const {
90
- pan,
91
- close
92
- } = gestureRef.current;
93
-
94
- // A row that unmounts while open (deleted, filtered out, screen changed)
95
- // must not leave the latch pointing at a dead closer.
96
- (0, _react.useEffect)(() => () => {
97
- if (closeOpenRow === close) closeOpenRow = null;
98
- }, [close]);
99
-
100
- // The row is glass now, so the actions can't hide under it: they fade in
101
- // with the first points of the drag instead of sitting there at rest.
102
- const actionOpacity = translateX.interpolate({
103
- inputRange: [-24, 0],
104
- outputRange: [1, 0],
105
- extrapolate: "clamp"
106
- });
107
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
108
- style: styles.clip,
109
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
110
- style: [styles.actionLayer, {
111
- width: openWidth,
112
- opacity: actionOpacity
113
- }],
114
- children: actions.map(action => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
115
- style: [styles.action, action.background ? {
116
- backgroundColor: action.background
117
- } : null],
118
- onPress: () => {
119
- close();
120
- action.onPress();
121
- },
122
- accessibilityLabel: action.label,
123
- testID: action.testID ?? (testID ? `${testID}-${action.label.toLowerCase()}` : undefined),
124
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
125
- style: [styles.actionText, action.color ? {
126
- color: action.color
127
- } : null],
128
- numberOfLines: 1,
129
- children: action.label
130
- })
131
- }, action.label))
132
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
133
- style: [styles.content, {
134
- transform: [{
135
- translateX
136
- }]
137
- }],
138
- ...pan.panHandlers,
139
- children: children
140
- })]
141
- });
142
- }
143
- const styles = _reactNative.StyleSheet.create({
144
- clip: {
145
- overflow: "hidden"
146
- },
147
- // Own geometry, no percentages: an absoluteFill layer with a `height:
148
- // "100%"` child measured against this content-sized parent inflated every
149
- // row to several hundred points on iOS/Fabric.
150
- actionLayer: {
151
- position: "absolute",
152
- top: 0,
153
- bottom: 0,
154
- right: 0,
155
- flexDirection: "row"
156
- },
157
- action: {
158
- width: ACTION_WIDTH,
159
- height: "100%",
160
- backgroundColor: _tmTheme.tm.color.fillStrong,
161
- alignItems: "center",
162
- justifyContent: "center",
163
- paddingHorizontal: 6
164
- },
165
- actionText: {
166
- color: _tmTheme.tm.color.label,
167
- fontSize: _tmTheme.tm.font.footnote,
168
- fontWeight: "600",
169
- letterSpacing: _tmTheme.tm.tracking.control
170
- },
171
- // Glass, like the card it sits in. The actions underneath are faded out
172
- // at rest (see actionOpacity), which is what keeps them from bleeding
173
- // through a translucent row.
174
- content: {
175
- backgroundColor: _tmTheme.tm.color.group
176
- }
177
- });
178
- //# sourceMappingURL=SwipeActionsRow.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SwipeActionsRow=SwipeActionsRow;var _react=require("react");var _reactNative=require("react-native");var _tmTheme=require("./tmTheme");var _jsxRuntime=require("react/jsx-runtime");const ACTION_WIDTH=84;const CLAIM_THRESHOLD=8;let closeOpenRow=null;function createGesture(i,n){let r=false;const a=l=>{r=l;if(l){if(closeOpenRow&&closeOpenRow!==o)closeOpenRow();closeOpenRow=o}else if(closeOpenRow===o){closeOpenRow=null}_reactNative.Animated.spring(i,{toValue:l?-n:0,useNativeDriver:true,bounciness:0,speed:18}).start()};const o=()=>a(false);const c=_reactNative.PanResponder.create({onMoveShouldSetPanResponder:(l,e)=>{const s=Math.abs(e.dx)>Math.abs(e.dy)*1.5;if(!s)return false;return e.dx<-CLAIM_THRESHOLD||r&&e.dx>CLAIM_THRESHOLD},onPanResponderMove:(l,e)=>{const s=r?-n:0;i.setValue(Math.min(0,Math.max(-n,s+e.dx)))},onPanResponderRelease:(l,e)=>{const s=(r?-n:0)+e.dx;a(e.vx<-.5?true:e.vx>.5?false:s<-n/2)},onPanResponderTerminate:()=>a(r)});return{pan:c,close:o}}function SwipeActionsRow({children:i,actions:n,testID:r}){const a=ACTION_WIDTH*n.length;const o=(0,_react.useRef)(new _reactNative.Animated.Value(0)).current;const c=(0,_react.useRef)(null);if(c.current===null)c.current=createGesture(o,a);const{pan:l,close:e}=c.current;(0,_react.useEffect)(()=>()=>{if(closeOpenRow===e)closeOpenRow=null},[e]);const s=o.interpolate({inputRange:[-24,0],outputRange:[1,0],extrapolate:"clamp"});return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.clip,children:[(0,_jsxRuntime.jsx)(_reactNative.Animated.View,{style:[styles.actionLayer,{width:a,opacity:s}],children:n.map(t=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.action,t.background?{backgroundColor:t.background}:null],onPress:()=>{e();t.onPress()},accessibilityLabel:t.label,testID:t.testID??(r?`${r}-${t.label.toLowerCase()}`:void 0),children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionText,t.color?{color:t.color}:null],numberOfLines:1,children:t.label})},t.label))}),(0,_jsxRuntime.jsx)(_reactNative.Animated.View,{style:[styles.content,{transform:[{translateX:o}]}],...l.panHandlers,children:i})]})}const styles=_reactNative.StyleSheet.create({clip:{overflow:"hidden"},actionLayer:{position:"absolute",top:0,bottom:0,right:0,flexDirection:"row"},action:{width:ACTION_WIDTH,height:"100%",backgroundColor:_tmTheme.tm.color.fillStrong,alignItems:"center",justifyContent:"center",paddingHorizontal:6},actionText:{color:_tmTheme.tm.color.label,fontSize:_tmTheme.tm.font.footnote,fontWeight:"600",letterSpacing:_tmTheme.tm.tracking.control},content:{backgroundColor:_tmTheme.tm.color.group}});
@@ -1,172 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.DisclosureChevron = DisclosureChevron;
7
- exports.Footnote = Footnote;
8
- exports.Group = Group;
9
- exports.PillLabel = PillLabel;
10
- exports.SectionLabel = SectionLabel;
11
- var _react = require("react");
12
- var _reactNative = require("react-native");
13
- var _sharedUi = require("@buoy-gg/shared-ui");
14
- var _tmTheme = require("./tmTheme");
15
- var _jsxRuntime = require("react/jsx-runtime");
16
- /**
17
- * Grouped-inset list primitives — the building blocks of the Time Machine
18
- * surface (see ./tmTheme for the tokens and the promotion plan).
19
- *
20
- * The shape they compose to:
21
- *
22
- * SectionLabel SOURCES ← outside the card, uppercase
23
- * Group ┌──────────────────┐
24
- * <row> │ All sources … 6 ›│ ← rows are plain children;
25
- * <row> ├──────────────────┤ Group draws the hairlines
26
- * └──────────────────┘
27
- * Footnote Route is captured with… ← explains the group above
28
- *
29
- * Rows are whatever a screen needs — Group only owns the card, the clipping
30
- * and the separators, so a row never has to know its position in the list.
31
- */
32
-
33
- /** Uppercase section label that sits above a Group. */
34
- function SectionLabel({
35
- children,
36
- testID
37
- }) {
38
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
39
- style: styles.sectionLabel,
40
- testID: testID,
41
- children: children
42
- });
43
- }
44
-
45
- /**
46
- * Explanatory line under a Group ("Swipe a restore point to delete it").
47
- * `centered` matches the iOS convention for a footnote under a lone button.
48
- */
49
- function Footnote({
50
- children,
51
- centered,
52
- tone = "secondary",
53
- testID
54
- }) {
55
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
56
- style: [styles.footnote, centered ? styles.footnoteCentered : null, tone === "warning" ? styles.footnoteWarning : null],
57
- testID: testID,
58
- children: children
59
- });
60
- }
61
-
62
- /**
63
- * A rounded grouped card. Draws a hairline between consecutive children and
64
- * clips them, so a row can paint edge-to-edge (swipe actions, press washes)
65
- * without punching through the corners.
66
- */
67
- function Group({
68
- children,
69
- style
70
- }) {
71
- const rows = _react.Children.toArray(children);
72
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
73
- style: [styles.group, style],
74
- children: rows.map((row, index) =>
75
- /*#__PURE__*/
76
- // Children.toArray assigns stable synthetic keys ('.$id' for keyed
77
- // children), so a row keeps its identity as the list changes.
78
- (0, _jsxRuntime.jsxs)(_reactNative.View, {
79
- children: [index > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
80
- style: styles.separator
81
- }) : null, row]
82
- }, row.key ?? index))
83
- });
84
- }
85
-
86
- /**
87
- * Trailing disclosure chevron for a row that opens or expands.
88
- *
89
- * A real glyph, not two rotated hairlines: at this size the hand-built
90
- * version's strokes never met at the vertex, so it read as a broken arrow.
91
- */
92
- function DisclosureChevron() {
93
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
94
- size: 16,
95
- color: _tmTheme.tm.color.labelTertiary
96
- });
97
- }
98
-
99
- /**
100
- * Pill button. Parameterized by color rather than by variant flags so a
101
- * screen can name its own (`CapturePill`, `RestorePill`) in one line.
102
- */
103
- function PillLabel({
104
- label,
105
- color,
106
- background,
107
- testID
108
- }) {
109
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
110
- style: [styles.pill, {
111
- backgroundColor: background
112
- }],
113
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
114
- style: [styles.pillText, {
115
- color
116
- }],
117
- testID: testID,
118
- children: label
119
- })
120
- });
121
- }
122
- const styles = _reactNative.StyleSheet.create({
123
- sectionLabel: {
124
- color: _tmTheme.tm.color.labelSecondary,
125
- fontSize: _tmTheme.tm.font.footnote,
126
- fontWeight: "500",
127
- textTransform: "uppercase",
128
- letterSpacing: 0.4,
129
- paddingHorizontal: _tmTheme.tm.gutter + _tmTheme.tm.textInset,
130
- paddingTop: 22,
131
- paddingBottom: 7
132
- },
133
- footnote: {
134
- color: _tmTheme.tm.color.labelSecondary,
135
- fontSize: _tmTheme.tm.font.footnote,
136
- lineHeight: _tmTheme.tm.font.footnote * 1.35,
137
- paddingHorizontal: _tmTheme.tm.gutter + _tmTheme.tm.textInset,
138
- paddingTop: 7
139
- },
140
- footnoteCentered: {
141
- textAlign: "center"
142
- },
143
- footnoteWarning: {
144
- color: _tmTheme.tm.color.warning
145
- },
146
- group: {
147
- marginHorizontal: _tmTheme.tm.gutter,
148
- backgroundColor: _tmTheme.tm.color.group,
149
- borderRadius: _tmTheme.tm.radius.group,
150
- borderWidth: 1,
151
- borderColor: _tmTheme.tm.color.groupBorder,
152
- overflow: "hidden"
153
- },
154
- separator: {
155
- height: _reactNative.StyleSheet.hairlineWidth,
156
- marginLeft: _tmTheme.tm.separatorInset,
157
- backgroundColor: _tmTheme.tm.color.separator
158
- },
159
- pill: {
160
- height: 32,
161
- paddingHorizontal: 15,
162
- borderRadius: _tmTheme.tm.radius.pill,
163
- alignItems: "center",
164
- justifyContent: "center"
165
- },
166
- pillText: {
167
- fontSize: _tmTheme.tm.font.control,
168
- fontWeight: "600",
169
- letterSpacing: _tmTheme.tm.tracking.control
170
- }
171
- });
172
- //# sourceMappingURL=primitives.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DisclosureChevron=DisclosureChevron;exports.Footnote=Footnote;exports.Group=Group;exports.PillLabel=PillLabel;exports.SectionLabel=SectionLabel;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _tmTheme=require("./tmTheme");var _jsxRuntime=require("react/jsx-runtime");function SectionLabel({children:t,testID:e}){return(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,testID:e,children:t})}function Footnote({children:t,centered:e,tone:r="secondary",testID:o}){return(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.footnote,e?styles.footnoteCentered:null,r==="warning"?styles.footnoteWarning:null],testID:o,children:t})}function Group({children:t,style:e}){const r=_react.Children.toArray(t);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.group,e],children:r.map((o,n)=>(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[n>0?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.separator}):null,o]},o.key??n))})}function DisclosureChevron(){return(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_tmTheme.tm.color.labelTertiary})}function PillLabel({label:t,color:e,background:r,testID:o}){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.pill,{backgroundColor:r}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.pillText,{color:e}],testID:o,children:t})})}const styles=_reactNative.StyleSheet.create({sectionLabel:{color:_tmTheme.tm.color.labelSecondary,fontSize:_tmTheme.tm.font.footnote,fontWeight:"500",textTransform:"uppercase",letterSpacing:.4,paddingHorizontal:_tmTheme.tm.gutter+_tmTheme.tm.textInset,paddingTop:22,paddingBottom:7},footnote:{color:_tmTheme.tm.color.labelSecondary,fontSize:_tmTheme.tm.font.footnote,lineHeight:_tmTheme.tm.font.footnote*1.35,paddingHorizontal:_tmTheme.tm.gutter+_tmTheme.tm.textInset,paddingTop:7},footnoteCentered:{textAlign:"center"},footnoteWarning:{color:_tmTheme.tm.color.warning},group:{marginHorizontal:_tmTheme.tm.gutter,backgroundColor:_tmTheme.tm.color.group,borderRadius:_tmTheme.tm.radius.group,borderWidth:1,borderColor:_tmTheme.tm.color.groupBorder,overflow:"hidden"},separator:{height:_reactNative.StyleSheet.hairlineWidth,marginLeft:_tmTheme.tm.separatorInset,backgroundColor:_tmTheme.tm.color.separator},pill:{height:32,paddingHorizontal:15,borderRadius:_tmTheme.tm.radius.pill,alignItems:"center",justifyContent:"center"},pillText:{fontSize:_tmTheme.tm.font.control,fontWeight:"600",letterSpacing:_tmTheme.tm.tracking.control}});