@clickless/react 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1095 -2
  3. package/dist/actions/actionCalls.d.ts +50 -0
  4. package/dist/actions/actionRegistry.d.ts +78 -0
  5. package/dist/components/Adaptive.d.ts +116 -0
  6. package/dist/components/AdaptiveAction.d.ts +4 -0
  7. package/dist/components/AdaptiveProvider.d.ts +38 -0
  8. package/dist/components/AdaptiveRegion.d.ts +60 -0
  9. package/dist/components/ClicklessUiErrorBoundary.d.ts +24 -0
  10. package/dist/components/OriginalToolbar.d.ts +21 -0
  11. package/dist/components/PromptBar.d.ts +21 -0
  12. package/dist/components/PromptPanel.d.ts +103 -0
  13. package/dist/components/WorkingDots.d.ts +4 -0
  14. package/dist/components/focusAfterPromptAction.d.ts +15 -0
  15. package/dist/components/hostColorScheme.d.ts +35 -0
  16. package/dist/components/promptPanelStyles.d.ts +14 -0
  17. package/dist/core/applyOperations.d.ts +21 -0
  18. package/dist/core/colorContrast.d.ts +22 -0
  19. package/dist/core/defaultLayout.d.ts +12 -0
  20. package/dist/core/index.d.ts +8 -0
  21. package/dist/core/ownProperties.d.ts +11 -0
  22. package/dist/core/propValues.d.ts +8 -0
  23. package/dist/core/reconcileLayout.d.ts +59 -0
  24. package/dist/core/schemas.gen.d.ts +427 -0
  25. package/dist/core/validateActionCalls.d.ts +28 -0
  26. package/dist/core/validateManifest.d.ts +11 -0
  27. package/dist/core/validateOperations.d.ts +15 -0
  28. package/dist/engine/engineClient.d.ts +231 -0
  29. package/dist/engine/engineErrorMessages.d.ts +13 -0
  30. package/dist/engine/engineResponses.d.ts +201 -0
  31. package/dist/engine/plainReplies.d.ts +2 -0
  32. package/dist/hooks/useActionRunHistory.d.ts +12 -0
  33. package/dist/hooks/useAdaptiveAction.d.ts +11 -0
  34. package/dist/hooks/useAdaptiveRegion.d.ts +34 -0
  35. package/dist/hooks/useChangeHistory.d.ts +32 -0
  36. package/dist/hooks/useDictation.d.ts +50 -0
  37. package/dist/hooks/useEngineReachable.d.ts +5 -0
  38. package/dist/hooks/usePromptBar.d.ts +163 -0
  39. package/dist/hooks/useRegionGroup.d.ts +15 -0
  40. package/dist/index.d.ts +21 -0
  41. package/dist/index.js +6600 -0
  42. package/dist/presets/mergePresets.d.ts +20 -0
  43. package/dist/presets/propPresets.d.ts +305 -0
  44. package/dist/region/changedComponentIds.d.ts +13 -0
  45. package/dist/region/firstPaintOrder.d.ts +19 -0
  46. package/dist/region/previewRequests.d.ts +21 -0
  47. package/dist/region/regionContext.d.ts +96 -0
  48. package/dist/region/regionGroup.d.ts +189 -0
  49. package/dist/region/regionSnapshot.d.ts +52 -0
  50. package/dist/region/regionStore.d.ts +361 -0
  51. package/dist/region/responsiveColumns.d.ts +35 -0
  52. package/dist/region/retrier.d.ts +22 -0
  53. package/dist/region/savedLayoutParsing.d.ts +7 -0
  54. package/dist/region/settleIntoSavedLayout.d.ts +14 -0
  55. package/dist/region/textDirection.d.ts +12 -0
  56. package/dist/region/unsavedChangeSaver.d.ts +45 -0
  57. package/dist/region/unsavedChanges.d.ts +78 -0
  58. package/dist/region/userFacingTitle.d.ts +7 -0
  59. package/package.json +59 -3
