@voltro/client 0.13.0 → 0.15.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.
- package/CHANGELOG.md +412 -0
- package/dist/index.d.ts +270 -17
- package/dist/index.js +747 -491
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -174,6 +174,16 @@ export declare interface ApiHandle {
|
|
|
174
174
|
readonly errorBus: RpcErrorBus;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Apply seeds from the hydration payload, BEFORE the first client render.
|
|
179
|
+
*
|
|
180
|
+
* Unknown store names are skipped rather than throwing: a payload can outlive a
|
|
181
|
+
* deploy (a cached document, a user with a stale tab), and refusing to boot the
|
|
182
|
+
* app over a store somebody deleted would turn a cosmetic staleness into a
|
|
183
|
+
* blank page.
|
|
184
|
+
*/
|
|
185
|
+
export declare const applyStoreSeeds: (seeds: ReadonlyArray<StoreSeed> | undefined) => void;
|
|
186
|
+
|
|
177
187
|
export declare interface AsyncValidationResult {
|
|
178
188
|
readonly status: ValidationStatus;
|
|
179
189
|
readonly valid: boolean | undefined;
|
|
@@ -351,6 +361,9 @@ export declare const clearMutations: () => void;
|
|
|
351
361
|
/** Drop successfully-sent entries (call after a drain to compact the queue). */
|
|
352
362
|
export declare const clearSent: (queue: Outbox) => Outbox;
|
|
353
363
|
|
|
364
|
+
/** Drop the recorded history (tests, and a devtools "clear"). */
|
|
365
|
+
export declare const clearStoreHistory: () => void;
|
|
366
|
+
|
|
354
367
|
export declare const CLIENT_NAME: "framework-client";
|
|
355
368
|
|
|
356
369
|
export declare interface ClientErrorEvent {
|
|
@@ -533,11 +546,28 @@ export declare interface DataTableState<Row> {
|
|
|
533
546
|
readonly hasMore: boolean;
|
|
534
547
|
}
|
|
535
548
|
|
|
549
|
+
/** All defined stores, in definition order. */
|
|
550
|
+
export declare const definedStores: () => ReadonlyArray<StoreHandle<never>>;
|
|
551
|
+
|
|
536
552
|
/** Declare a typed analytics event. */
|
|
537
553
|
export declare const defineEvent: <const Name extends string, A, I>(name: Name, payload: Schema.Schema<A, I>) => EventDescriptor<Name, A>;
|
|
538
554
|
|
|
539
|
-
/**
|
|
540
|
-
|
|
555
|
+
/**
|
|
556
|
+
* Define a store.
|
|
557
|
+
*
|
|
558
|
+
* `initial` is a FUNCTION, not a value, so every keyed instance gets its own
|
|
559
|
+
* fresh state rather than sharing one object — the bug you find weeks later
|
|
560
|
+
* when editing order A also edits order B.
|
|
561
|
+
*/
|
|
562
|
+
export declare const defineStore: <S extends object>(name: string, initial: () => S, options?: {
|
|
563
|
+
readonly persist?: PersistOptions<S>;
|
|
564
|
+
}) => StoreHandle<S>;
|
|
565
|
+
|
|
566
|
+
/** Identity helper (like `defineTracking('CheckoutButton', { onMount: 'checkout.viewed' })`).
|
|
567
|
+
*
|
|
568
|
+
* Pass the component's props as the type argument to get a typed catalogue:
|
|
569
|
+
* `defineTracking<ComposerProps>('TodoComposer', { onSubmit: (p) => … })`. */
|
|
570
|
+
export declare const defineTracking: <P = Record<string, unknown>>(name: string, map: TrackingMap<P>) => TrackingSpec<P>;
|
|
541
571
|
|
|
542
572
|
/**
|
|
543
573
|
* Pure projection: turn a capability manifest into one `EntityAdminSpec` per
|
|
@@ -588,10 +618,8 @@ declare interface EntryState<T> {
|
|
|
588
618
|
cachedSnapshot: CacheSnapshot<T> | null;
|
|
589
619
|
}
|
|
590
620
|
|
|
591
|
-
/**
|
|
592
|
-
|
|
593
|
-
* rpc wire emits. Returns undefined for non-tagged errors. */
|
|
594
|
-
export declare const errorTag: (err: unknown) => string | undefined;
|
|
621
|
+
/** Compares two selector results. Return true to keep the previous value. */
|
|
622
|
+
export declare type Equals<T> = (a: T, b: T) => boolean;
|
|
595
623
|
|
|
596
624
|
export declare interface EventCatalog {
|
|
597
625
|
readonly names: ReadonlyArray<string>;
|
|
@@ -711,6 +739,8 @@ export declare const getMutationNotifier: () => MutationNotifier | undefined;
|
|
|
711
739
|
/** Read the current feed. Newest-first; up to MAX_MUTATIONS entries. */
|
|
712
740
|
export declare const getMutations: () => ReadonlyArray<MutationEvent>;
|
|
713
741
|
|
|
742
|
+
declare type Listener = () => void;
|
|
743
|
+
|
|
714
744
|
/**
|
|
715
745
|
* Non-fetching cache used as a LOADING baseline:
|
|
716
746
|
* - during SSR (no runtime / no provider), and
|
|
@@ -737,6 +767,8 @@ export declare class LoadingSubscriptionCache extends SubscriptionCache {
|
|
|
737
767
|
};
|
|
738
768
|
}
|
|
739
769
|
|
|
770
|
+
export declare const makeStoreSeedBag: () => StoreSeedBag;
|
|
771
|
+
|
|
740
772
|
/** Exported for tests: the inspect URL this hook fetches. */
|
|
741
773
|
export declare const manifestUrl: (base: string) => string;
|
|
742
774
|
|
|
@@ -884,6 +916,31 @@ declare interface PermissionState_2 {
|
|
|
884
916
|
}
|
|
885
917
|
export { PermissionState_2 as PermissionState }
|
|
886
918
|
|
|
919
|
+
/**
|
|
920
|
+
* Where a store's state survives a reload.
|
|
921
|
+
*
|
|
922
|
+
* Declarative because the hand-rolled version is always the same three bugs:
|
|
923
|
+
* reading before the browser exists (SSR crashes), writing on every keystroke
|
|
924
|
+
* (a synchronous localStorage write per character), and a parse that throws on
|
|
925
|
+
* a value written by an older version of the app and takes the boot with it.
|
|
926
|
+
*/
|
|
927
|
+
export declare interface PersistOptions<S> {
|
|
928
|
+
/** Storage key. Namespaced by the caller — this is written verbatim. */
|
|
929
|
+
readonly key: string;
|
|
930
|
+
/** `local` survives a browser restart; `session` lasts the tab. */
|
|
931
|
+
readonly storage?: 'local' | 'session';
|
|
932
|
+
/** Persist only part of the state — a draft, not a whole UI tree. */
|
|
933
|
+
readonly pick?: (state: S) => Partial<S>;
|
|
934
|
+
/**
|
|
935
|
+
* Migrate a value written by an older shape.
|
|
936
|
+
*
|
|
937
|
+
* Returning `undefined` DISCARDS it, which is the right answer far more often
|
|
938
|
+
* than guessing: a stale draft is an annoyance, a half-migrated one is a bug
|
|
939
|
+
* report nobody can reproduce.
|
|
940
|
+
*/
|
|
941
|
+
readonly migrate?: (stored: unknown) => Partial<S> | undefined;
|
|
942
|
+
}
|
|
943
|
+
|
|
887
944
|
/** Structural mirror of @voltro/runtime's PreviewDiff (client stays decoupled). */
|
|
888
945
|
export declare interface PreviewDiff {
|
|
889
946
|
readonly rows: ReadonlyArray<PreviewRowDiff>;
|
|
@@ -996,10 +1053,13 @@ export declare const reportClientError: (error: unknown, context?: Record<string
|
|
|
996
1053
|
* module-global flags + any pending grace-period timer). */
|
|
997
1054
|
export declare const _resetFrameworkRuntimesWarning: () => void;
|
|
998
1055
|
|
|
1056
|
+
/** Test helper: forget every defined store. NEVER call this in app code. */
|
|
1057
|
+
export declare const resetStoreRegistryForTests: () => void;
|
|
1058
|
+
|
|
999
1059
|
export declare const resolveByTag: (client: unknown, tag: string) => unknown;
|
|
1000
1060
|
|
|
1001
1061
|
/** Resolve one map entry against the props. Pure. */
|
|
1002
|
-
export declare const resolveTrackingEvent: (entry: TrackingEntry | undefined, props:
|
|
1062
|
+
export declare const resolveTrackingEvent: <P>(entry: TrackingEntry<P> | undefined, props: P) => TrackingEvent | null;
|
|
1003
1063
|
|
|
1004
1064
|
export declare interface ResourceCanInput {
|
|
1005
1065
|
/** The action being gated (e.g. `'read'`, `'write'`, `'delete'`). */
|
|
@@ -1163,6 +1223,18 @@ export declare const schemaToColumns: (schema: Schema.Schema.Any) => ReadonlyArr
|
|
|
1163
1223
|
*/
|
|
1164
1224
|
export declare const schemaToFields: (schema: Schema.Schema.Any) => ReadonlyArray<FieldDescriptor>;
|
|
1165
1225
|
|
|
1226
|
+
/**
|
|
1227
|
+
* Seed a store for THIS request's hydration. Call it anywhere on the server
|
|
1228
|
+
* during a render — a loader, a layout loader — and the value reaches the
|
|
1229
|
+
* client's first render without any serialization step of your own.
|
|
1230
|
+
*/
|
|
1231
|
+
export declare const seedStore: <S extends object>(handle: StoreHandle<S>, value: Partial<S>, opts?: {
|
|
1232
|
+
readonly key?: string;
|
|
1233
|
+
}) => void;
|
|
1234
|
+
|
|
1235
|
+
/** Reads a slice out of the state. Its RESULT identity decides re-render. */
|
|
1236
|
+
export declare type Selector<S, T> = (state: S) => T;
|
|
1237
|
+
|
|
1166
1238
|
/** One persisted/wire element of a resumable stream. Mirrors `@voltro/ai`'s
|
|
1167
1239
|
* `SeqEvent` without taking a dependency on it (the client stays AI-agnostic). */
|
|
1168
1240
|
export declare interface SeqElement<E> {
|
|
@@ -1220,6 +1292,12 @@ export declare type SequenceResult<Ctx> = {
|
|
|
1220
1292
|
* at boot, next to your toast provider. */
|
|
1221
1293
|
export declare const setMutationNotifier: (notifier: MutationNotifier | undefined) => void;
|
|
1222
1294
|
|
|
1295
|
+
/**
|
|
1296
|
+
* Install the request-scoped bag resolver. Server-side only; pass `null` to
|
|
1297
|
+
* uninstall (tests).
|
|
1298
|
+
*/
|
|
1299
|
+
export declare const setStoreSeedResolver: (resolver: (() => StoreSeedBag | null) | null) => void;
|
|
1300
|
+
|
|
1223
1301
|
/**
|
|
1224
1302
|
* Transition a pending mutation to 'success' or 'error'. Updates the
|
|
1225
1303
|
* existing entry in-place (preserves order in the buffer) so the
|
|
@@ -1236,6 +1314,17 @@ export declare const settleMutation: (id: string, outcome: {
|
|
|
1236
1314
|
readonly error: unknown;
|
|
1237
1315
|
}) => void;
|
|
1238
1316
|
|
|
1317
|
+
/**
|
|
1318
|
+
* Shallow equality over own enumerable entries — the comparator a selector that
|
|
1319
|
+
* BUILDS something needs.
|
|
1320
|
+
*
|
|
1321
|
+
* `(s) => ({ a: s.a, b: s.b })` and `(s) => s.items.filter(…)` return a fresh
|
|
1322
|
+
* reference every call, so the default identity check always reports "changed".
|
|
1323
|
+
* Comparing one level deep is what makes those selectors behave the way reading
|
|
1324
|
+
* a single field already does.
|
|
1325
|
+
*/
|
|
1326
|
+
export declare const shallow: <T>(a: T, b: T) => boolean;
|
|
1327
|
+
|
|
1239
1328
|
/** Shallow element-wise array equality. Pure — the cache-invalidation core. */
|
|
1240
1329
|
export declare const shallowArrayEqual: (a: ReadonlyArray<unknown>, b: ReadonlyArray<unknown>) => boolean;
|
|
1241
1330
|
|
|
@@ -1337,6 +1426,141 @@ export declare interface StepOptions<Ctx, Result> {
|
|
|
1337
1426
|
* from a step that is being rolled back after it. */
|
|
1338
1427
|
export declare type StepUndo<Result, Ctx = Record<string, unknown>> = (result: Result, ctx: Ctx) => unknown | Promise<unknown>;
|
|
1339
1428
|
|
|
1429
|
+
export declare interface StoreHandle<S> {
|
|
1430
|
+
readonly name: string;
|
|
1431
|
+
/**
|
|
1432
|
+
* Read a slice in a component. Re-renders ONLY when the selector's RESULT
|
|
1433
|
+
* changes, so a store with fifty fields re-renders a component that reads one
|
|
1434
|
+
* of them exactly as often as that one field changes.
|
|
1435
|
+
*
|
|
1436
|
+
* "Changes" means `Object.is` by default. A selector that BUILDS something —
|
|
1437
|
+
* an object literal, a mapped or filtered array — returns a fresh reference
|
|
1438
|
+
* every call, so pass `{ equals: shallow }` for those. In dev the framework
|
|
1439
|
+
* warns, once, when it detects the case.
|
|
1440
|
+
*/
|
|
1441
|
+
readonly use: <T>(selector: Selector<S, T>, opts?: StoreUseOptions<T>) => T;
|
|
1442
|
+
/** The underlying instance — for actions, effects and tests. */
|
|
1443
|
+
readonly instance: (key?: string) => StoreInstance<S>;
|
|
1444
|
+
/** Shorthand for `instance(key).get()`. */
|
|
1445
|
+
readonly get: (key?: string) => S;
|
|
1446
|
+
/** Shorthand for `instance(key).set(...)`. */
|
|
1447
|
+
readonly set: (next: Partial<S> | Updater<S>, key?: string, label?: string) => void;
|
|
1448
|
+
/**
|
|
1449
|
+
* Run several writes as ONE — one notification, one devtools entry named
|
|
1450
|
+
* `label`, one undo step.
|
|
1451
|
+
*
|
|
1452
|
+
* Without it, an action that touches three fields is three of each: the
|
|
1453
|
+
* devtools show three anonymous writes instead of the thing the user did,
|
|
1454
|
+
* and Ctrl-Z walks back through a third of a change at a time. React batches
|
|
1455
|
+
* the RE-RENDERS on its own; it cannot batch the meaning.
|
|
1456
|
+
*
|
|
1457
|
+
* ```ts
|
|
1458
|
+
* checkout.batch('applyCoupon', () => {
|
|
1459
|
+
* checkout.set({ coupon })
|
|
1460
|
+
* checkout.set({ total: recompute(coupon) })
|
|
1461
|
+
* })
|
|
1462
|
+
* ```
|
|
1463
|
+
*
|
|
1464
|
+
* If `fn` throws, every write it made is rolled back — nothing was announced
|
|
1465
|
+
* yet, so a failed action cannot leave the half-applied state that is the
|
|
1466
|
+
* usual reason people reach for a transaction. A nested batch joins its
|
|
1467
|
+
* parent. Passing an `async` function is an error: everything after its
|
|
1468
|
+
* first `await` would land outside the batch.
|
|
1469
|
+
*/
|
|
1470
|
+
readonly batch: (label: string, fn: () => void, key?: string) => void;
|
|
1471
|
+
/**
|
|
1472
|
+
* Revert the most recent write to this instance.
|
|
1473
|
+
*
|
|
1474
|
+
* Possible only because every write goes through one seam — the previous
|
|
1475
|
+
* state is recorded there, so undo is a lookup rather than a feature the
|
|
1476
|
+
* store had to be designed around. Returns false when there is nothing to
|
|
1477
|
+
* undo (nothing recorded, or the history has scrolled past it).
|
|
1478
|
+
*/
|
|
1479
|
+
readonly undo: (key?: string) => boolean;
|
|
1480
|
+
/** Re-apply the write an `undo` reverted. False when there is nothing ahead. */
|
|
1481
|
+
readonly redo: (key?: string) => boolean;
|
|
1482
|
+
/** Whether `undo` / `redo` would do anything — for disabling a button. */
|
|
1483
|
+
readonly canUndo: (key?: string) => boolean;
|
|
1484
|
+
readonly canRedo: (key?: string) => boolean;
|
|
1485
|
+
/** Drop a keyed instance's state. The global instance cannot be dropped. */
|
|
1486
|
+
readonly release: (key: string) => void;
|
|
1487
|
+
/** Every live key — for devtools and for tests that assert cleanup. */
|
|
1488
|
+
readonly keys: () => ReadonlyArray<string>;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
export declare const storeHistory: () => ReadonlyArray<StoreMutation>;
|
|
1492
|
+
|
|
1493
|
+
/** One store instance: the global one, or one per key. */
|
|
1494
|
+
export declare interface StoreInstance<S> {
|
|
1495
|
+
/** Current state. For actions and tests — components read via a selector. */
|
|
1496
|
+
readonly get: () => S;
|
|
1497
|
+
/** Replace the state. A partial object is merged; a function is applied. */
|
|
1498
|
+
readonly set: (next: Partial<S> | Updater<S>, label?: string) => void;
|
|
1499
|
+
/** Apply many writes as ONE. See {@link StoreHandle.batch}. */
|
|
1500
|
+
readonly batch: (label: string, fn: () => void) => void;
|
|
1501
|
+
/** Reset to the initial state this instance was created with. */
|
|
1502
|
+
readonly reset: () => void;
|
|
1503
|
+
/** Low-level subscribe (what `use` is built on). Returns an unsubscribe. */
|
|
1504
|
+
readonly subscribe: (listener: Listener) => () => void;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
/** One recorded write. `prev`/`next` are the state objects themselves — they
|
|
1508
|
+
* are immutable by convention, so holding them costs a reference. */
|
|
1509
|
+
export declare interface StoreMutation {
|
|
1510
|
+
readonly store: string;
|
|
1511
|
+
/** The keyed instance, or undefined for the global one. */
|
|
1512
|
+
readonly key?: string;
|
|
1513
|
+
/** Whatever the caller passed as `set(next, label)`. */
|
|
1514
|
+
readonly label?: string;
|
|
1515
|
+
/**
|
|
1516
|
+
* True when this write WAS an undo.
|
|
1517
|
+
*
|
|
1518
|
+
* Recorded so a devtools feed shows the complete story, and skipped by
|
|
1519
|
+
* `undo()` so repeated calls walk BACK through the stack instead of toggling
|
|
1520
|
+
* between the last two states. Undoing an undo is a redo, and a redo that
|
|
1521
|
+
* pretends to be an undo is the kind of surprise nobody debugs twice.
|
|
1522
|
+
*/
|
|
1523
|
+
readonly isUndo?: true;
|
|
1524
|
+
readonly prev: unknown;
|
|
1525
|
+
readonly next: unknown;
|
|
1526
|
+
readonly at: number;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
/** One seeded value, as it travels in the hydration payload. */
|
|
1530
|
+
export declare interface StoreSeed {
|
|
1531
|
+
readonly store: string;
|
|
1532
|
+
readonly key?: string;
|
|
1533
|
+
readonly value: unknown;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
/** Collects seeds for ONE request. The server creates one per render. */
|
|
1537
|
+
export declare interface StoreSeedBag {
|
|
1538
|
+
readonly seeds: StoreSeed[];
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
export declare interface StoreUseOptions<T> {
|
|
1542
|
+
/** Which instance to read. Omitted = the global one. */
|
|
1543
|
+
readonly key?: string;
|
|
1544
|
+
/**
|
|
1545
|
+
* How to decide the selected value is unchanged. Defaults to `Object.is`.
|
|
1546
|
+
*
|
|
1547
|
+
* Pass {@link shallow} whenever the selector builds something new — an object
|
|
1548
|
+
* literal, a mapped or filtered array. Identity comparison can never see two
|
|
1549
|
+
* fresh references as equal, so without it such a selector re-renders on
|
|
1550
|
+
* every change to any field in the store.
|
|
1551
|
+
*/
|
|
1552
|
+
readonly equals?: Equals<T>;
|
|
1553
|
+
/**
|
|
1554
|
+
* Keep this keyed instance alive after its last subscriber unmounts.
|
|
1555
|
+
*
|
|
1556
|
+
* The default is to drop it, because instances are created on demand and
|
|
1557
|
+
* nothing else would ever remove them: a table keyed by row id would
|
|
1558
|
+
* accumulate one per row ever rendered. Set this for state that must survive
|
|
1559
|
+
* navigating away and back — a half-filled form, say.
|
|
1560
|
+
*/
|
|
1561
|
+
readonly retain?: boolean;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1340
1564
|
/** Subscribe to client errors. Returns an unsubscribe fn. */
|
|
1341
1565
|
export declare const subscribeClientErrors: (listener: ClientErrorListener) => (() => void);
|
|
1342
1566
|
|
|
@@ -1345,6 +1569,9 @@ export declare const subscribeClientTraces: (listener: ClientTraceListener) => (
|
|
|
1345
1569
|
|
|
1346
1570
|
export declare const subscribeMutations: (cb: () => void) => (() => void);
|
|
1347
1571
|
|
|
1572
|
+
/** Subscribe to writes — the devtools panel's feed. Returns an unsubscribe. */
|
|
1573
|
+
export declare const subscribeStoreHistory: (listener: Listener) => (() => void);
|
|
1574
|
+
|
|
1348
1575
|
export declare class SubscriptionCache {
|
|
1349
1576
|
private readonly entries;
|
|
1350
1577
|
private readonly inactiveTtlMs;
|
|
@@ -1649,8 +1876,14 @@ export declare interface SubscriptionStateWithFallback<T> extends SubscriptionMe
|
|
|
1649
1876
|
readonly isEmpty: boolean;
|
|
1650
1877
|
}
|
|
1651
1878
|
|
|
1652
|
-
/** A map entry: a bare event name, or a function of the component's props.
|
|
1653
|
-
|
|
1879
|
+
/** A map entry: a bare event name, or a function of the component's props.
|
|
1880
|
+
*
|
|
1881
|
+
* `P` is the component's prop type. It defaults to an untyped bag so a
|
|
1882
|
+
* catalogue can stay loose, but naming it is what makes the payload builders
|
|
1883
|
+
* read real fields instead of indexing into `unknown` and casting — and a cast
|
|
1884
|
+
* is exactly what an event catalogue must not need, because it is also the
|
|
1885
|
+
* list of what leaves the browser. */
|
|
1886
|
+
export declare type TrackingEntry<P = Record<string, unknown>> = string | ((props: P) => TrackingEvent);
|
|
1654
1887
|
|
|
1655
1888
|
/** A resolved analytics event: a name + arbitrary payload. */
|
|
1656
1889
|
export declare type TrackingEvent = {
|
|
@@ -1659,21 +1892,38 @@ export declare type TrackingEvent = {
|
|
|
1659
1892
|
|
|
1660
1893
|
/** The declarative map. `onMount`/`onUnmount` are lifecycle; every other key is
|
|
1661
1894
|
* a CALLBACK PROP name to wrap (so calling `onClick` also fires its event). */
|
|
1662
|
-
export declare interface TrackingMap {
|
|
1663
|
-
readonly onMount?: TrackingEntry
|
|
1664
|
-
readonly onUnmount?: TrackingEntry
|
|
1665
|
-
readonly [callback: string]: TrackingEntry | undefined;
|
|
1895
|
+
export declare interface TrackingMap<P = Record<string, unknown>> {
|
|
1896
|
+
readonly onMount?: TrackingEntry<P>;
|
|
1897
|
+
readonly onUnmount?: TrackingEntry<P>;
|
|
1898
|
+
readonly [callback: string]: TrackingEntry<P> | undefined;
|
|
1666
1899
|
}
|
|
1667
1900
|
|
|
1668
1901
|
/** Where resolved events go — the analytics sink (the client→server transport
|
|
1669
1902
|
* provides this; tests provide a recorder). */
|
|
1670
1903
|
export declare type TrackingSink = (event: TrackingEvent) => void;
|
|
1671
1904
|
|
|
1672
|
-
export declare interface TrackingSpec {
|
|
1905
|
+
export declare interface TrackingSpec<P = Record<string, unknown>> {
|
|
1673
1906
|
readonly name: string;
|
|
1674
|
-
readonly map: TrackingMap
|
|
1907
|
+
readonly map: TrackingMap<P>;
|
|
1675
1908
|
}
|
|
1676
1909
|
|
|
1910
|
+
/**
|
|
1911
|
+
* Jump one instance to the state recorded at `index` — the devtools panel's
|
|
1912
|
+
* back/forward.
|
|
1913
|
+
*
|
|
1914
|
+
* Deliberately NOT built on `undo`. Undo is a stack that CONSUMES entries, so
|
|
1915
|
+
* stepping forward again would be impossible; time travel needs the log to stay
|
|
1916
|
+
* intact and a cursor to move over it. `side` picks which half of the recorded
|
|
1917
|
+
* step to restore, so stepping back from entry i means `('before', i)` and
|
|
1918
|
+
* forward means `('after', i)`.
|
|
1919
|
+
*
|
|
1920
|
+
* The jump is itself recorded — the log should show what happened, including
|
|
1921
|
+
* that somebody travelled — but marked so `undo()` skips it, exactly as an undo
|
|
1922
|
+
* is skipped. Returns false for an index that no longer exists (the log is
|
|
1923
|
+
* bounded, so a long session scrolls past the beginning).
|
|
1924
|
+
*/
|
|
1925
|
+
export declare const travelToStoreState: (index: number, side: "before" | "after") => boolean;
|
|
1926
|
+
|
|
1677
1927
|
export declare const UNDO_APPLY_TAG = "__voltro.undo.apply";
|
|
1678
1928
|
|
|
1679
1929
|
export declare const UNDO_LOG_TAG = "__voltro.undo.log";
|
|
@@ -1733,6 +1983,9 @@ declare type UpdatePayload<Messages extends WorkflowClientMessages, Name extends
|
|
|
1733
1983
|
readonly payload: infer Payload;
|
|
1734
1984
|
} ? Payload : unknown : unknown;
|
|
1735
1985
|
|
|
1986
|
+
/** Applied to the current state to produce the next one. */
|
|
1987
|
+
export declare type Updater<S> = (state: S) => S;
|
|
1988
|
+
|
|
1736
1989
|
declare type UpdateResult<Messages extends WorkflowClientMessages, Name extends string> = NonNullable<Messages['updates']> extends Readonly<Record<Name, infer Update>> ? Update extends {
|
|
1737
1990
|
readonly result: infer Result;
|
|
1738
1991
|
} ? Omit<WorkflowUpdateResult, 'result'> & {
|
|
@@ -2112,7 +2365,7 @@ export declare const useTableSkeleton: (apiName: string, queryTag: string) => Re
|
|
|
2112
2365
|
* the returned props. The sink is the analytics transport (injected, so the
|
|
2113
2366
|
* kernel stays transport-agnostic — and testable).
|
|
2114
2367
|
*/
|
|
2115
|
-
export declare const useTracking: (spec: TrackingSpec
|
|
2368
|
+
export declare const useTracking: <P extends object>(spec: TrackingSpec<P>, props: P, sink: TrackingSink) => P;
|
|
2116
2369
|
|
|
2117
2370
|
export declare const useUndo: (options: UseUndoOptions) => UndoControls;
|
|
2118
2371
|
|
|
@@ -2376,6 +2629,6 @@ export declare interface WorkflowWaitingFor {
|
|
|
2376
2629
|
* Lifecycle keys (onMount/onUnmount) are skipped — those fire from effects.
|
|
2377
2630
|
* Pure: returns a new props object, mutates nothing.
|
|
2378
2631
|
*/
|
|
2379
|
-
export declare const wrapTrackedCallbacks: (spec: TrackingSpec
|
|
2632
|
+
export declare const wrapTrackedCallbacks: <P extends object>(spec: TrackingSpec<P>, props: P, sink: TrackingSink) => P;
|
|
2380
2633
|
|
|
2381
2634
|
export { }
|