@@ -0,0 +1,52 @@
1
+ import type { Layout, LayoutChange, Manifest } from "../core/index.js";
2
+ export interface RegionSnapshot {
3
+ /** Built from the mounted `Adaptive` components. Null until the region has mounted. */
4
+ manifest: Manifest | null;
5
+ /**
6
+ * The committed layout. `order` and `items` hold the components on screen;
7
+ * `offScreen` holds what is kept for the ones that are not.
8
+ */
9
+ layout: Layout | null;
10
+ /** A proposed layout awaiting `commitPreview`, `discardPreview` or `cancelPreview`. */
11
+ preview: Layout | null;
12
+ /**
13
+ * How the region first looked, before any change, while it is shown in place
14
+ * of the layout. Null otherwise, and always while there is a preview.
15
+ */
16
+ original: Layout | null;
17
+ /** True when what is on the screen differs from how it first looked. */
18
+ differsFromOriginal: boolean;
19
+ /**
20
+ * Ids of the components the preview, or the original while it is shown,
21
+ * draws differently from the layout. Empty when neither is showing.
22
+ */
23
+ changedComponentIds: ReadonlySet<string>;
24
+ /**
25
+ * How the saved layout had to change to fit the components now on screen:
26
+ * components new in this version, settings the manifest no longer allows,
27
+ * and what was dropped for good (components past the limit kept off screen,
28
+ * or entries with nothing saved). Empty when it fits. Components that are
29
+ * only off screen for now, such as another tab's, are not changes.
30
+ */
31
+ savedLayoutAdjustments: readonly LayoutChange[];
32
+ /** True while the saved layout is being fetched from the engine. */
33
+ loading: boolean;
34
+ /**
35
+ * True when the saved layout could not be fetched, so the screen may not
36
+ * show it. It is fetched again on its own, a few seconds later and then less
37
+ * often, and at once when the engine answers again after being out of
38
+ * reach; false once it has been.
39
+ */
40
+ loadFailed: boolean;
41
+ canUndo: boolean;
42
+ /** Number of the latest saved change. 0 when there is none, or no engine. */
43
+ revision: number;
44
+ /** True when changes are stored by the engine, so there is a history to read. */
45
+ hasHistory: boolean;
46
+ /**
47
+ * True while a change made with the application's own controls is shown but
48
+ * not saved yet, as when the engine cannot be reached. It is saved when the
49
+ * engine is back.
50
+ */
51
+ hasUnsavedChanges: boolean;
52
+ }
@@ -0,0 +1,361 @@
1
+ import { type Layout, type ApplyOperationsOutcome, type Component, type Manifest, type Operation } from "../core/index.js";
2
+ import { type EngineClient, type PreviewToPlanFrom } from "../engine/engineClient.js";
3
+ import type { HistoryPage, LayoutResponse, PlanResponse, UndoneChange } from "../engine/engineResponses.js";
4
+ import type { RegionSnapshot } from "./regionSnapshot.js";
5
+ import { type PreviewRequest } from "./previewRequests.js";
6
+ import { textDirectionToPlanWith } from "./textDirection.js";
7
+ /** How an undo went. */
8
+ export interface UndoResult {
9
+ /**
10
+ * True when part of the undone change stays in place in a region this undo
11
+ * was not asked about, such as one on another page, because that region
12
+ * changed again since.
13
+ */
14
+ keptElsewhere: boolean;
15
+ /** The change taken back, or null when that is not known, as from an engine that does not say. */
16
+ undoneChange: UndoneChange | null;
17
+ }
18
+ /**
19
+ * What became of the preview when a planner's answer came: a new one shows,
20
+ * holding that answer only; the answer was added to the one showing; nothing
21
+ * is shown for it, as for a question or a preview taken back whole; or it no
22
+ * longer fits the screen, and any preview showing is left as it was.
23
+ */
24
+ export type PlannedPreviewOutcome = "new" | "addedTo" | "none" | "doesNotFit";
25
+ /** A preview a prompt is planned from, taken as planning starts. */
26
+ export interface PreviewToBuildOn {
27
+ /** Handed back to `showPlannedPreview`, so the answer is added to this preview and no other. */
28
+ readonly handle: PendingPreview;
29
+ /** What the plan request carries of it. */
30
+ readonly planWith: PreviewToPlanFrom;
31
+ }
32
+ /** A change shown and not saved yet. Only the region's own store reads inside it. */
33
+ export interface PendingPreview {
34
+ layout: Layout;
35
+ operations: readonly Operation[];
36
+ /** The requests whose answers make it up, oldest first; none for one that did not come from a prompt. */
37
+ requests: readonly PreviewRequest[];
38
+ }
39
+ /** What an engine's answer to an undo says about how it went. */
40
+ export declare const undoResultOf: (undoAnswer: {
41
+ notUndoneIn?: string[];
42
+ undone?: unknown;
43
+ }) => UndoResult;
44
+ export interface RegionConfig {
45
+ regionId: string;
46
+ version: string;
47
+ columns: number;
48
+ title?: string;
49
+ /** Present, as false, only for a region that draws no grid of its own. */
50
+ grid?: false;
51
+ }
52
+ export type LayoutChangeHandler = (layout: Layout, operations: readonly Operation[]) => void;
53
+ /**
54
+ * What a turn to write does first with the changes not saved yet: send them,
55
+ * send them and refuse to go on if any could not be saved, or leave them.
56
+ */
57
+ export type UnsavedChangesFirst = "save" | "saveOrRefuse" | "leave";
58
+ /**
59
+ * Where a layout the engine gave came from: a fresh read, the saving of a
60
+ * change not saved yet, an undo, or a change saved by prompt or restore, with
61
+ * the `sequence` it took when it began.
62
+ */
63
+ export type SavedLayoutSource = "read" | "savedUnsavedChange" | "undo" | {
64
+ laterChangeSequence: number;
65
+ };
66
+ /**
67
+ * Holds one region's state. With an engine, every committed change is sent to
68
+ * it and its answer is the truth; without one, changes live in memory only.
69
+ *
70
+ * A change made with the application's own controls (one without a prompt)
71
+ * never waits on the engine: it is shown at once and saved behind the scenes.
72
+ * While the engine cannot be reached it is kept for the visit and saved when
73
+ * the engine is back, unless what it changed reads differently in the saved
74
+ * layout by then (see `carryOverUnsavedChanges`). Changes reach the engine in
75
+ * the order they were made: a prompt's change or a restore waits for the
76
+ * older ones to be saved, and is refused if they cannot be. An undo leaves
77
+ * them, since it takes the newest back itself when that is one of them.
78
+ */
79
+ export declare class RegionStore {
80
+ readonly regionId: string;
81
+ private readonly engine;
82
+ private readonly nextChangeSequence;
83
+ onLayoutChange: LayoutChangeHandler | undefined;
84
+ /**
85
+ * The columns this screen draws the layout in, set by the region as the
86
+ * screen's width changes. The planner is told when they are fewer than the
87
+ * layout's, so its replies describe what the user sees.
88
+ */
89
+ drawnColumns: number | null;
90
+ private regionConfig;
91
+ private registeredComponents;
92
+ private savedLayout;
93
+ private pendingPreview;
94
+ /** The last preview saved, so an answer planned from it is shown on the layout it became. */
95
+ private lastSavedPreview;
96
+ /** True while the region shows how it first looked in place of the layout. */
97
+ private originalShown;
98
+ private snapshotListeners;
99
+ private savedLayoutListeners;
100
+ private cachedSnapshot;
101
+ private latestSavedRevision;
102
+ private latestSavedChangeId;
103
+ private savedLayoutLoading;
104
+ private loadFailed;
105
+ private loadStarted;
106
+ private engineAnswered;
107
+ private commitInProgress;
108
+ private engineCanUndo;
109
+ /** Without an engine: the layout before each change, and the change, oldest first. */
110
+ private undoStack;
111
+ private writeQueue;
112
+ /** Shown on top of `savedLayout`. Only ever holds anything with an engine. */
113
+ private readonly unsavedChanges;
114
+ /** The `sequence` of each saved change an undo here could take back, oldest first. */
115
+ private savedChangeSequences;
116
+ private stopListeningToReachability;
117
+ private readonly loadRetrier;
118
+ private readonly unsavedChangeSaver;
119
+ /**
120
+ * `nextChangeSequence` numbers changes across the regions of one provider, so the
121
+ * newest among several regions can be told.
122
+ */
123
+ constructor(regionId: string, engine: EngineClient | null, nextChangeSequence: () => number);
124
+ /** Anything else getting an answer is a sign the engine is back: what waits to be tried again is tried now. */
125
+ private listenToReachability;
126
+ /** The `sequence` of the newest change not saved yet, or 0 when there is none. */
127
+ get newestUnsavedChangeSequence(): number;
128
+ /** True while a change not saved yet may still be saved, whether or not the region is on the screen. */
129
+ get hasSaveableUnsavedChanges(): boolean;
130
+ /**
131
+ * The `sequence` of the newest change here an undo could take back, saved or
132
+ * not, or 0 when there is none from this visit.
133
+ */
134
+ get newestChangeSequence(): number;
135
+ /** The highest `sequence` among the saved changes here that an undo could still take back, or 0. */
136
+ get newestSavedChangeSequence(): number;
137
+ /** Kept in the order the engine took them, so an undo takes the last off as the engine does. */
138
+ private recordSavedChange;
139
+ /** A `sequence` for a change saved by prompt or restore, taken when it begins. */
140
+ takeChangeSequence: () => number;
141
+ /** True when the newest change here is one not saved yet, which only this screen can take back. */
142
+ private newestChangeIsUnsaved;
143
+ /** True when the saved layout of a region on the screen could not be read, and no read is under way. */
144
+ private get needsLoadRetry();
145
+ /** The number of the latest saved change, as the engine last gave it. */
146
+ get savedRevision(): number;
147
+ /** The number, counted across all the user's regions, of the change that made the latest revision. */
148
+ get latestChangeId(): number;
149
+ subscribe: (snapshotListener: () => void) => (() => void);
150
+ getSnapshot: () => RegionSnapshot;
151
+ getServerSnapshot: () => RegionSnapshot;
152
+ /** A layout set earlier in the session wins over `initialLayout`, so it survives a remount. */
153
+ mountRegion: (mountedRegionConfig: RegionConfig, initialLayout: Layout | undefined) => (() => void);
154
+ /** Reads the saved layout before the region mounts, unless it has been read or is being read. */
155
+ preloadSavedLayout: () => void;
156
+ private startLoading;
157
+ /** Reads the engine's copy again. If that fails, the region keeps the layout it has. */
158
+ private refreshSavedLayout;
159
+ /** The element an item is drawn in, or null if it is not mounted. */
160
+ elementOf: (componentId: string) => Element | null;
161
+ /** Which way the page reads where this region is drawn, as a plan request carries it. */
162
+ textDirectionToPlanWith: () => ReturnType<typeof textDirectionToPlanWith>;
163
+ /** What the planner is told about the screen besides the manifest: only what differs from a wide one. */
164
+ drawnColumnsToPlanWith: () => {
165
+ drawnColumns?: number;
166
+ };
167
+ registerComponent: (component: Component, element: Element | null) => (() => void);
168
+ /**
169
+ * Validates the operations and commits them if all are valid.
170
+ *
171
+ * A change from a prompt is shown once the engine has saved it, and rejects
172
+ * with an `EngineError` if the engine cannot be reached or the layout changed
173
+ * elsewhere. A change without a prompt, as from the application's own
174
+ * controls, is shown and resolves at once, and is saved behind the scenes:
175
+ * later, if the engine cannot be reached.
176
+ */
177
+ applyOperations: (operations: readonly Operation[], prompt?: string, message?: string, viaVoice?: boolean) => Promise<ApplyOperationsOutcome>;
178
+ /**
179
+ * `applyOperations` for a change that is shown before the engine has it.
180
+ * Async so that a fault, such as a region that is not mounted, rejects as it
181
+ * does for every other change.
182
+ */
183
+ private applyAtOnce;
184
+ /**
185
+ * Sends the changes not saved yet to the engine, oldest first. Run at the
186
+ * start of each turn to write but an undo's (see `oneWriteAtATime`), so they
187
+ * reach the engine before anything made after them. Never rejects: what
188
+ * could not be saved is tried again later.
189
+ */
190
+ private saveUnsavedChanges;
191
+ /**
192
+ * Drops the changes kept for this visit only that are older than a change
193
+ * saved by prompt or restore in another region of the same prompt box,
194
+ * which did not reach this one. They would otherwise be undone before it.
195
+ */
196
+ giveWayToLaterChange: (laterChangeSequence: number) => void;
197
+ /**
198
+ * Stops trying the engine again in the background, to save changes or to
199
+ * read the saved layout, for when the provider holding this store has gone.
200
+ */
201
+ dispose: () => void;
202
+ /** Takes up what `dispose` stopped, as when React mounts the provider once more. */
203
+ resume: () => void;
204
+ /** A turn to write with nothing of its own to write: it saves what is not saved yet, in turn. */
205
+ private queueSavingUnsavedChanges;
206
+ /** Shows the result of the operations without committing it. */
207
+ previewOperations: (operations: readonly Operation[], prompt?: string, message?: string, viaVoice?: boolean) => ApplyOperationsOutcome;
208
+ private showPreview;
209
+ /**
210
+ * Saves the preview. Resolves to null when there is none. A preview that
211
+ * turns out not to be valid is taken off the screen, since it can never be saved.
212
+ */
213
+ commitPreview: () => Promise<ApplyOperationsOutcome | null>;
214
+ /**
215
+ * Shows the region as it first looked, before any change, without saving
216
+ * anything, or goes back to its layout. A preview, or any change to the
217
+ * layout, ends it.
218
+ */
219
+ showOriginal: (shown: boolean) => void;
220
+ /** Takes the preview off the screen without saving it. */
221
+ cancelPreview: () => void;
222
+ /**
223
+ * `cancelPreview`, for when the user themselves chose not to keep it. The
224
+ * engine is told, so the application's team can see where a prompt's result
225
+ * was not what its user meant. A preview that did not come from a prompt has
226
+ * nothing to say about that and is only cancelled, as is one that is already
227
+ * being saved.
228
+ */
229
+ discardPreview: () => void;
230
+ /**
231
+ * Tells the engine the preview from a prompt was not kept. One that is being
232
+ * saved is not reported. Record-keeping only: the user is never made to wait
233
+ * on it or told it failed.
234
+ */
235
+ private reportPreviewNotKept;
236
+ /**
237
+ * Returns to the layout before the last committed change. A change not saved
238
+ * yet is taken back at once, on this screen alone, as the engine never had it.
239
+ */
240
+ undoLastChange: () => Promise<UndoResult>;
241
+ /**
242
+ * Takes back the newest change, if it is one not saved yet and not on its
243
+ * way to the engine. Returns it, or null when there was none to take back.
244
+ */
245
+ private takeBackUnsavedChange;
246
+ /**
247
+ * Puts a committed change on the screen: any preview goes, and the host is
248
+ * told. Returns the layout shown, or null when the region is not mounted.
249
+ */
250
+ private showChange;
251
+ /**
252
+ * Returns the screen to how it was after the given saved change; 0 is the
253
+ * original layout. Later changes stay in the history. Resolves to the number
254
+ * of the saved change the restore itself made.
255
+ */
256
+ restoreRevision: (revision: number) => Promise<number>;
257
+ /**
258
+ * Saved changes, newest first, `limit` at a time. Pass `before` to read older
259
+ * ones, and `promptedOnly` to leave out changes that were not made by prompt.
260
+ */
261
+ readHistory: (options: {
262
+ limit: number;
263
+ before?: number;
264
+ promptedOnly?: boolean;
265
+ }) => Promise<HistoryPage>;
266
+ /**
267
+ * Asks the engine to turn a request into operations and previews them.
268
+ * The returned message is written for the user.
269
+ *
270
+ * A request made while a preview is showing is planned from that preview,
271
+ * so a follow-up such as "bigger again" builds on what the user is looking
272
+ * at: the operations answered are what it changes from there, and are added
273
+ * to the preview, which is then kept or discarded as one change. An answer
274
+ * with nothing to change, such as a question, leaves the preview as it is.
275
+ * If the saved layout changed elsewhere since the preview was made, it is
276
+ * fetched again, which takes the preview off, and this rejects with an
277
+ * `EngineError` whose code is "conflict". If no answer comes, the preview
278
+ * stays, and can still be kept.
279
+ */
280
+ planFromPrompt: (prompt: string, viaVoice?: boolean) => Promise<PlanResponse>;
281
+ /** `planFromPrompt`, saying what became of the preview. */
282
+ planAndShowPreview: (prompt: string, viaVoice?: boolean) => Promise<{
283
+ planResponse: PlanResponse;
284
+ previewOutcome: PlannedPreviewOutcome;
285
+ }>;
286
+ /**
287
+ * The preview a prompt typed now is planned from, or null when there is
288
+ * none. One being saved is not built on: it is about to be the saved layout.
289
+ */
290
+ previewToBuildOn: () => PreviewToBuildOn | null;
291
+ /**
292
+ * Sends a plan request made with `previewToBuildOn`. When the engine says the
293
+ * preview no longer applies to the saved layout it was made on, the preview
294
+ * can never be saved, so it is taken off, as one that left the screen.
295
+ */
296
+ answeringForPreview: <T>(previewToBuildOn: PreviewToBuildOn | null, sendRequest: () => Promise<T>) => Promise<T>;
297
+ /**
298
+ * Shows what the planner proposed for a prompt. Planned from the preview in
299
+ * `previewBuiltOn`, it is added to that preview while it still shows; one
300
+ * that takes the whole preview back leaves nothing to keep, so the preview
301
+ * counts as discarded. Planned from the saved layout, it replaces any
302
+ * preview that was showing, which counts as discarded.
303
+ */
304
+ showPlannedPreview: (operations: readonly Operation[], previewRequest: PreviewRequest, previewBuiltOn: PreviewToBuildOn | null) => PlannedPreviewOutcome;
305
+ /**
306
+ * Shows a layout the engine stored for this region in a change it made to
307
+ * several at once, as `applyOperations` does for a change to this one.
308
+ */
309
+ acceptSavedLayout: (layoutResponse: LayoutResponse, operations: readonly Operation[], layoutSource: Exclude<SavedLayoutSource, "read" | "savedUnsavedChange">) => void;
310
+ /**
311
+ * Runs one saved change at a time. Each is checked against, and sent with the
312
+ * number of, the change before it, so two made in quick succession do not
313
+ * both claim to follow the same one. Without an engine nothing waits.
314
+ * `unsavedChangesFirst` says what happens first to the changes not saved yet: an
315
+ * undo leaves them, since it takes the newest back itself; a prompt's change
316
+ * or a restore is refused when they cannot be saved, so it never reaches the
317
+ * engine ahead of an older one.
318
+ */
319
+ oneWriteAtATime: <T>(writeChange: () => Promise<T>, unsavedChangesFirst?: UnsavedChangesFirst) => Promise<T>;
320
+ /** Throws why the changes not saved yet could not be saved, if any still wait. */
321
+ private refuseWhileUnsaved;
322
+ /** When the engine says the layout changed elsewhere, fetches it before failing. */
323
+ private reloadingOnConflict;
324
+ /**
325
+ * Fetches the engine's copy of the layout, which replaces the one shown and
326
+ * takes any preview off: on every mount, and after the engine said this
327
+ * region changed elsewhere.
328
+ */
329
+ loadSavedLayout: () => Promise<void>;
330
+ /**
331
+ * Calls `savedLayoutListener` when the engine has answered for the saved layout, just
332
+ * before the screen is told, while it still shows what it showed before.
333
+ */
334
+ beforeSavedLayoutIsShown: (savedLayoutListener: () => void) => (() => void);
335
+ /**
336
+ * Takes the engine's copy as the saved layout. Changes not saved yet stay on
337
+ * top of it. After a fresh read or an undo, those that cannot be carried
338
+ * over to it are still shown for the rest of the visit, so nothing changes
339
+ * under the user, but are never saved. A change saved by prompt or restore
340
+ * stands over the older ones: those kept for the visit only, and those that
341
+ * cannot be carried over to it, go.
342
+ */
343
+ private acceptEngineLayout;
344
+ /** Tells the host. A fault in its handler is reported, and does not stop the SDK keeping its own state right. */
345
+ private reportLayoutChange;
346
+ /**
347
+ * What the operations would do to the saved layout, without doing it.
348
+ * `fallbackManifest` stands in for the manifest when the region is no longer mounted.
349
+ */
350
+ applyToCurrentLayout: (operations: readonly Operation[], fallbackManifest?: Manifest | null) => {
351
+ manifest: Manifest;
352
+ applyOutcome: ApplyOperationsOutcome;
353
+ };
354
+ /**
355
+ * The screen changed under the preview, as on leaving the page, so it no
356
+ * longer describes it: it is taken off and reported as abandoned.
357
+ */
358
+ private dropPendingPreview;
359
+ private notifyListeners;
360
+ private computeSnapshot;
361
+ }
@@ -0,0 +1,35 @@
1
+ /** A region's columns: one number, or the columns to draw from each screen width up, in pixels. */
2
+ export type RegionColumns = number | Readonly<Record<number, number>>;
3
+ /**
4
+ * The columns a region's layout is kept in, and the columns it is drawn in on
5
+ * this screen.
6
+ *
7
+ * With breakpoints, the layout is kept in the widest one's columns whatever the
8
+ * screen, so the planner, the saved layout and every check see one grid, and a
9
+ * change made on a phone does not narrow what the user set for a wide screen.
10
+ * A narrower screen draws the same layout in fewer columns (see `drawnSpans`).
11
+ * The server, and the first paint in the browser, draw the widest.
12
+ */
13
+ export declare function useResponsiveColumns(columns: RegionColumns): {
14
+ layoutColumns: number;
15
+ drawnColumns: number;
16
+ };
17
+ /**
18
+ * How many drawn columns an item `w` columns wide in the layout spans, on its
19
+ * own: its share of the width, rounded. Used only before the region has
20
+ * mounted; after that `drawnSpans` places whole rows.
21
+ */
22
+ export declare function drawnSpan(width: number, layoutColumns: number, drawnColumns: number): number;
23
+ /**
24
+ * How many drawn columns each item spans, worked out a row at a time so the
25
+ * rows stay as they are on a wide screen: an item covering columns `start` to
26
+ * `end` of the wide grid covers the same share of the narrow one, rounded at
27
+ * its edges, so the spans of one row add up to the drawn columns. Items are
28
+ * given in the order they are drawn, with their width and height, and each
29
+ * list is one grid.
30
+ */
31
+ export declare function drawnSpans(grids: readonly (readonly {
32
+ id: string;
33
+ w: number;
34
+ h: number;
35
+ }[])[], layoutColumns: number, drawnColumns: number): ReadonlyMap<string, number>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Tries something again later, less often each time it fails, and at once
3
+ * when the device comes back online. Stopped, as when the provider holding it
4
+ * has gone, it schedules nothing until started again.
5
+ */
6
+ export declare class Retrier {
7
+ private readonly attemptAgain;
8
+ private retryTimer;
9
+ private nextRetryDelayMs;
10
+ private stopped;
11
+ constructor(attemptAgain: () => void);
12
+ get isWaiting(): boolean;
13
+ /** Tries again later, unless already waiting to or stopped. */
14
+ schedule(): void;
15
+ /** Tries again at once, if it was waiting to. */
16
+ retryNow: () => void;
17
+ /** What it was waiting to try worked, so the next failure waits the shortest time again. */
18
+ succeeded(): void;
19
+ cancel(): void;
20
+ stop(): void;
21
+ start(): void;
22
+ }
@@ -0,0 +1,7 @@
1
+ import { Layout } from "../core/index.js";
2
+ /**
3
+ * The layout if it has the shape of one, else null. A saved layout comes from
4
+ * storage the SDK does not control, and one that is cut short or from another
5
+ * format must fall back to the default instead of breaking the screen.
6
+ */
7
+ export declare function parseSavedLayout(savedLayout: unknown): Layout | null;
@@ -0,0 +1,14 @@
1
+ import type { Layout } from "../core/index.js";
2
+ import type { RegionStore } from "./regionStore.js";
3
+ /**
4
+ * While the saved layout is being fetched the region shows what it has, often
5
+ * the default, and nothing waits for the engine. When the saved layout arrives,
6
+ * each item that it puts somewhere else glides there from where it was, and an
7
+ * item that was not drawn fades in, so the change reads as the screen settling
8
+ * rather than jumping. Users who ask for less motion get the change at once.
9
+ *
10
+ * Where items were is read the moment the engine answers, while the screen
11
+ * still shows the old layout, so scrolling or the page's own content moving
12
+ * while the engine was slow makes nothing slide.
13
+ */
14
+ export declare function useSettleIntoSavedLayout(regionStore: RegionStore, layout: Layout | null): void;
@@ -0,0 +1,12 @@
1
+ import type { TextDirection } from "../engine/engineClient.js";
2
+ /**
3
+ * Which way the page reads where `element` is drawn, or at its root without
4
+ * one. Read from the browser, so it holds however the page set it: a `dir`
5
+ * attribute on the element or a parent, or a stylesheet's `direction`. A
6
+ * `lang` attribute alone does not change it.
7
+ */
8
+ export declare function textDirectionAt(element: Element | null | undefined): TextDirection;
9
+ /** The direction as a plan request carries it: only when the page reads right to left. */
10
+ export declare function textDirectionToPlanWith(element: Element | null | undefined): {
11
+ textDirection?: TextDirection;
12
+ };
@@ -0,0 +1,45 @@
1
+ import type { LayoutResponse } from "../engine/engineResponses.js";
2
+ import type { UnsavedChange } from "./unsavedChanges.js";
3
+ /** What the saver needs from the region whose changes it saves. */
4
+ export interface UnsavedChangeSaverHost {
5
+ /** The oldest change the engine may still take. */
6
+ nextChangeToSave(): UnsavedChange | undefined;
7
+ /** Runs before the first change is sent, so each is sent against the layout the engine has. */
8
+ prepareToSave(): Promise<void>;
9
+ sendChange(change: UnsavedChange): Promise<LayoutResponse>;
10
+ /** Fetches the engine's copy, after it said the layout changed elsewhere. */
11
+ reloadSavedLayout(): Promise<void>;
12
+ changeSaved(change: UnsavedChange, layoutResponse: LayoutResponse): void;
13
+ /** Asks for a turn to write, in which `save` runs. */
14
+ queueSaving(): void;
15
+ }
16
+ /**
17
+ * Saves a region's unsaved changes behind the scenes. What the engine could
18
+ * not take is tried again later, sooner if the device comes back online.
19
+ */
20
+ export declare class UnsavedChangeSaver {
21
+ private readonly host;
22
+ private savingChange;
23
+ private lastSaveFailure;
24
+ private readonly retrier;
25
+ constructor(host: UnsavedChangeSaverHost);
26
+ /** The change on its way to the engine right now, if any. */
27
+ get changeBeingSaved(): UnsavedChange | null;
28
+ get isWaitingToRetry(): boolean;
29
+ /** Why the last attempt to save stopped short, or null when everything it tried was saved. */
30
+ get lastFailure(): unknown;
31
+ /**
32
+ * Sends the changes the engine may still take, oldest first. Never rejects:
33
+ * what could not be saved is tried again later.
34
+ */
35
+ save(): Promise<void>;
36
+ /** Tries again later, unless already waiting to, stopped, or there is nothing to save. */
37
+ scheduleRetry(): void;
38
+ /** Tries again at once, if it was waiting to. */
39
+ retryNow(): void;
40
+ /** Nothing is left to save, so nothing needs trying again. */
41
+ cancelRetry(): void;
42
+ /** Tries nothing more until `start`, even after a save already under way fails. */
43
+ stop(): void;
44
+ start(): void;
45
+ }
@@ -0,0 +1,78 @@
1
+ import { type Layout, type Manifest, type Operation } from "../core/index.js";
2
+ /** A change made with the application's own controls that the engine has not saved yet. */
3
+ export interface UnsavedChange {
4
+ operations: readonly Operation[];
5
+ /** The screen it was made on, for saving it after the region has gone. */
6
+ manifest: Manifest;
7
+ /**
8
+ * Counted across the regions of one provider, so the newest change among
9
+ * several can be undone first. Only the order of these numbers means anything.
10
+ */
11
+ sequence: number;
12
+ /**
13
+ * False once it will never be saved: the engine refused it for good, or it
14
+ * clashes with the saved layout read since it was made. It is then kept for
15
+ * this visit only, and gives way to the next change that is saved.
16
+ */
17
+ saveable: boolean;
18
+ }
19
+ /**
20
+ * A region's changes not saved yet, oldest first, shown on top of its saved
21
+ * layout until the engine has them.
22
+ */
23
+ export declare class UnsavedChangeList {
24
+ private readonly nextChangeSequence;
25
+ private changes;
26
+ constructor(nextChangeSequence: () => number);
27
+ get isEmpty(): boolean;
28
+ /** True while any of them may still be saved. */
29
+ get hasSaveable(): boolean;
30
+ /** The `sequence` of the newest, or 0 when there is none. */
31
+ get newestSequence(): number;
32
+ /** The screen the newest was made on, for when the region is no longer mounted. */
33
+ get newestManifest(): Manifest | undefined;
34
+ /** The oldest the engine may still take. */
35
+ nextToSave(): UnsavedChange | undefined;
36
+ add(operations: readonly Operation[], manifest: Manifest): void;
37
+ /** Takes back the newest, unless it is `changeBeingSaved`. Returns the one taken back, or null. */
38
+ takeBackNewest(changeBeingSaved: UnsavedChange | null): UnsavedChange | null;
39
+ /**
40
+ * The engine has `change` now. It goes, and so do the changes kept for the
41
+ * visit only that were made before it: changes are saved oldest first, so
42
+ * those are all that come before it, and it is newer than every one of them.
43
+ */
44
+ dropSavedChange(change: UnsavedChange): void;
45
+ /**
46
+ * Drops the changes kept for the visit only that are older than a change
47
+ * saved by prompt or restore, numbered `laterChangeSequence`, which
48
+ * stands over them. Returns true when there were any.
49
+ */
50
+ giveWayTo(laterChangeSequence: number): boolean;
51
+ /**
52
+ * After a fresh read of the saved layout, carries the changes from the
53
+ * layout they were made on to it (see `carryOverUnsavedChanges`). Those that
54
+ * cannot be carried are kept for the visit only.
55
+ */
56
+ carryOverToReadLayout(manifest: Manifest, shownLayout: Layout, savedLayout: Layout): void;
57
+ /**
58
+ * After a change saved by prompt or restore, numbered
59
+ * `laterChangeSequence`: the older changes are carried over to the layout it
60
+ * made where they can be and dropped where they cannot, since it stands over
61
+ * them. Those made while it was on its way are newer, and stay as they are.
62
+ */
63
+ carryOverToLaterChange(manifest: Manifest, shownLayout: Layout, savedLayout: Layout, laterChangeSequence: number): void;
64
+ /** The layout with every change that fits it laid on top. One that does not waits, unshown, until it does. */
65
+ applyTo(manifest: Manifest, layout: Layout): Layout;
66
+ }
67
+ /**
68
+ * The changes that can be carried from the layout they were made on,
69
+ * `shownLayout`, to the saved layout the engine has now given, `savedLayout`.
70
+ * A change is carried only when what it acts on reads the same in both: a
71
+ * setting the user changed while their saved layout could not be read, or
72
+ * that was changed elsewhere meanwhile, is not overwritten with a value worked
73
+ * out from a screen they were not shown. One whose component is not on the
74
+ * screen now is carried as it is when what it acts on reads the same: it is
75
+ * saved with the screen it was made on. Both layouts must be reconciled
76
+ * against `manifest`.
77
+ */
78
+ export declare function carryOverUnsavedChanges(manifest: Manifest, shownLayout: Layout, savedLayout: Layout, changes: readonly UnsavedChange[]): UnsavedChange[];
@@ -0,0 +1,7 @@
1
+ import type { Component } from "../core/index.js";
2
+ /**
3
+ * The component's title, for text the user reads, or null when it has none of
4
+ * its own. A component given no title carries its id as its title, for the
5
+ * planner, and an id such as "txns" means nothing to the user.
6
+ */
7
+ export declare function userFacingTitleOf(component: Pick<Component, "id" | "title">): string | null;