@voltro/client 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.
- package/CHANGELOG.md +52 -0
- package/LICENSE +57 -0
- package/README.md +26 -0
- package/SECURITY.md +56 -0
- package/THIRD-PARTY-NOTICES.md +347 -0
- package/dist/index.d.ts +1882 -0
- package/dist/index.js +2037 -0
- package/package.json +44 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1882 @@
|
|
|
1
|
+
import { ClientDescriptor } from '@voltro/protocol';
|
|
2
|
+
import { ClipboardEvent as ClipboardEvent_2 } from 'react';
|
|
3
|
+
import { Context } from 'react';
|
|
4
|
+
import { DragEvent as DragEvent_2 } from 'react';
|
|
5
|
+
import { Effect } from 'effect';
|
|
6
|
+
import { Fiber } from 'effect';
|
|
7
|
+
import { ManagedRuntime } from 'effect';
|
|
8
|
+
import { ReactNode } from 'react';
|
|
9
|
+
import { Schema } from 'effect';
|
|
10
|
+
import { Stream } from 'effect';
|
|
11
|
+
import { SubscriptionEvent } from '@voltro/protocol';
|
|
12
|
+
import { UIEvent as UIEvent_2 } from 'react';
|
|
13
|
+
import { WorkflowDomainEventRow } from '@voltro/protocol';
|
|
14
|
+
import { WorkflowEventDeliveryRow } from '@voltro/protocol';
|
|
15
|
+
import { WorkflowRunEventRow } from '@voltro/protocol';
|
|
16
|
+
import { WorkflowRunHandle } from '@voltro/protocol';
|
|
17
|
+
import { WorkflowRunRow } from '@voltro/protocol';
|
|
18
|
+
import { WorkflowRunStatus } from '@voltro/protocol';
|
|
19
|
+
import { WorkflowRunStepRow } from '@voltro/protocol';
|
|
20
|
+
import { WorkflowUpdateResult } from '@voltro/protocol';
|
|
21
|
+
|
|
22
|
+
export declare interface ActionState<Input, Output> {
|
|
23
|
+
/** Invoke the action. Resolves the typed output or rejects (and sets
|
|
24
|
+
* `.error` + emits on the api error bus). */
|
|
25
|
+
readonly run: (input: Input) => Promise<Output>;
|
|
26
|
+
/** True while a call is in flight. */
|
|
27
|
+
readonly pending: boolean;
|
|
28
|
+
/** The last rejection, or `undefined` if the most recent call succeeded
|
|
29
|
+
* (or none has run yet). */
|
|
30
|
+
readonly error: unknown | undefined;
|
|
31
|
+
/** The most recent successful result, or `undefined`. */
|
|
32
|
+
readonly lastResult: Output | undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Mirrors `@voltro/protocol/scopes` ADMIN_SCOPE — an admin satisfies any
|
|
36
|
+
* required scope. Inlined so the client stays decoupled from server code. */
|
|
37
|
+
export declare const ADMIN_SCOPE = "admin:full";
|
|
38
|
+
|
|
39
|
+
export declare interface AgentChatMessage {
|
|
40
|
+
readonly id: string;
|
|
41
|
+
readonly role: string;
|
|
42
|
+
readonly content: string;
|
|
43
|
+
readonly streaming: boolean;
|
|
44
|
+
readonly order: number;
|
|
45
|
+
readonly stepOrder?: number;
|
|
46
|
+
readonly parts?: ReadonlyArray<AgentChatPart>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** One rendered segment of an assistant (or user) turn, persisted in the
|
|
50
|
+
* agent_messages row's `parts` JSON. Structural — the client stays
|
|
51
|
+
* AI-package-agnostic (mirrors @voltro/ai's part union). */
|
|
52
|
+
export declare type AgentChatPart = {
|
|
53
|
+
readonly type: 'text';
|
|
54
|
+
readonly text: string;
|
|
55
|
+
} | {
|
|
56
|
+
readonly type: 'reasoning';
|
|
57
|
+
readonly text: string;
|
|
58
|
+
} | {
|
|
59
|
+
readonly type: 'tool';
|
|
60
|
+
readonly toolName: string;
|
|
61
|
+
readonly state?: string;
|
|
62
|
+
readonly input?: unknown;
|
|
63
|
+
readonly output?: unknown;
|
|
64
|
+
} | {
|
|
65
|
+
readonly type: 'source';
|
|
66
|
+
readonly sourceType?: string;
|
|
67
|
+
readonly id?: string;
|
|
68
|
+
readonly url?: string;
|
|
69
|
+
readonly title?: string;
|
|
70
|
+
} | {
|
|
71
|
+
readonly type: 'file';
|
|
72
|
+
readonly mediaType: string;
|
|
73
|
+
readonly data: string;
|
|
74
|
+
} | {
|
|
75
|
+
readonly type: string;
|
|
76
|
+
readonly [k: string]: unknown;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export declare interface AgentChatState {
|
|
80
|
+
readonly messages: ReadonlyArray<AgentChatMessage>;
|
|
81
|
+
/** True while any row is `streaming:true` (the live typewriter turn). */
|
|
82
|
+
readonly streaming: boolean;
|
|
83
|
+
readonly loading: boolean;
|
|
84
|
+
readonly error: unknown | undefined;
|
|
85
|
+
/** Send a user turn; the assistant turn streams back into `messages`. */
|
|
86
|
+
readonly send: (prompt: string, extra?: Readonly<Record<string, unknown>>) => Promise<unknown>;
|
|
87
|
+
/** Re-run the last user prompt as a fresh turn. No-op if none. */
|
|
88
|
+
readonly regenerate: () => Promise<unknown> | undefined;
|
|
89
|
+
readonly sending: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export declare interface AgentControls {
|
|
93
|
+
/** The assistant text streamed so far for the in-flight run. */
|
|
94
|
+
readonly tokens: string;
|
|
95
|
+
/** Accumulated completed turns across runs. */
|
|
96
|
+
readonly history: ReadonlyArray<AgentTurn>;
|
|
97
|
+
readonly status: AgentStreamStatus;
|
|
98
|
+
readonly error: unknown | undefined;
|
|
99
|
+
/** Begin a run. When `input.message` is a string it's appended to history
|
|
100
|
+
* on completion (paired with the assistant reply). */
|
|
101
|
+
readonly send: (input?: Readonly<Record<string, unknown>>) => void;
|
|
102
|
+
readonly cancel: () => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export declare interface AgentStreamControls<E> extends AgentStreamState<E> {
|
|
106
|
+
/** Begin a run with `input`. Resets prior events; replaces any in-flight run. */
|
|
107
|
+
readonly start: (input?: Readonly<Record<string, unknown>>) => void;
|
|
108
|
+
/** Interrupt the in-flight run (its server-side scope tears down). */
|
|
109
|
+
readonly cancel: () => void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export declare interface AgentStreamState<E> {
|
|
113
|
+
/** Elements received so far, in order. */
|
|
114
|
+
readonly events: ReadonlyArray<E>;
|
|
115
|
+
readonly status: AgentStreamStatus;
|
|
116
|
+
/** Set when status === 'error'. */
|
|
117
|
+
readonly error: unknown | undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export declare type AgentStreamStatus = 'idle' | 'streaming' | 'done' | 'error';
|
|
121
|
+
|
|
122
|
+
export declare interface AgentTurn {
|
|
123
|
+
readonly role: 'user' | 'assistant';
|
|
124
|
+
readonly content: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export declare interface Analytics<E extends ReadonlyArray<EventDescriptor<string, unknown>>> {
|
|
128
|
+
/** Emit an event — name + payload typed by the catalog; validated at runtime. */
|
|
129
|
+
readonly track: <K extends keyof EventMap<E> & string>(name: K, payload: EventMap<E>[K]) => void;
|
|
130
|
+
readonly names: ReadonlyArray<string>;
|
|
131
|
+
readonly catalog: EventCatalog;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export declare type AnyRuntime = ManagedRuntime.ManagedRuntime<never, never>;
|
|
135
|
+
|
|
136
|
+
export declare interface ApiHandle {
|
|
137
|
+
readonly runtime: AnyRuntime;
|
|
138
|
+
readonly cache: SubscriptionCache;
|
|
139
|
+
/** Resolved typed rpc client. Methods nest by tag (`todos.list` →
|
|
140
|
+
* `client.todos.list`). Hooks walk by tag-segment (see `resolveByTag`)
|
|
141
|
+
* to invoke, so the static type here is the erased `unknown`; the typed
|
|
142
|
+
* view comes from `useAppClient<T>(name)` at the call site. */
|
|
143
|
+
readonly client: unknown;
|
|
144
|
+
/** Per-rpc-tag descriptor metadata. Drives auto-optimistic and source-
|
|
145
|
+
* based cache routing. */
|
|
146
|
+
readonly descriptors: Readonly<Record<string, ClientDescriptor>>;
|
|
147
|
+
/**
|
|
148
|
+
* Base HTTP origin where the api's `/_voltro/inspect/*` endpoints
|
|
149
|
+
* live. Derived from `wsUrl` at mount time (`ws://host:port/ws` →
|
|
150
|
+
* `http://host:port`). DevTools and any inspect-consuming tooling
|
|
151
|
+
* use this for the metrics / subscriptions / events endpoints.
|
|
152
|
+
*/
|
|
153
|
+
readonly inspectBaseUrl: string;
|
|
154
|
+
/** Per-api error bus. Mutations + subscription failures land here so
|
|
155
|
+
* app-level listeners can react to typed errors globally (auto-logout
|
|
156
|
+
* on `Unauthenticated`, network-error toasts, etc.). */
|
|
157
|
+
readonly errorBus: RpcErrorBus;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export declare interface AsyncValidationResult {
|
|
161
|
+
readonly status: ValidationStatus;
|
|
162
|
+
readonly valid: boolean | undefined;
|
|
163
|
+
readonly message: string | undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Auto-apply target as seen from the client. Identical shape to the
|
|
168
|
+
* server's TargetSpec but with all schema generics erased (the client
|
|
169
|
+
* sees concrete row shapes at runtime, not Schema instances).
|
|
170
|
+
*
|
|
171
|
+
* Optional overrides:
|
|
172
|
+
* - `shape` for insert: build the row from input + optimistic id
|
|
173
|
+
* for update: build the patched row from (input, current)
|
|
174
|
+
* - `identify` for update/delete: extract the row id from input
|
|
175
|
+
* (defaults to `input.id`)
|
|
176
|
+
* - `order` for insert: 'prepend' (default) or 'append'
|
|
177
|
+
*/
|
|
178
|
+
export declare interface AutoApplyTarget {
|
|
179
|
+
readonly table: string;
|
|
180
|
+
readonly op: 'insert' | 'update' | 'delete';
|
|
181
|
+
readonly order?: 'prepend' | 'append' | undefined;
|
|
182
|
+
readonly shape?: ((input: Record<string, unknown>, optimisticIdOrCurrent?: unknown) => Record<string, unknown>) | undefined;
|
|
183
|
+
readonly identify?: ((input: Record<string, unknown>) => string) | undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
declare interface CacheEntry {
|
|
187
|
+
readonly key: string;
|
|
188
|
+
/** First element of the keyArr — the rpc tag (e.g. 'todos.list'). Used
|
|
189
|
+
* by `forTag()` so callers can patch every sub-key for a tag without
|
|
190
|
+
* knowing the inputs. Captured at create-time so updates without a
|
|
191
|
+
* prior subscribe still work (stub entries get tag too). */
|
|
192
|
+
readonly tag: string | undefined;
|
|
193
|
+
state: EntryState<unknown>;
|
|
194
|
+
/** Subscriber re-render callbacks. */
|
|
195
|
+
subscribers: Set<() => void>;
|
|
196
|
+
/** Fiber running the underlying stream. */
|
|
197
|
+
fiber: Fiber.RuntimeFiber<unknown, unknown> | null;
|
|
198
|
+
/** Pending eviction (last subscriber gone, TTL countdown). */
|
|
199
|
+
evictionTimer: NodeJS.Timeout | null;
|
|
200
|
+
/** Source table(s) this entry reads (from the rpc descriptor). Used by
|
|
201
|
+
* auto-optimistic to find which entries to patch when a mutation with
|
|
202
|
+
* a matching `target.table` is invoked — an array matches if the target is
|
|
203
|
+
* among the listed tables. May be undefined for queries whose source isn't
|
|
204
|
+
* expressed as table(s) (joins, aggregates). */
|
|
205
|
+
source: string | ReadonlyArray<string> | undefined;
|
|
206
|
+
/** True once a server snapshot reported this query as COMPUTED (handler
|
|
207
|
+
* returns a shaped value, not a table row-set). Auto-optimistic skips
|
|
208
|
+
* blind INSERTs into computed entries — the client can't evaluate the
|
|
209
|
+
* query's opaque server-side filter to know if a new row belongs, so it
|
|
210
|
+
* defers to the authoritative recompute push. UPDATE/DELETE (matched by
|
|
211
|
+
* id) still apply. Defaults false until the first snapshot resolves it. */
|
|
212
|
+
computed: boolean;
|
|
213
|
+
/** Saved `fetch` thunk from the first subscribe(). Used by `refreshAll()`
|
|
214
|
+
* to re-issue the WS subscription after a connection-subject re-bind
|
|
215
|
+
* (e.g. soft re-auth after login). Each subscriber's hook keeps its
|
|
216
|
+
* own fetch closure, but only the first one's identity matters — the
|
|
217
|
+
* server-side subscription is one per cache-entry key, not per
|
|
218
|
+
* subscriber. */
|
|
219
|
+
fetch: (() => Stream.Stream<SubscriptionEvent<unknown>, unknown, never>) | null;
|
|
220
|
+
/** W3C trace id of the live stream, captured when the fiber starts.
|
|
221
|
+
* Shared with the server (the subscription span propagates it) and
|
|
222
|
+
* attached to error-bus events so a failure points at the right
|
|
223
|
+
* `voltro logs --trace <id>`. */
|
|
224
|
+
traceId?: string;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Plain-data snapshot of a single cache entry for devtools / test
|
|
228
|
+
* introspection. Doesn't carry the live fiber or React-subscriber
|
|
229
|
+
* set — those are kept private. */
|
|
230
|
+
export declare interface CacheEntrySnapshot {
|
|
231
|
+
readonly key: string;
|
|
232
|
+
readonly tag: string | undefined;
|
|
233
|
+
readonly source: string | ReadonlyArray<string> | undefined;
|
|
234
|
+
readonly subscriberCount: number;
|
|
235
|
+
/** True while the underlying stream's fiber is running. */
|
|
236
|
+
readonly hasFiber: boolean;
|
|
237
|
+
/** True after the last subscriber left and the eviction TTL is
|
|
238
|
+
* counting down — a quick remount within the window resurrects. */
|
|
239
|
+
readonly evicting: boolean;
|
|
240
|
+
readonly snapshot: CacheSnapshot<unknown>;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export declare interface CacheSnapshot<T> {
|
|
244
|
+
/** Current visible data = base + all live patches applied in order. */
|
|
245
|
+
readonly data: T | undefined;
|
|
246
|
+
/** Most recent revision the server delivered. -1 if no snapshot yet. */
|
|
247
|
+
readonly revision: number;
|
|
248
|
+
/** Wall-clock ms when the most recent server delta was emitted; undefined for snapshots. */
|
|
249
|
+
readonly emittedAt: number | undefined;
|
|
250
|
+
/** Error from the underlying stream (if no snapshot has ever arrived). */
|
|
251
|
+
readonly error: unknown | undefined;
|
|
252
|
+
/** Number of live optimistic patches currently applied. */
|
|
253
|
+
readonly pendingPatches: number;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Does a subject with `subjectScopes` satisfy `required`? ADMIN bypasses;
|
|
257
|
+
* an empty requirement is always allowed. Pure — the matcher core. */
|
|
258
|
+
export declare const canCall: (subjectScopes: ReadonlyArray<string>, required: string | ReadonlyArray<string>) => boolean;
|
|
259
|
+
|
|
260
|
+
/** Structural mirror of @voltro/cli's `CapabilityManifestTable` column — the
|
|
261
|
+
* client stays decoupled from the (node-only) cli package. */
|
|
262
|
+
export declare interface CapabilityColumn {
|
|
263
|
+
readonly name: string;
|
|
264
|
+
readonly type: string;
|
|
265
|
+
readonly nullable: boolean;
|
|
266
|
+
/** Set when this column is a foreign key — the table it points at. */
|
|
267
|
+
readonly refersTo?: string;
|
|
268
|
+
/** Closed value set (`text().oneOf([...])`) → render a select. */
|
|
269
|
+
readonly enum?: ReadonlyArray<string>;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** Structural mirror of @voltro/cli's `CapabilityManifest` (served at
|
|
273
|
+
* `GET /_voltro/inspect/manifest`). */
|
|
274
|
+
export declare interface CapabilityManifest {
|
|
275
|
+
readonly version: number;
|
|
276
|
+
readonly procedures: ReadonlyArray<CapabilityProcedure>;
|
|
277
|
+
readonly workflows: ReadonlyArray<{
|
|
278
|
+
readonly name: string;
|
|
279
|
+
}>;
|
|
280
|
+
readonly widgets: ReadonlyArray<string>;
|
|
281
|
+
readonly tables: ReadonlyArray<CapabilityTable>;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export declare interface CapabilityManifestState {
|
|
285
|
+
readonly manifest: CapabilityManifest | undefined;
|
|
286
|
+
readonly loading: boolean;
|
|
287
|
+
readonly error: unknown | undefined;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** A procedure in the manifest. `source` is the table a query reads;
|
|
291
|
+
* `targets` are the tables+ops a mutation writes. */
|
|
292
|
+
export declare interface CapabilityProcedure {
|
|
293
|
+
readonly tag: string;
|
|
294
|
+
readonly kind: string;
|
|
295
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
296
|
+
readonly output?: Readonly<Record<string, unknown>>;
|
|
297
|
+
readonly source?: string | ReadonlyArray<string>;
|
|
298
|
+
readonly targets?: ReadonlyArray<{
|
|
299
|
+
readonly table: string;
|
|
300
|
+
readonly op: string;
|
|
301
|
+
}>;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** A user table in the manifest (framework `_voltro_*` tables are excluded). */
|
|
305
|
+
export declare interface CapabilityTable {
|
|
306
|
+
readonly name: string;
|
|
307
|
+
readonly columns: ReadonlyArray<CapabilityColumn>;
|
|
308
|
+
readonly reactive: boolean;
|
|
309
|
+
readonly framework: boolean;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** Clear the buffer (devtools "Clear" button). */
|
|
313
|
+
export declare const clearMutations: () => void;
|
|
314
|
+
|
|
315
|
+
/** Drop successfully-sent entries (call after a drain to compact the queue). */
|
|
316
|
+
export declare const clearSent: (queue: Outbox) => Outbox;
|
|
317
|
+
|
|
318
|
+
export declare const CLIENT_NAME: "framework-client";
|
|
319
|
+
|
|
320
|
+
export declare interface ClientErrorEvent {
|
|
321
|
+
/** The thrown value (Error | anything). */
|
|
322
|
+
readonly error: unknown;
|
|
323
|
+
/** Where it came from. `route` = caught by the framework's route
|
|
324
|
+
* ErrorBoundary (render OR loader); `manual` = app called a capture helper. */
|
|
325
|
+
readonly source: 'route' | 'manual';
|
|
326
|
+
/** React component stack, when the route boundary caught a render error. */
|
|
327
|
+
readonly componentStack?: string;
|
|
328
|
+
/** Active pathname at the time, for context. */
|
|
329
|
+
readonly pathname?: string;
|
|
330
|
+
/** Optional caller-supplied extra context (manual captures). */
|
|
331
|
+
readonly context?: Record<string, unknown>;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
declare type ClientErrorListener = (event: ClientErrorEvent) => void;
|
|
335
|
+
|
|
336
|
+
export declare interface ClientTraceEvent {
|
|
337
|
+
/** W3C trace id (32 hex) of the call the client just started. */
|
|
338
|
+
readonly traceId: string;
|
|
339
|
+
/** W3C span id (16 hex) of the client span — the parent the server
|
|
340
|
+
* continues from. Lets a vendor integration (Sentry) place the
|
|
341
|
+
* browser-side span in the SAME trace tree as the server transaction. */
|
|
342
|
+
readonly spanId: string;
|
|
343
|
+
/** `'mutation'` | `'action'` | `'subscription'` — which surface started it. */
|
|
344
|
+
readonly source: 'mutation' | 'action' | 'subscription';
|
|
345
|
+
/** RPC tag (e.g. `'todos.create'`). */
|
|
346
|
+
readonly tag: string;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
declare type ClientTraceListener = (event: ClientTraceEvent) => void;
|
|
350
|
+
|
|
351
|
+
/** Pure virtualization math: scroll position → the row window to fetch +
|
|
352
|
+
* the spacer heights. `total` (when known) caps the window + sizes the bottom
|
|
353
|
+
* spacer; without it, infinite-scroll (bottomSpacer 0). */
|
|
354
|
+
export declare const computeWindow: (args: {
|
|
355
|
+
readonly scrollTop: number;
|
|
356
|
+
readonly viewportHeight: number;
|
|
357
|
+
readonly rowHeight: number;
|
|
358
|
+
readonly overscan?: number;
|
|
359
|
+
readonly total?: number;
|
|
360
|
+
}) => WindowSpec;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* The wire shape a data-copilot action returns. Mirror it in the action's
|
|
364
|
+
* `output` schema — a refusal carries the human-readable `reason` (derived
|
|
365
|
+
* from the typed `CopilotRejected`), a success carries the result `rows`.
|
|
366
|
+
* Modelled as a successful response either way: a refused question is a
|
|
367
|
+
* normal answer with `ok: false`, NOT a thrown error (that's reserved for
|
|
368
|
+
* transport / execution failures).
|
|
369
|
+
*/
|
|
370
|
+
export declare type CopilotAnswer<Row = Record<string, unknown>> = {
|
|
371
|
+
readonly ok: true;
|
|
372
|
+
readonly rows: ReadonlyArray<Row>;
|
|
373
|
+
} | {
|
|
374
|
+
readonly ok: false;
|
|
375
|
+
readonly reason: string;
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Build a typed analytics surface from a declared event list + a sink. `track`
|
|
380
|
+
* is typed against the catalog; on a payload that fails its Schema it logs a
|
|
381
|
+
* loud dev error (the "bad event shape is loud" rule) and still forwards (best-
|
|
382
|
+
* effort — losing the event would be worse than a slightly-off payload).
|
|
383
|
+
*/
|
|
384
|
+
export declare const createAnalytics: <const E extends ReadonlyArray<EventDescriptor<string, unknown>>>(events: E, sink: TrackingSink) => Analytics<E>;
|
|
385
|
+
|
|
386
|
+
export declare interface DataCopilotState<Row = Record<string, unknown>> {
|
|
387
|
+
/** Ask a natural-language question. Resolves the typed answer (also stored
|
|
388
|
+
* on `.answer`); rejects only on a transport / execution error. */
|
|
389
|
+
readonly ask: (question: string) => Promise<CopilotAnswer<Row>>;
|
|
390
|
+
/** The most recent answer (rows or refusal), or `undefined` before the
|
|
391
|
+
* first `ask` (or after `reset`). */
|
|
392
|
+
readonly answer: CopilotAnswer<Row> | undefined;
|
|
393
|
+
/** True while a question is in flight. */
|
|
394
|
+
readonly pending: boolean;
|
|
395
|
+
/** The last transport / execution error, or `undefined`. A REFUSAL is not
|
|
396
|
+
* an error — it arrives as `answer.ok === false`. */
|
|
397
|
+
readonly error: unknown | undefined;
|
|
398
|
+
/** Clear the stored answer. */
|
|
399
|
+
readonly reset: () => void;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export declare interface DataTableState<Row> {
|
|
403
|
+
/** Columns derived from the query's output Schema (or the explicit override). */
|
|
404
|
+
readonly columns: ReadonlyArray<FieldDescriptor>;
|
|
405
|
+
/** Live rows (sorted if a sort is active). */
|
|
406
|
+
readonly rows: ReadonlyArray<Row>;
|
|
407
|
+
readonly loading: boolean;
|
|
408
|
+
readonly error: unknown | undefined;
|
|
409
|
+
readonly sort: SortState | undefined;
|
|
410
|
+
/** Toggle/clear sort on a column (asc → desc → asc …). */
|
|
411
|
+
readonly toggleSort: (column: string) => void;
|
|
412
|
+
/** Grow the window by one page (only meaningful with `pageSize`). */
|
|
413
|
+
readonly loadMore: () => void;
|
|
414
|
+
/** True when the last window came back full — there may be more rows.
|
|
415
|
+
* Always false without `pageSize`. */
|
|
416
|
+
readonly hasMore: boolean;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** Declare a typed analytics event. */
|
|
420
|
+
export declare const defineEvent: <const Name extends string, A, I>(name: Name, payload: Schema.Schema<A, I>) => EventDescriptor<Name, A>;
|
|
421
|
+
|
|
422
|
+
/** Identity helper (like `defineTracking('CheckoutButton', { onMount: 'checkout.viewed' })`). */
|
|
423
|
+
export declare const defineTracking: (name: string, map: TrackingMap) => TrackingSpec;
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Pure projection: turn a capability manifest into one `EntityAdminSpec` per
|
|
427
|
+
* user table, each joined to the query that lists it and the mutations that
|
|
428
|
+
* create/update/delete it. The auto-admin template maps over the result to
|
|
429
|
+
* render a live, permission-gated back-office; everything here is derived from
|
|
430
|
+
* what the app actually exposes, so an entity with no list query simply renders
|
|
431
|
+
* no table rather than binding to a tag that 404s.
|
|
432
|
+
*/
|
|
433
|
+
export declare const deriveEntityAdmins: (manifest: CapabilityManifest) => ReadonlyArray<EntityAdminSpec>;
|
|
434
|
+
|
|
435
|
+
export declare const enqueueEntry: (queue: Outbox, id: string, tag: string, input: unknown) => Outbox;
|
|
436
|
+
|
|
437
|
+
/** One entity's admin surface: the table + the procedures that read/write it,
|
|
438
|
+
* plus the conventional scope strings the UI gates writes on. A tag is
|
|
439
|
+
* `undefined` when the app exposes no procedure for that op (the admin then
|
|
440
|
+
* renders that affordance read-only / hidden). */
|
|
441
|
+
export declare interface EntityAdminSpec {
|
|
442
|
+
readonly table: string;
|
|
443
|
+
readonly columns: ReadonlyArray<CapabilityColumn>;
|
|
444
|
+
readonly reactive: boolean;
|
|
445
|
+
/** Query whose `source` is this table → drives <DataTable>. */
|
|
446
|
+
readonly listTag?: string;
|
|
447
|
+
/** Mutation targeting `{table, op:'insert'}` → drives the create <AutoForm>. */
|
|
448
|
+
readonly createTag?: string;
|
|
449
|
+
/** Mutation targeting `{table, op:'update'}` → row edit. */
|
|
450
|
+
readonly updateTag?: string;
|
|
451
|
+
/** Mutation targeting `{table, op:'delete'}` → row delete. */
|
|
452
|
+
readonly deleteTag?: string;
|
|
453
|
+
/** Conventional scope strings the admin gates on via `useCan`. The app maps
|
|
454
|
+
* these to its real RBAC scopes; absent a scope registry in the manifest
|
|
455
|
+
* this convention is the seam (gate at the action level — round-2/07 adds
|
|
456
|
+
* row-level authority). */
|
|
457
|
+
readonly createScope: string;
|
|
458
|
+
readonly writeScope: string;
|
|
459
|
+
readonly deleteScope: string;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
declare interface EntryState<T> {
|
|
463
|
+
/** Last server-delivered data (base for patches). */
|
|
464
|
+
base: T | undefined;
|
|
465
|
+
baseRevision: number;
|
|
466
|
+
baseEmittedAt: number | undefined;
|
|
467
|
+
baseError: unknown | undefined;
|
|
468
|
+
patches: Array<OptimisticPatch<T>>;
|
|
469
|
+
/** Cached optimistic snapshot — invalidated on every state change so
|
|
470
|
+
* `getSnapshot` returns a stable reference between mutations. */
|
|
471
|
+
cachedSnapshot: CacheSnapshot<T> | null;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/** Helper: pattern-match the `_tag` field on a thrown error value. Works
|
|
475
|
+
* on Schema.TaggedError instances + plain `{_tag: ..., …}` objects the
|
|
476
|
+
* rpc wire emits. Returns undefined for non-tagged errors. */
|
|
477
|
+
export declare const errorTag: (err: unknown) => string | undefined;
|
|
478
|
+
|
|
479
|
+
export declare interface EventCatalog {
|
|
480
|
+
readonly names: ReadonlyArray<string>;
|
|
481
|
+
readonly get: (name: string) => EventDescriptor<string, unknown> | undefined;
|
|
482
|
+
/** Discovery inventory: every event's name + its JSON-Schema-able payload. */
|
|
483
|
+
readonly events: ReadonlyArray<EventDescriptor<string, unknown>>;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export declare const eventCatalog: (events: ReadonlyArray<EventDescriptor<string, unknown>>) => EventCatalog;
|
|
487
|
+
|
|
488
|
+
export declare interface EventDescriptor<Name extends string, A> {
|
|
489
|
+
readonly name: Name;
|
|
490
|
+
/** The payload Schema, erased — `Schema` is INVARIANT in its decoded type, so
|
|
491
|
+
* storing `Schema.Schema<A>` here would make `EventDescriptor` invariant in
|
|
492
|
+
* `A` and break a heterogeneous catalog. The decoded type is carried by the
|
|
493
|
+
* covariant phantom `_type` below instead, so `EventDescriptor<string,
|
|
494
|
+
* unknown>` accepts every typed descriptor AND `track` stays typed. */
|
|
495
|
+
readonly payload: Schema.Schema.Any;
|
|
496
|
+
/** Phantom — never present at runtime; carries the decoded payload type for
|
|
497
|
+
* `track`'s compile-time signature. Covariant (optional), so erasure works. */
|
|
498
|
+
readonly _type?: A;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** Map a tuple of event descriptors → `{ name: payloadType }` for typing track.
|
|
502
|
+
* The covariant `_type` phantom lets `EventDescriptor<string, unknown>` accept
|
|
503
|
+
* every typed descriptor as a constraint while inference still recovers `A`. */
|
|
504
|
+
declare type EventMap<E extends ReadonlyArray<EventDescriptor<string, unknown>>> = {
|
|
505
|
+
[D in E[number] as D['name']]: D extends EventDescriptor<string, infer A> ? A : never;
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
export declare interface EventValidation {
|
|
509
|
+
readonly valid: boolean;
|
|
510
|
+
/** `path` → message, empty when valid. */
|
|
511
|
+
readonly errors: Readonly<Record<string, string>>;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export declare interface FieldDescriptor {
|
|
515
|
+
/** Property name on the input object. */
|
|
516
|
+
readonly name: string;
|
|
517
|
+
/** Human label — the Schema `title` annotation, else the humanised name. */
|
|
518
|
+
readonly label: string;
|
|
519
|
+
/** The default widget kind. `'custom'` ⇒ supply a render-prop. */
|
|
520
|
+
readonly widget: WidgetKind;
|
|
521
|
+
/** True when the property must be present (in JSON-Schema `required`). */
|
|
522
|
+
readonly required: boolean;
|
|
523
|
+
/** True when the value may be `null` (e.g. `Schema.NullOr`). */
|
|
524
|
+
readonly nullable: boolean;
|
|
525
|
+
/** Present for closed value sets (a `Schema.Literal` union → `select`). */
|
|
526
|
+
readonly options?: ReadonlyArray<FieldOption>;
|
|
527
|
+
/** The resolved JSON-Schema node — carries `maxLength` / `pattern` /
|
|
528
|
+
* `minimum` / `format` / `description` for widgets + validation hints. */
|
|
529
|
+
readonly jsonSchema: Readonly<Record<string, unknown>>;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export declare interface FieldErrors {
|
|
533
|
+
readonly [field: string]: string;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export declare interface FieldOption {
|
|
537
|
+
readonly value: string;
|
|
538
|
+
readonly label: string;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export declare interface FilterDescriptor {
|
|
542
|
+
readonly name: string;
|
|
543
|
+
readonly label: string;
|
|
544
|
+
readonly kind: FilterKind;
|
|
545
|
+
/** Present for `select` / `multi-select` (from an enum field). */
|
|
546
|
+
readonly options?: ReadonlyArray<FieldOption>;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export declare type FilterKind = 'text' | 'select' | 'multi-select' | 'number-range' | 'date-range' | 'boolean';
|
|
550
|
+
|
|
551
|
+
/** Derive the filter controls from a query's input Schema. Each filterable
|
|
552
|
+
* input field → one FilterDescriptor. Pure. */
|
|
553
|
+
export declare const filtersFromSchema: (schema: Schema.Schema.Any) => ReadonlyArray<FilterDescriptor>;
|
|
554
|
+
|
|
555
|
+
export declare interface FormBinding<Input, Output> {
|
|
556
|
+
/** Ordered, render-agnostic field list derived from the input schema. */
|
|
557
|
+
readonly fields: ReadonlyArray<FieldDescriptor>;
|
|
558
|
+
readonly values: Partial<Input>;
|
|
559
|
+
/** First error per field — populated on submit. */
|
|
560
|
+
readonly errors: FieldErrors;
|
|
561
|
+
/** True when the CURRENT values decode against the schema. */
|
|
562
|
+
readonly isValid: boolean;
|
|
563
|
+
readonly pending: boolean;
|
|
564
|
+
/** The mutation's typed failure, if the last submit threw. */
|
|
565
|
+
readonly submitError: unknown | undefined;
|
|
566
|
+
readonly data: Output | undefined;
|
|
567
|
+
readonly setValue: (name: string, value: unknown) => void;
|
|
568
|
+
readonly setValues: (patch: Partial<Input>) => void;
|
|
569
|
+
readonly reset: () => void;
|
|
570
|
+
/** Validate; if valid, run the mutation. Returns the output, or `undefined`
|
|
571
|
+
* when validation blocked the submit. */
|
|
572
|
+
readonly submit: () => Promise<Output | undefined>;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export declare interface FrameworkRuntimes {
|
|
576
|
+
/** Look up an api handle (runtime + cache) by name. Throws if no such api was mounted. */
|
|
577
|
+
readonly get: (name: string) => ApiHandle;
|
|
578
|
+
/** Enumerate the names of currently-installed apis (for debug). */
|
|
579
|
+
readonly names: ReadonlyArray<string>;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
export declare const FrameworkRuntimesContext: Context<FrameworkRuntimes | null>;
|
|
583
|
+
|
|
584
|
+
export declare const FrameworkRuntimesProvider: ({ apis, children, }: FrameworkRuntimesProviderProps) => ReactNode;
|
|
585
|
+
|
|
586
|
+
export declare interface FrameworkRuntimesProviderProps {
|
|
587
|
+
readonly apis: ReadonlyMap<string, ApiHandle>;
|
|
588
|
+
readonly children: ReactNode;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** Read the current feed. Newest-first; up to MAX_MUTATIONS entries. */
|
|
592
|
+
export declare const getMutations: () => ReadonlyArray<MutationEvent>;
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Non-fetching cache used as a LOADING baseline:
|
|
596
|
+
* - during SSR (no runtime / no provider), and
|
|
597
|
+
* - on the client's first render(s) before the api supervisor has
|
|
598
|
+
* resolved a configured api's runtime + client.
|
|
599
|
+
*
|
|
600
|
+
* It subclasses the real cache so it carries the FULL method surface
|
|
601
|
+
* (`peek` / `peekAll` / `update` / `forTag` / `refreshAll` / …) — a
|
|
602
|
+
* hand-rolled partial stub broke the moment a consumer (e.g. devtools)
|
|
603
|
+
* called a method it didn't implement. The ONLY override is `subscribe`:
|
|
604
|
+
* it must NOT open a real stream, because the supplied runtime is a stub
|
|
605
|
+
* that can't fork fibers. It hands back an empty snapshot so the component
|
|
606
|
+
* renders its loading state; when the real client resolves, FrameworkBoot
|
|
607
|
+
* swaps in the real cache and the component re-subscribes for live data.
|
|
608
|
+
* Every other inherited method operates on an always-empty entry map, so
|
|
609
|
+
* they're inherently safe no-ops.
|
|
610
|
+
*/
|
|
611
|
+
export declare class LoadingSubscriptionCache extends SubscriptionCache {
|
|
612
|
+
subscribe(keyArr: ReadonlyArray<unknown>, _fetch: () => Stream.Stream<SubscriptionEvent<unknown>, unknown, never>, _runtime: AnyRuntime, _onChange: () => void, _options?: {
|
|
613
|
+
readonly source?: string | ReadonlyArray<string>;
|
|
614
|
+
}): {
|
|
615
|
+
readonly getSnapshot: () => CacheSnapshot<unknown>;
|
|
616
|
+
readonly unsubscribe: () => void;
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** Exported for tests: the inspect URL this hook fetches. */
|
|
621
|
+
export declare const manifestUrl: (base: string) => string;
|
|
622
|
+
|
|
623
|
+
export declare const markConflict: (queue: Outbox, id: string, error: unknown) => Outbox;
|
|
624
|
+
|
|
625
|
+
export declare const markFailed: (queue: Outbox, id: string, error: unknown) => Outbox;
|
|
626
|
+
|
|
627
|
+
export declare const markSent: (queue: Outbox, id: string) => Outbox;
|
|
628
|
+
|
|
629
|
+
export declare interface MutationBuilder<Input, Output> extends MutationState<Input, Output> {
|
|
630
|
+
/** Override auto-optimistic with a custom reducer. */
|
|
631
|
+
readonly withOptimistic: (optimistic: OptimisticFn<Input>) => MutationBuilder<Input, Output>;
|
|
632
|
+
/** Disable auto-optimistic entirely (useful for mutations whose
|
|
633
|
+
* effect must NOT preview locally — payments, sends, etc.). */
|
|
634
|
+
readonly withoutOptimistic: () => MutationBuilder<Input, Output>;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
export declare interface MutationEvent {
|
|
638
|
+
/** Stable id of the mutation invocation. Matches the cache's
|
|
639
|
+
* optimistic-patch mutationId so panels can correlate. */
|
|
640
|
+
readonly id: string;
|
|
641
|
+
/** Api name the mutation was dispatched on. */
|
|
642
|
+
readonly apiName: string;
|
|
643
|
+
/** Rpc tag (e.g. `'todos.create'`). */
|
|
644
|
+
readonly tag: string;
|
|
645
|
+
/** Status — published as 'pending' on start, transitions to
|
|
646
|
+
* 'success' or 'error' on settle. */
|
|
647
|
+
readonly status: MutationStatus;
|
|
648
|
+
/** Resolved input (after the descriptor's schema parse). */
|
|
649
|
+
readonly input: unknown;
|
|
650
|
+
/** Resolved output on success. */
|
|
651
|
+
readonly output?: unknown;
|
|
652
|
+
/** Thrown / rejected error on failure. */
|
|
653
|
+
readonly error?: unknown;
|
|
654
|
+
/** Wall-clock ms when the mutation started. */
|
|
655
|
+
readonly startedAt: number;
|
|
656
|
+
/** Wall-clock ms when the mutation settled. Undefined while pending. */
|
|
657
|
+
readonly settledAt?: number;
|
|
658
|
+
/** durationMs = settledAt - startedAt. Convenience field. */
|
|
659
|
+
readonly durationMs?: number;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
export declare interface MutationState<Input, Output> {
|
|
663
|
+
readonly mutate: (input: Input) => Promise<Output>;
|
|
664
|
+
readonly pending: boolean;
|
|
665
|
+
readonly error: unknown | undefined;
|
|
666
|
+
readonly data: Output | undefined;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
export declare type MutationStatus = 'pending' | 'success' | 'error';
|
|
670
|
+
|
|
671
|
+
export declare interface OptimisticContext {
|
|
672
|
+
/** Stage an optimistic patch keyed by `queryKey` (same convention as
|
|
673
|
+
* useSubscription's: `[rpcTag, input]`). The patch is automatically
|
|
674
|
+
* reverted when the enclosing mutation resolves (success or failure).
|
|
675
|
+
* Use when you know the EXACT input the subscription was opened with. */
|
|
676
|
+
readonly update: <T>(queryKey: ReadonlyArray<unknown>, reducer: (current: T) => T) => void;
|
|
677
|
+
/** Patch every cached entry whose rpc tag matches `rpcTag`, regardless
|
|
678
|
+
* of input. Use for sourceless queries (joins, aggregates, custom
|
|
679
|
+
* projections) where the auto-optimistic source-router can't see what
|
|
680
|
+
* to patch — and you don't know what inputs are currently subscribed
|
|
681
|
+
* to. Returns the number of patched entries (0 means no current
|
|
682
|
+
* subscribers for that tag). */
|
|
683
|
+
readonly forTag: <T>(rpcTag: string, reducer: (current: T) => T) => {
|
|
684
|
+
readonly patchedCount: number;
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
export declare type OptimisticFn<Input> = (cache: OptimisticContext, input: Input) => void;
|
|
689
|
+
|
|
690
|
+
declare interface OptimisticPatch<T = unknown> {
|
|
691
|
+
readonly id: string;
|
|
692
|
+
readonly mutationId: string;
|
|
693
|
+
readonly reducer: (current: T) => T;
|
|
694
|
+
/** Set once the mutation SUCCEEDED. A confirmed patch stays applied (so the
|
|
695
|
+
* optimistic preview never blinks out) until a server snapshot/delta updates
|
|
696
|
+
* `base` to reflect the committed write — only THEN is it dropped. Without
|
|
697
|
+
* this, dropping the patch on mutation-resolve reveals a still-stale base
|
|
698
|
+
* before the (CDC-latent) delta arrives → the on→off→on toggle flash. */
|
|
699
|
+
confirmed?: boolean;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
export declare type Outbox = ReadonlyArray<OutboxEntry>;
|
|
703
|
+
|
|
704
|
+
export declare interface OutboxControls {
|
|
705
|
+
readonly queue: Outbox;
|
|
706
|
+
readonly enqueue: (tag: string, input: unknown) => void;
|
|
707
|
+
readonly replay: () => Promise<void>;
|
|
708
|
+
readonly online: boolean;
|
|
709
|
+
readonly pending: number;
|
|
710
|
+
readonly conflicts: ReadonlyArray<OutboxEntry>;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
export declare interface OutboxEntry {
|
|
714
|
+
readonly id: string;
|
|
715
|
+
readonly tag: string;
|
|
716
|
+
readonly input: unknown;
|
|
717
|
+
readonly status: OutboxStatus;
|
|
718
|
+
readonly attempts: number;
|
|
719
|
+
readonly error?: unknown;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
export declare type OutboxStatus = 'pending' | 'sent' | 'failed' | 'conflict';
|
|
723
|
+
|
|
724
|
+
/** Provide the current subject's scopes to `useCan`. Mount it once high in the
|
|
725
|
+
* tree, fed by your session subscription so it updates on role changes. */
|
|
726
|
+
export declare function PermissionProvider(props: PermissionProviderProps): ReactNode;
|
|
727
|
+
|
|
728
|
+
export declare interface PermissionProviderProps {
|
|
729
|
+
/** The current subject's scopes (from your session query — reactive). */
|
|
730
|
+
readonly scopes: ReadonlyArray<string>;
|
|
731
|
+
readonly children: ReactNode;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
declare interface PermissionState_2 {
|
|
735
|
+
readonly scopes: ReadonlyArray<string>;
|
|
736
|
+
}
|
|
737
|
+
export { PermissionState_2 as PermissionState }
|
|
738
|
+
|
|
739
|
+
/** Structural mirror of @voltro/runtime's PreviewDiff (client stays decoupled). */
|
|
740
|
+
export declare interface PreviewDiff {
|
|
741
|
+
readonly rows: ReadonlyArray<PreviewRowDiff>;
|
|
742
|
+
readonly summary: {
|
|
743
|
+
readonly inserts: number;
|
|
744
|
+
readonly updates: number;
|
|
745
|
+
readonly deletes: number;
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
export declare interface PreviewFieldChange {
|
|
750
|
+
readonly from: unknown;
|
|
751
|
+
readonly to: unknown;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
export declare interface PreviewRowDiff {
|
|
755
|
+
readonly table: string;
|
|
756
|
+
readonly op: 'insert' | 'update' | 'delete';
|
|
757
|
+
readonly id: string | undefined;
|
|
758
|
+
readonly fields: Readonly<Record<string, PreviewFieldChange>>;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
export declare interface PreviewState<Input> {
|
|
762
|
+
readonly preview: (input: Input) => Promise<PreviewDiff>;
|
|
763
|
+
readonly diff: PreviewDiff | undefined;
|
|
764
|
+
readonly pending: boolean;
|
|
765
|
+
readonly error: unknown | undefined;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
export declare interface ProvenanceResult {
|
|
769
|
+
readonly table: string;
|
|
770
|
+
readonly id: string;
|
|
771
|
+
readonly column?: string;
|
|
772
|
+
readonly value: unknown;
|
|
773
|
+
readonly lastWrite: ProvenanceWrite | null;
|
|
774
|
+
readonly attribution: 'audit' | 'none';
|
|
775
|
+
readonly derived?: boolean;
|
|
776
|
+
readonly history?: ReadonlyArray<ProvenanceWrite>;
|
|
777
|
+
readonly found: boolean;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
export declare interface ProvenanceState {
|
|
781
|
+
readonly data: ProvenanceResult | undefined;
|
|
782
|
+
readonly loading: boolean;
|
|
783
|
+
readonly error: unknown | undefined;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/** Exported for tests: the inspect URL this hook fetches. */
|
|
787
|
+
export declare const provenanceUrl: (base: string, table: string, id: string, column?: string) => string;
|
|
788
|
+
|
|
789
|
+
/** Structural mirror of @voltro/runtime's `ProvenanceResult` — the client
|
|
790
|
+
* stays decoupled from the server package. */
|
|
791
|
+
export declare interface ProvenanceWrite {
|
|
792
|
+
readonly actor: {
|
|
793
|
+
readonly id: string | null;
|
|
794
|
+
readonly kind?: string;
|
|
795
|
+
readonly via?: string;
|
|
796
|
+
} | null;
|
|
797
|
+
readonly at: string | null;
|
|
798
|
+
readonly traceId?: string | null;
|
|
799
|
+
readonly value?: unknown;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/** Publish a client error. Cheap + sync; a broken listener can't break the caller. */
|
|
803
|
+
export declare const publishClientError: (event: ClientErrorEvent) => void;
|
|
804
|
+
|
|
805
|
+
/** Publish a started client trace. Cheap + sync; safe on the hot path. */
|
|
806
|
+
export declare const publishClientTrace: (event: ClientTraceEvent) => void;
|
|
807
|
+
|
|
808
|
+
export declare interface QueryFieldState {
|
|
809
|
+
readonly options: ReadonlyArray<FieldOption>;
|
|
810
|
+
readonly loading: boolean;
|
|
811
|
+
readonly term: string;
|
|
812
|
+
readonly search: (term: string) => void;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
export declare interface QueryFiltersState<Row> {
|
|
816
|
+
readonly filters: ReadonlyArray<FilterDescriptor>;
|
|
817
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
818
|
+
readonly setFilter: (name: string, value: unknown) => void;
|
|
819
|
+
readonly clear: () => void;
|
|
820
|
+
/** Live result rows for the current filter values. */
|
|
821
|
+
readonly rows: ReadonlyArray<Row>;
|
|
822
|
+
/** Live result count (undefined until first snapshot). */
|
|
823
|
+
readonly count: number | undefined;
|
|
824
|
+
readonly loading: boolean;
|
|
825
|
+
readonly error: unknown | undefined;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
export declare interface RecordState<R> {
|
|
829
|
+
readonly record: R | undefined;
|
|
830
|
+
readonly loading: boolean;
|
|
831
|
+
readonly error: unknown | undefined;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* The entries to replay, in FIFO order, UP TO (not including) the first
|
|
836
|
+
* conflict — a conflicted write blocks everything after it (causality). Sent
|
|
837
|
+
* entries are skipped; pending + failed are replayable.
|
|
838
|
+
*/
|
|
839
|
+
export declare const replayable: (queue: Outbox) => Outbox;
|
|
840
|
+
|
|
841
|
+
/** Report an error to every subscribed reporter (e.g. Sentry). Safe no-op
|
|
842
|
+
* when nothing is subscribed. The ergonomic manual-capture entry point —
|
|
843
|
+
* call it from a try/catch in an event handler, an async effect, anywhere
|
|
844
|
+
* the route boundary won't catch the throw. */
|
|
845
|
+
export declare const reportClientError: (error: unknown, context?: Record<string, unknown>) => void;
|
|
846
|
+
|
|
847
|
+
/** Test-only: reset the one-time no-provider dev-warning state (the
|
|
848
|
+
* module-global flags + any pending grace-period timer). */
|
|
849
|
+
export declare const _resetFrameworkRuntimesWarning: () => void;
|
|
850
|
+
|
|
851
|
+
export declare const resolveByTag: (client: unknown, tag: string) => unknown;
|
|
852
|
+
|
|
853
|
+
/** Resolve one map entry against the props. Pure. */
|
|
854
|
+
export declare const resolveTrackingEvent: (entry: TrackingEntry | undefined, props: Record<string, unknown>) => TrackingEvent | null;
|
|
855
|
+
|
|
856
|
+
export declare interface ResourceCanInput {
|
|
857
|
+
/** The action being gated (e.g. `'read'`, `'write'`, `'delete'`). */
|
|
858
|
+
readonly action: string;
|
|
859
|
+
/** The resource's policy type (matches a `defineResourcePolicy` type). */
|
|
860
|
+
readonly resourceType: string;
|
|
861
|
+
/** The specific resource id. */
|
|
862
|
+
readonly resourceId: string;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/** The wire shape the server's single-resource can-query returns. */
|
|
866
|
+
export declare interface ResourceCanResult {
|
|
867
|
+
readonly allowed: boolean;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
export declare interface ResourceCansInput {
|
|
871
|
+
readonly action: string;
|
|
872
|
+
readonly resourceType: string;
|
|
873
|
+
/** The resource ids to check in ONE round-trip (e.g. a table page's rows). */
|
|
874
|
+
readonly resourceIds: ReadonlyArray<string>;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
/** The wire shape the server's batch can-query returns — the SUBSET of the
|
|
878
|
+
* input ids the subject may act on. */
|
|
879
|
+
export declare interface ResourceCansResult {
|
|
880
|
+
readonly allowedIds: ReadonlyArray<string>;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
export declare interface ResumableAgentStreamControls<E> extends ResumableAgentStreamState<E> {
|
|
884
|
+
/** Begin a run. `input` MUST carry the resume key (`streamId`) so reconnects
|
|
885
|
+
* target the same server-side log; `fromSeq` is injected by the hook. */
|
|
886
|
+
readonly start: (input?: Readonly<Record<string, unknown>>) => void;
|
|
887
|
+
/** Stop the run + cancel any pending reconnect (its server scope tears down). */
|
|
888
|
+
readonly cancel: () => void;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
export declare interface ResumableAgentStreamOptions<E> {
|
|
892
|
+
readonly maxReconnects?: number;
|
|
893
|
+
readonly backoffMs?: number;
|
|
894
|
+
readonly maxBackoffMs?: number;
|
|
895
|
+
/** Decide if an inner event is TERMINAL. Default: an `AgentEvent`-shaped
|
|
896
|
+
* `{ _tag: 'done' | 'error' }`. */
|
|
897
|
+
readonly isTerminal?: (event: E) => boolean;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
export declare interface ResumableAgentStreamState<E> {
|
|
901
|
+
/** The UNWRAPPED inner events received so far, in order (deduped by seq). */
|
|
902
|
+
readonly events: ReadonlyArray<E>;
|
|
903
|
+
readonly status: ResumableStreamStatus;
|
|
904
|
+
/** How many times the transport dropped + auto-reconnected this run. */
|
|
905
|
+
readonly reconnects: number;
|
|
906
|
+
/** Set when status === 'error'. */
|
|
907
|
+
readonly error: unknown | undefined;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
export declare interface ResumableConsumeConfig<E> {
|
|
911
|
+
/** Max CONSECUTIVE reconnects WITHOUT progress before giving up. The counter
|
|
912
|
+
* resets whenever a reconnect delivers at least one new event, so a long
|
|
913
|
+
* stream survives any number of well-spaced drops. */
|
|
914
|
+
readonly maxReconnects: number;
|
|
915
|
+
/** Base backoff between reconnects in ms; grows exponentially, capped. */
|
|
916
|
+
readonly backoffMs: number;
|
|
917
|
+
readonly maxBackoffMs: number;
|
|
918
|
+
/** True when an inner event is TERMINAL (the run finished — do NOT reconnect). */
|
|
919
|
+
readonly isTerminal: (event: E) => boolean;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
* The pure resumable-consume loop as ONE Effect (no React). Opens the stream
|
|
924
|
+
* from the current cursor; on a drop BEFORE the terminal event it backs off and
|
|
925
|
+
* reopens with `fromSeq` = the last seq seen. Dedups by seq (replay overlap),
|
|
926
|
+
* unwraps each `SeqEvent` to its inner event, and reports through `sink`.
|
|
927
|
+
* Interruption (user cancel) ends it silently. Exported for direct testing.
|
|
928
|
+
*/
|
|
929
|
+
export declare const resumableConsumeProgram: <E>(method: ResumableStreamMethod<E>, baseInput: Readonly<Record<string, unknown>>, sink: ResumableSink<E>, config: ResumableConsumeConfig<E>) => Effect.Effect<void>;
|
|
930
|
+
|
|
931
|
+
/** Where the consume loop reports progress. The hook wires these to React
|
|
932
|
+
* state; tests wire a recorder. Kept separate from React so the resume logic
|
|
933
|
+
* is unit-testable without rendering. */
|
|
934
|
+
export declare interface ResumableSink<E> {
|
|
935
|
+
readonly onEvent: (event: E) => void;
|
|
936
|
+
readonly onStatus: (status: ResumableStreamStatus) => void;
|
|
937
|
+
/** A transport drop happened → a reconnect attempt is starting. */
|
|
938
|
+
readonly onReconnect: () => void;
|
|
939
|
+
readonly onError: (error: unknown) => void;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** The rpc surface a resumable run is invoked through — `{ ...input, fromSeq }`
|
|
943
|
+
* → a stream of seq-tagged elements. */
|
|
944
|
+
export declare type ResumableStreamMethod<E> = (payload: unknown) => Stream.Stream<SeqElement<E>, unknown, never>;
|
|
945
|
+
|
|
946
|
+
export declare type ResumableStreamStatus = 'idle' | 'streaming' | 'reconnecting' | 'done' | 'error';
|
|
947
|
+
|
|
948
|
+
/** Pure: map source rows → `{ value, label }` options. Falls back to the value
|
|
949
|
+
* when the label field is absent. Exported for direct testing + reuse. */
|
|
950
|
+
export declare const rowsToOptions: (rows: ReadonlyArray<Record<string, unknown>>, labelField: string, valueField: string) => ReadonlyArray<FieldOption>;
|
|
951
|
+
|
|
952
|
+
export declare interface RpcError {
|
|
953
|
+
/** Source — `'mutation'` for transactional unary calls, `'action'` for
|
|
954
|
+
* non-transactional unary calls, `'subscription'` for streams. */
|
|
955
|
+
readonly source: 'mutation' | 'action' | 'subscription';
|
|
956
|
+
/** RPC tag (e.g. `'orgs.create'`, `'projects.list'`). */
|
|
957
|
+
readonly tag: string;
|
|
958
|
+
/** The raw error value. May be a Schema.TaggedError instance, a plain
|
|
959
|
+
* Error, an unknown thrown value. Pattern-match on `_tag` for typed errors. */
|
|
960
|
+
readonly error: unknown;
|
|
961
|
+
/** Trace id of the failed call — the SAME id the server logged + the
|
|
962
|
+
* dashboards show. Lets a listener (or `DefaultErrorFallback`) point at
|
|
963
|
+
* `voltro logs --trace <id>`. Present when a client span was active
|
|
964
|
+
* (always, in practice — Effect's native tracer is ambient). */
|
|
965
|
+
readonly traceId?: string;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
export declare class RpcErrorBus {
|
|
969
|
+
#private;
|
|
970
|
+
/** Subscribe. Returns an unsubscribe function. */
|
|
971
|
+
on(listener: RpcErrorListener): () => void;
|
|
972
|
+
/** Emit. Pipeline code (useMutation / subscriptionCache) calls this. */
|
|
973
|
+
emit(event: RpcError): void;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
export declare type RpcErrorListener = (event: RpcError) => void;
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Derive table COLUMNS from a query's output `Schema` — an
|
|
980
|
+
* `Schema.Array(Schema.Struct({...}))`. Drills into the array's element and maps
|
|
981
|
+
* its properties (same descriptor shape as `schemaToFields`, reused for
|
|
982
|
+
* `<DataTable>` cells). Returns `[]` if the output isn't an array of objects.
|
|
983
|
+
*/
|
|
984
|
+
export declare const schemaToColumns: (schema: Schema.Schema.Any) => ReadonlyArray<FieldDescriptor>;
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Derive the ordered field list for a `Schema.Struct` input. Returns `[]` for a
|
|
988
|
+
* schema with no object properties (a scalar, `Schema.Void`, or anything
|
|
989
|
+
* `JSONSchema.make` cannot represent).
|
|
990
|
+
*/
|
|
991
|
+
export declare const schemaToFields: (schema: Schema.Schema.Any) => ReadonlyArray<FieldDescriptor>;
|
|
992
|
+
|
|
993
|
+
/** One persisted/wire element of a resumable stream. Mirrors `@voltro/ai`'s
|
|
994
|
+
* `SeqEvent` without taking a dependency on it (the client stays AI-agnostic). */
|
|
995
|
+
export declare interface SeqElement<E> {
|
|
996
|
+
readonly seq: number;
|
|
997
|
+
readonly event: E;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* Transition a pending mutation to 'success' or 'error'. Updates the
|
|
1002
|
+
* existing entry in-place (preserves order in the buffer) so the
|
|
1003
|
+
* panel doesn't shuffle while the user is reading it.
|
|
1004
|
+
*
|
|
1005
|
+
* No-op if no pending entry matches `id` (e.g. the start event was
|
|
1006
|
+
* dropped from the ring after a long session).
|
|
1007
|
+
*/
|
|
1008
|
+
export declare const settleMutation: (id: string, outcome: {
|
|
1009
|
+
readonly status: "success";
|
|
1010
|
+
readonly output: unknown;
|
|
1011
|
+
} | {
|
|
1012
|
+
readonly status: "error";
|
|
1013
|
+
readonly error: unknown;
|
|
1014
|
+
}) => void;
|
|
1015
|
+
|
|
1016
|
+
/** Shallow element-wise array equality. Pure — the cache-invalidation core. */
|
|
1017
|
+
export declare const shallowArrayEqual: (a: ReadonlyArray<unknown>, b: ReadonlyArray<unknown>) => boolean;
|
|
1018
|
+
|
|
1019
|
+
declare type SignalPayload<Messages extends WorkflowClientMessages, Name extends string> = NonNullable<Messages['signals']> extends Readonly<Record<Name, infer Payload>> ? Payload : unknown;
|
|
1020
|
+
|
|
1021
|
+
export declare interface SortState {
|
|
1022
|
+
readonly column: string;
|
|
1023
|
+
readonly direction: 'asc' | 'desc';
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/** Stable-key-ordered values of a sources record — the cache key for a derive. */
|
|
1027
|
+
export declare const sourceValues: (sources: Record<string, unknown>) => ReadonlyArray<unknown>;
|
|
1028
|
+
|
|
1029
|
+
export declare const ssrClientProxy: unknown;
|
|
1030
|
+
|
|
1031
|
+
export declare const ssrStubHandle: ApiHandle;
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* Stable, deterministic string for an arbitrary key array. Object keys
|
|
1035
|
+
* sort recursively so `{a:1,b:2}` and `{b:2,a:1}` map to the same string.
|
|
1036
|
+
* Arrays preserve order (it matters). Used as the cache's `Map` key.
|
|
1037
|
+
*/
|
|
1038
|
+
export declare const stableKey: (key: ReadonlyArray<unknown>) => string;
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Publish a NEW (pending) mutation event. Caller is responsible for
|
|
1042
|
+
* calling `settleMutation(id, ...)` later. Returns the id used to
|
|
1043
|
+
* settle.
|
|
1044
|
+
*
|
|
1045
|
+
* If the buffer is at MAX_MUTATIONS, the oldest entry is dropped to
|
|
1046
|
+
* make room.
|
|
1047
|
+
*/
|
|
1048
|
+
export declare const startMutation: (args: Pick<MutationEvent, "id" | "apiName" | "tag" | "input">) => void;
|
|
1049
|
+
|
|
1050
|
+
/** Subscribe to client errors. Returns an unsubscribe fn. */
|
|
1051
|
+
export declare const subscribeClientErrors: (listener: ClientErrorListener) => (() => void);
|
|
1052
|
+
|
|
1053
|
+
/** Subscribe to started client traces. Returns an unsubscribe fn. */
|
|
1054
|
+
export declare const subscribeClientTraces: (listener: ClientTraceListener) => () => void;
|
|
1055
|
+
|
|
1056
|
+
export declare const subscribeMutations: (cb: () => void) => (() => void);
|
|
1057
|
+
|
|
1058
|
+
export declare class SubscriptionCache {
|
|
1059
|
+
private readonly entries;
|
|
1060
|
+
private readonly inactiveTtlMs;
|
|
1061
|
+
private readonly onChangeHook;
|
|
1062
|
+
private readonly errorBus;
|
|
1063
|
+
constructor(options?: SubscriptionCacheOptions);
|
|
1064
|
+
/**
|
|
1065
|
+
* Register a subscriber. The cache forks the underlying fiber on the
|
|
1066
|
+
* first subscriber and re-uses it for the rest. Returns the snapshot
|
|
1067
|
+
* getter, the per-subscriber notify-on-change hook, and an unsubscribe
|
|
1068
|
+
* function.
|
|
1069
|
+
*
|
|
1070
|
+
* `fetch` is invoked at most once per cache-entry lifetime (it builds
|
|
1071
|
+
* the Effect Stream against the runtime). Subsequent subscribers piggy-
|
|
1072
|
+
* back on the same stream.
|
|
1073
|
+
*/
|
|
1074
|
+
subscribe(keyArr: ReadonlyArray<unknown>, fetch: () => Stream.Stream<SubscriptionEvent<unknown>, unknown, never>, runtime: AnyRuntime, onChange: () => void, options?: {
|
|
1075
|
+
readonly source?: string | ReadonlyArray<string>;
|
|
1076
|
+
}): {
|
|
1077
|
+
readonly getSnapshot: () => CacheSnapshot<unknown>;
|
|
1078
|
+
readonly unsubscribe: () => void;
|
|
1079
|
+
};
|
|
1080
|
+
/**
|
|
1081
|
+
* Stage an optimistic patch against `keyArr`. Subscribers see the
|
|
1082
|
+
* patched value on the next snapshot read. Returns a handle for manual
|
|
1083
|
+
* revert (the canonical revert is via `revertByMutation` once the
|
|
1084
|
+
* mutation resolves).
|
|
1085
|
+
*
|
|
1086
|
+
* If the entry doesn't exist yet (mutation fires before its
|
|
1087
|
+
* subscription mounts — uncommon but possible), we create a stub entry
|
|
1088
|
+
* with no fiber. When a subscription later mounts for the same key,
|
|
1089
|
+
* the patch is preserved and the fiber is forked normally.
|
|
1090
|
+
*/
|
|
1091
|
+
update<T>(keyArr: ReadonlyArray<unknown>, reducer: (current: T) => T, mutationId: string): {
|
|
1092
|
+
readonly revert: () => void;
|
|
1093
|
+
readonly patchId: string;
|
|
1094
|
+
};
|
|
1095
|
+
/**
|
|
1096
|
+
* Patch every cached entry whose rpc tag matches `tag`, regardless of
|
|
1097
|
+
* the input the subscription was opened with. The escape hatch for
|
|
1098
|
+
* sourceless queries — joins, aggregates, custom-projection routes —
|
|
1099
|
+
* that the auto-optimistic source-router can't reach.
|
|
1100
|
+
*
|
|
1101
|
+
* Usage from `.withOptimistic`:
|
|
1102
|
+
*
|
|
1103
|
+
* create.withOptimistic((cache, input) => {
|
|
1104
|
+
* cache.forTag('todos.summary', (current) => ({
|
|
1105
|
+
* ...(current as { count: number }),
|
|
1106
|
+
* count: (current as { count: number }).count + 1,
|
|
1107
|
+
* }))
|
|
1108
|
+
* })
|
|
1109
|
+
*
|
|
1110
|
+
* Returns the number of entries that were patched, so callers can warn
|
|
1111
|
+
* if zero entries matched (probably means the tag is misspelt).
|
|
1112
|
+
*/
|
|
1113
|
+
forTag<T>(tag: string, reducer: (current: T) => T, mutationId: string): {
|
|
1114
|
+
readonly patchedCount: number;
|
|
1115
|
+
};
|
|
1116
|
+
/** Drop every patch owned by `mutationId` from EVERY entry. */
|
|
1117
|
+
revertByMutation(mutationId: string): void;
|
|
1118
|
+
/**
|
|
1119
|
+
* Mark a SUCCEEDED mutation's optimistic patches as confirmed. Unlike
|
|
1120
|
+
* `revertByMutation` (used on failure), this does NOT drop them — they stay
|
|
1121
|
+
* visible until the next server snapshot/delta updates `base` (which then
|
|
1122
|
+
* reflects the committed write and drops them, see the stream apply loop).
|
|
1123
|
+
* This removes the on→off→on flash where dropping the patch on mutation
|
|
1124
|
+
* resolve briefly exposes a stale base before the server delta lands.
|
|
1125
|
+
*/
|
|
1126
|
+
confirmByMutation(mutationId: string): void;
|
|
1127
|
+
/**
|
|
1128
|
+
* Auto-derive optimistic patches from a mutation's declared target(s).
|
|
1129
|
+
* Iterates every cache entry whose `source` table matches a target's
|
|
1130
|
+
* table; applies the canonical patch for the op:
|
|
1131
|
+
*
|
|
1132
|
+
* - insert : prepend (or append) a row derived from input + an
|
|
1133
|
+
* `optimistic: true` flag + a generated id.
|
|
1134
|
+
* - update : replace the row whose id matches `input.id` (or the
|
|
1135
|
+
* custom identify fn from the spec) by merging input
|
|
1136
|
+
* fields on top of the current row.
|
|
1137
|
+
* - delete : filter out the row whose id matches `input.id`.
|
|
1138
|
+
*
|
|
1139
|
+
* Specs with a custom `shape`/`identify`/`order` function override
|
|
1140
|
+
* these defaults. All patches are tagged with `mutationId` for atomic
|
|
1141
|
+
* revert.
|
|
1142
|
+
*/
|
|
1143
|
+
autoApply(targets: ReadonlyArray<AutoApplyTarget>, input: Record<string, unknown>, mutationId: string): void;
|
|
1144
|
+
/** Drop a specific patch by id. */
|
|
1145
|
+
private revertPatch;
|
|
1146
|
+
/**
|
|
1147
|
+
* Read the current snapshot for a key WITHOUT subscribing. If the
|
|
1148
|
+
* entry doesn't exist, returns the "empty" snapshot (data=undefined,
|
|
1149
|
+
* revision=-1, no patches). Safe to call from `useSyncExternalStore`'s
|
|
1150
|
+
* getSnapshot, which is invoked many times during a single render.
|
|
1151
|
+
*/
|
|
1152
|
+
peek(keyArr: ReadonlyArray<unknown>): CacheSnapshot<unknown>;
|
|
1153
|
+
/** Test / debug helper. */
|
|
1154
|
+
getEntry(keyArr: ReadonlyArray<unknown>): CacheEntry | undefined;
|
|
1155
|
+
/** Test / debug helper. */
|
|
1156
|
+
size(): number;
|
|
1157
|
+
/**
|
|
1158
|
+
* Devtools introspection: snapshot every cache entry's wire state +
|
|
1159
|
+
* metadata. Returns plain data (no live references) so consumers can
|
|
1160
|
+
* render without worrying about React state-equality.
|
|
1161
|
+
*
|
|
1162
|
+
* The map is keyed by the cache's stable-key string (same one the
|
|
1163
|
+
* fan-out invalidation uses). Entries appear in insertion order;
|
|
1164
|
+
* sort at the call site if order matters.
|
|
1165
|
+
*/
|
|
1166
|
+
peekAll(): ReadonlyArray<CacheEntrySnapshot>;
|
|
1167
|
+
/** Tear down every entry (used on runtime dispose). */
|
|
1168
|
+
destroy(runtime: AnyRuntime): void;
|
|
1169
|
+
/**
|
|
1170
|
+
* Re-issue every active subscription against the runtime. Used after
|
|
1171
|
+
* a soft re-auth (login on the same WebSocket connection) so the
|
|
1172
|
+
* server resolves the new subject for each subscription's tenant
|
|
1173
|
+
* scope — without dropping the connection.
|
|
1174
|
+
*
|
|
1175
|
+
* For each entry with a saved fetch:
|
|
1176
|
+
* - interrupt the current fiber (stops the old WS subscription)
|
|
1177
|
+
* - clear the base state so the next snapshot fully replaces it
|
|
1178
|
+
* - re-fork via the saved fetch (new WS subscription with the
|
|
1179
|
+
* server's now-current subject for this connection)
|
|
1180
|
+
*
|
|
1181
|
+
* Subscribers' `onChange` callbacks fire when the new snapshot
|
|
1182
|
+
* lands, prompting React to re-render with the post-reauth data.
|
|
1183
|
+
*
|
|
1184
|
+
* Stub entries (no fetch saved yet) are left alone — they'll
|
|
1185
|
+
* promote naturally on their next subscriber.
|
|
1186
|
+
*/
|
|
1187
|
+
refreshAll(runtime: AnyRuntime): void;
|
|
1188
|
+
private create;
|
|
1189
|
+
private createStub;
|
|
1190
|
+
private freshState;
|
|
1191
|
+
private startFiber;
|
|
1192
|
+
private invalidate;
|
|
1193
|
+
private getSnapshot;
|
|
1194
|
+
private unsubscribe;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
export declare interface SubscriptionCacheOptions {
|
|
1198
|
+
/** Milliseconds to keep an entry alive after the last subscriber leaves.
|
|
1199
|
+
* Lets back-button / quick remount reuse the warm subscription. */
|
|
1200
|
+
readonly inactiveTtlMs?: number;
|
|
1201
|
+
/** Debug hook fired on every cache state change. */
|
|
1202
|
+
readonly onChange?: (key: string) => void;
|
|
1203
|
+
/** Optional error bus — when a subscription stream errors out, the
|
|
1204
|
+
* cache reports it to the bus so global listeners (e.g. auto-logout
|
|
1205
|
+
* on Unauthenticated) can react. */
|
|
1206
|
+
readonly errorBus?: RpcErrorBus;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* Subscribe to a streaming rpc by tag.
|
|
1211
|
+
*
|
|
1212
|
+
* @param apiName The name under which the rpc client was mounted in
|
|
1213
|
+
* `app.config.ts`.
|
|
1214
|
+
* @param rpcTag The rpc's tag (e.g. `'todos.list'`). Drives cache
|
|
1215
|
+
* dedup AND descriptor lookup for auto-optimistic
|
|
1216
|
+
* source-routing.
|
|
1217
|
+
* @param input The rpc payload. Stable serialisation is part of the
|
|
1218
|
+
* cache key.
|
|
1219
|
+
* @param options `{ skip }` defers the subscription until inputs are
|
|
1220
|
+
* ready — while skipped no ws subscription opens and
|
|
1221
|
+
* `data` stays `undefined`. Flipping `skip` back to
|
|
1222
|
+
* false subscribes with the current input. Mirrors
|
|
1223
|
+
* Convex's `"skip"` sentinel without overloading the
|
|
1224
|
+
* input argument.
|
|
1225
|
+
*/
|
|
1226
|
+
export declare interface SubscriptionOptions {
|
|
1227
|
+
readonly skip?: boolean;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
export declare interface SubscriptionState<T> {
|
|
1231
|
+
/** Latest data (base + optimistic patches) — undefined until the
|
|
1232
|
+
* initial server snapshot arrives. */
|
|
1233
|
+
readonly data: T | undefined;
|
|
1234
|
+
/** Server revision counter; -1 before first snapshot. */
|
|
1235
|
+
readonly revision: number;
|
|
1236
|
+
/** Wall-clock ms when the most recent delta was emitted; undefined for snapshots / optimistic. */
|
|
1237
|
+
readonly emittedAt: number | undefined;
|
|
1238
|
+
/** Stream error (only surfaced when no snapshot has ever arrived). */
|
|
1239
|
+
readonly error: unknown | undefined;
|
|
1240
|
+
/** Number of live optimistic patches currently applied. Useful for
|
|
1241
|
+
* rendering a faint "syncing…" indicator when > 0. */
|
|
1242
|
+
readonly pendingPatches: number;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/** A map entry: a bare event name, or a function of the component's props. */
|
|
1246
|
+
export declare type TrackingEntry = string | ((props: Record<string, unknown>) => TrackingEvent);
|
|
1247
|
+
|
|
1248
|
+
/** A resolved analytics event: a name + arbitrary payload. */
|
|
1249
|
+
export declare type TrackingEvent = {
|
|
1250
|
+
readonly event: string;
|
|
1251
|
+
} & Record<string, unknown>;
|
|
1252
|
+
|
|
1253
|
+
/** The declarative map. `onMount`/`onUnmount` are lifecycle; every other key is
|
|
1254
|
+
* a CALLBACK PROP name to wrap (so calling `onClick` also fires its event). */
|
|
1255
|
+
export declare interface TrackingMap {
|
|
1256
|
+
readonly onMount?: TrackingEntry;
|
|
1257
|
+
readonly onUnmount?: TrackingEntry;
|
|
1258
|
+
readonly [callback: string]: TrackingEntry | undefined;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
/** Where resolved events go — the analytics sink (the client→server transport
|
|
1262
|
+
* provides this; tests provide a recorder). */
|
|
1263
|
+
export declare type TrackingSink = (event: TrackingEvent) => void;
|
|
1264
|
+
|
|
1265
|
+
export declare interface TrackingSpec {
|
|
1266
|
+
readonly name: string;
|
|
1267
|
+
readonly map: TrackingMap;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
export declare const UNDO_APPLY_TAG = "__voltro.undo.apply";
|
|
1271
|
+
|
|
1272
|
+
export declare const UNDO_LOG_TAG = "__voltro.undo.log";
|
|
1273
|
+
|
|
1274
|
+
export declare const UNDO_REDO_TAG = "__voltro.undo.redo";
|
|
1275
|
+
|
|
1276
|
+
export declare interface UndoController {
|
|
1277
|
+
readonly entries: ReadonlyArray<UndoLogEntry>;
|
|
1278
|
+
readonly loading: boolean;
|
|
1279
|
+
/** True when there's a not-yet-undone, undoable (non-action-crossing) entry. */
|
|
1280
|
+
readonly canUndo: boolean;
|
|
1281
|
+
/** True when there's a previously-undone entry to redo. */
|
|
1282
|
+
readonly canRedo: boolean;
|
|
1283
|
+
/** Undo one invocation by id (the server synthesizes + applies its inverse). */
|
|
1284
|
+
readonly undo: (invocationId: string) => Promise<void>;
|
|
1285
|
+
/** Redo one previously-undone invocation by id. */
|
|
1286
|
+
readonly redo: (invocationId: string) => Promise<void>;
|
|
1287
|
+
/** Undo the newest undoable action (Ctrl-Z). No-op when none. */
|
|
1288
|
+
readonly undoLast: () => Promise<void>;
|
|
1289
|
+
/** Redo the newest undone action (Ctrl-Shift-Z). No-op when none. */
|
|
1290
|
+
readonly redoLast: () => Promise<void>;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
export declare interface UndoControls {
|
|
1294
|
+
readonly record: (entry: UndoEntry) => void;
|
|
1295
|
+
readonly undo: () => Promise<void>;
|
|
1296
|
+
readonly redo: () => Promise<void>;
|
|
1297
|
+
readonly canUndo: boolean;
|
|
1298
|
+
readonly canRedo: boolean;
|
|
1299
|
+
readonly stack: ReadonlyArray<UndoEntry>;
|
|
1300
|
+
/** Set when the next undo would cross an action / hit a conflict — the UI
|
|
1301
|
+
* disables + explains instead of silently failing. */
|
|
1302
|
+
readonly nextBlockedBy: 'action' | 'conflict' | undefined;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
export declare interface UndoEntry {
|
|
1306
|
+
/** The mutation invocation this entry can undo. */
|
|
1307
|
+
readonly invocationId: string;
|
|
1308
|
+
/** Human label from the mutation (e.g. "create todo") for "Undo 'create todo'". */
|
|
1309
|
+
readonly label?: string;
|
|
1310
|
+
/** Why the NEXT undo past here is blocked (an external action / a conflict). */
|
|
1311
|
+
readonly blockedBy?: 'action' | 'conflict';
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/** Structural mirror of `@voltro/protocol`'s UndoLogEntry — the client stays
|
|
1315
|
+
* decoupled from server packages (like useProvenance mirrors ProvenanceResult). */
|
|
1316
|
+
export declare interface UndoLogEntry {
|
|
1317
|
+
readonly id: string;
|
|
1318
|
+
readonly tag: string;
|
|
1319
|
+
readonly label: string | null;
|
|
1320
|
+
readonly undone: boolean;
|
|
1321
|
+
readonly crossesAction: boolean;
|
|
1322
|
+
readonly createdAt: string;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
declare type UpdatePayload<Messages extends WorkflowClientMessages, Name extends string> = NonNullable<Messages['updates']> extends Readonly<Record<Name, infer Update>> ? Update extends {
|
|
1326
|
+
readonly payload: infer Payload;
|
|
1327
|
+
} ? Payload : unknown : unknown;
|
|
1328
|
+
|
|
1329
|
+
declare type UpdateResult<Messages extends WorkflowClientMessages, Name extends string> = NonNullable<Messages['updates']> extends Readonly<Record<Name, infer Update>> ? Update extends {
|
|
1330
|
+
readonly result: infer Result;
|
|
1331
|
+
} ? Omit<WorkflowUpdateResult, 'result'> & {
|
|
1332
|
+
readonly result: Result;
|
|
1333
|
+
} : WorkflowUpdateResult : WorkflowUpdateResult;
|
|
1334
|
+
|
|
1335
|
+
export declare interface UploadHandle {
|
|
1336
|
+
/** Upload one file. Resolves the stored asset or rejects (sets `.error`). */
|
|
1337
|
+
readonly upload: (file: File | Blob, opts?: UploadOptions) => Promise<UploadResult>;
|
|
1338
|
+
/** Upload many with bounded concurrency; resolves in input order. */
|
|
1339
|
+
readonly uploadMany: (files: ReadonlyArray<File | Blob>, opts?: UploadOptions) => Promise<ReadonlyArray<UploadResult>>;
|
|
1340
|
+
/** Aggregate progress across the in-flight batch, 0..1. */
|
|
1341
|
+
readonly progress: number;
|
|
1342
|
+
readonly status: UploadStatus;
|
|
1343
|
+
readonly error: unknown | undefined;
|
|
1344
|
+
/** Abort every in-flight upload (rejects their promises with AbortError). */
|
|
1345
|
+
readonly cancel: () => void;
|
|
1346
|
+
/** Clear status/error/progress back to idle. */
|
|
1347
|
+
readonly reset: () => void;
|
|
1348
|
+
/** Drop-handler: extracts files from a drag event + uploads them. Spread
|
|
1349
|
+
* `dropzoneProps` onto a container, or call this directly. */
|
|
1350
|
+
readonly onDrop: (event: DragEvent_2, opts?: UploadOptions) => Promise<ReadonlyArray<UploadResult>>;
|
|
1351
|
+
/** Paste-handler: uploads any files on the clipboard (screenshot paste, etc.). */
|
|
1352
|
+
readonly onPaste: (event: ClipboardEvent_2, opts?: UploadOptions) => Promise<ReadonlyArray<UploadResult>>;
|
|
1353
|
+
/** Spread onto a div for a zero-boilerplate dropzone (prevents default drag
|
|
1354
|
+
* nav + uploads dropped files with the hook's default options). */
|
|
1355
|
+
readonly dropzoneProps: {
|
|
1356
|
+
readonly onDragOver: (e: DragEvent_2) => void;
|
|
1357
|
+
readonly onDrop: (e: DragEvent_2) => void;
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
export declare interface UploadOptions {
|
|
1362
|
+
/** `'private'` (default) or `'public'`. Public objects get a cacheable URL. */
|
|
1363
|
+
readonly visibility?: 'public' | 'private';
|
|
1364
|
+
/** Fixed logical key (e.g. `avatars/<userId>.png`); else content-addressed. */
|
|
1365
|
+
readonly key?: string;
|
|
1366
|
+
/** App metadata stored on the ref (so no parallel `assets` table is needed). */
|
|
1367
|
+
readonly folder?: string;
|
|
1368
|
+
readonly tags?: ReadonlyArray<string>;
|
|
1369
|
+
readonly alt?: string;
|
|
1370
|
+
readonly caption?: string;
|
|
1371
|
+
/** rpc tag of the ticket-minting action. Default `'storage.mintUploadTicket'`
|
|
1372
|
+
* — override for a namespaced storage plugin instance. */
|
|
1373
|
+
readonly mintTag?: string;
|
|
1374
|
+
/** Transport. `'through-app'` (default) POSTs the bytes through the app on
|
|
1375
|
+
* every provider. `'presign'` offloads the client→server leg: on a
|
|
1376
|
+
* presigning provider (s3/minio) it PUTs straight to the bucket, then the
|
|
1377
|
+
* server fetches the bytes back to scan + register (a non-degraded ref) —
|
|
1378
|
+
* and transparently falls back to through-app when the provider can't
|
|
1379
|
+
* presign. `'resumable'` splits the file into chunks and uploads them one at
|
|
1380
|
+
* a time (each retryable independently) — for large media over flaky links.
|
|
1381
|
+
* `'multipart'` PUTs each part DIRECTLY to the bucket (offloaded + resumable,
|
|
1382
|
+
* s3/minio) for multi-GB media, falling back to `'resumable'` when the
|
|
1383
|
+
* provider can't do multipart. */
|
|
1384
|
+
readonly prefer?: 'through-app' | 'presign' | 'resumable' | 'multipart';
|
|
1385
|
+
/** rpc tag of the presign-minting action. Default `'storage.mintPresignedUpload'`. */
|
|
1386
|
+
readonly presignMintTag?: string;
|
|
1387
|
+
/** rpc tag of the finalize action. Default `'storage.finalizeUpload'`. */
|
|
1388
|
+
readonly finalizeTag?: string;
|
|
1389
|
+
/** rpc tag of the resumable-begin action. Default `'storage.beginResumableUpload'`. */
|
|
1390
|
+
readonly beginResumableTag?: string;
|
|
1391
|
+
/** rpc tags for the multipart actions (defaults `'storage.beginMultipartUpload'` etc). */
|
|
1392
|
+
readonly multipartBeginTag?: string;
|
|
1393
|
+
readonly multipartSignTag?: string;
|
|
1394
|
+
readonly multipartCompleteTag?: string;
|
|
1395
|
+
readonly multipartAbortTag?: string;
|
|
1396
|
+
/** Chunk/part size (bytes) for `prefer:'resumable'`/`'multipart'`. Server
|
|
1397
|
+
* default (5 MiB) if omitted; multipart clamps to the S3 5 MiB minimum. */
|
|
1398
|
+
readonly chunkSize?: number;
|
|
1399
|
+
/** Max parallel uploads for `uploadMany`. Default 3. */
|
|
1400
|
+
readonly concurrency?: number;
|
|
1401
|
+
/** Retry attempts per file on a network/5xx error. Default 1. */
|
|
1402
|
+
readonly retries?: number;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
/** The stored asset, shaped as a drop-in for the common CMS-upload contract. */
|
|
1406
|
+
export declare interface UploadResult {
|
|
1407
|
+
readonly id: string;
|
|
1408
|
+
readonly url: string;
|
|
1409
|
+
readonly name: string;
|
|
1410
|
+
readonly mime: string;
|
|
1411
|
+
readonly size: number;
|
|
1412
|
+
readonly width?: number;
|
|
1413
|
+
readonly height?: number;
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
export declare type UploadStatus = 'idle' | 'uploading' | 'success' | 'error';
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
* Invoke a server `defineAction` procedure by tag. Unlike `useMutation`,
|
|
1420
|
+
* an action has no optimistic / cache surface — it's a unary call whose
|
|
1421
|
+
* effects (sends, captures, side-effecting writes the framework must NOT
|
|
1422
|
+
* preview locally) only become visible when the server pushes a delta on
|
|
1423
|
+
* an independent subscription.
|
|
1424
|
+
*/
|
|
1425
|
+
export declare const useAction: <Input = unknown, Output = unknown>(apiName: string, rpcTag: string) => ActionState<Input, Output>;
|
|
1426
|
+
|
|
1427
|
+
export declare const useAgent: (apiName: string, rpcTag: string) => AgentControls;
|
|
1428
|
+
|
|
1429
|
+
export declare const useAgentChat: (apiName: string, agent: string, options: UseAgentChatOptions) => AgentChatState;
|
|
1430
|
+
|
|
1431
|
+
export declare interface UseAgentChatOptions {
|
|
1432
|
+
/** The thread to read + append to. Mint one per chat (e.g. a useRef'd uuid). */
|
|
1433
|
+
readonly threadId: string;
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1436
|
+
export declare const useAgentStream: <E = unknown>(apiName: string, rpcTag: string) => AgentStreamControls<E>;
|
|
1437
|
+
|
|
1438
|
+
export declare const useAsyncValidation: (apiName: string, queryTag: string, value: string, options: UseAsyncValidationOptions) => AsyncValidationResult;
|
|
1439
|
+
|
|
1440
|
+
export declare interface UseAsyncValidationOptions {
|
|
1441
|
+
/** Map the input value → the validation query's input. Default `{ value }`. */
|
|
1442
|
+
readonly input?: (value: string) => Readonly<Record<string, unknown>>;
|
|
1443
|
+
/** Map the query result → a verdict. REQUIRED — only you know the shape. */
|
|
1444
|
+
readonly interpret: (data: unknown) => {
|
|
1445
|
+
readonly valid: boolean;
|
|
1446
|
+
readonly message?: string;
|
|
1447
|
+
};
|
|
1448
|
+
readonly debounceMs?: number;
|
|
1449
|
+
readonly skipEmpty?: boolean;
|
|
1450
|
+
}
|
|
1451
|
+
|
|
1452
|
+
/** Reactively: may the current subject call something needing `required`
|
|
1453
|
+
* scope(s)? Use to gate UI. Defaults to false (deny) with no provider. */
|
|
1454
|
+
export declare const useCan: (required: string | ReadonlyArray<string>) => boolean;
|
|
1455
|
+
|
|
1456
|
+
/**
|
|
1457
|
+
* Fetch the api's capability manifest (procedures + tables + schemas) once.
|
|
1458
|
+
* Browser-safe — imports only React + the runtime context, exactly like
|
|
1459
|
+
* `useProvenance`. The inspect surface is default-open in dev; when a deploy
|
|
1460
|
+
* sets an inspect token the manifest GET is bearer-gated, so a production admin
|
|
1461
|
+
* pointed at a locked-down api must surface that token (a deploy concern, not
|
|
1462
|
+
* this hook's).
|
|
1463
|
+
*/
|
|
1464
|
+
export declare const useCapabilityManifest: (apiName: string) => CapabilityManifestState;
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* Bind a data-copilot action by api name + tag. The action's input is
|
|
1468
|
+
* `{ question }` and its output is a {@link CopilotAnswer}. Generic over the
|
|
1469
|
+
* row shape so a caller that knows its schema gets typed rows back.
|
|
1470
|
+
*/
|
|
1471
|
+
export declare const useDataCopilot: <Row = Record<string, unknown>>(apiName: string, actionTag: string) => DataCopilotState<Row>;
|
|
1472
|
+
|
|
1473
|
+
export declare const useDataTable: <Row extends Record<string, unknown> = Record<string, unknown>>(apiName: string, queryTag: string, options?: UseDataTableOptions) => DataTableState<Row>;
|
|
1474
|
+
|
|
1475
|
+
export declare interface UseDataTableOptions {
|
|
1476
|
+
/** The query input (filters/pagination cursor). */
|
|
1477
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
1478
|
+
/** Explicit columns — overrides the schema-derived ones. */
|
|
1479
|
+
readonly columns?: ReadonlyArray<FieldDescriptor>;
|
|
1480
|
+
readonly initialSort?: SortState;
|
|
1481
|
+
/** Opt into "load more" pagination: the subscription input gets a growing
|
|
1482
|
+
* `limit` (the query applies `.limit(input.limit)`). This is LIVE
|
|
1483
|
+
* grow-the-window pagination — rows stay reactive as the window grows. Not
|
|
1484
|
+
* cursor-based (cursor + live is the windowed-subscriptions idea); use it
|
|
1485
|
+
* when O(window) is fine and you want the simple "Load more" UX. */
|
|
1486
|
+
readonly pageSize?: number;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
/** Debounce a value — returns the latest value after `ms` of quiet. Reusable. */
|
|
1490
|
+
export declare const useDebounced: <T>(value: T, ms?: number) => T;
|
|
1491
|
+
|
|
1492
|
+
/**
|
|
1493
|
+
* Compute a derived value from a record of reactive sources. Recomputes the
|
|
1494
|
+
* reducer only when a source value changes (shallow compare); returns the
|
|
1495
|
+
* cached (same-reference) result otherwise. The reducer should be pure.
|
|
1496
|
+
*/
|
|
1497
|
+
export declare const useDerived: <S extends Record<string, unknown>, T>(sources: S, reducer: (sources: S) => T) => T;
|
|
1498
|
+
|
|
1499
|
+
export declare const useFormBinding: <Input extends Record<string, unknown> = Record<string, unknown>, Output = unknown>(apiName: string, mutationTag: string, options: UseFormBindingOptions<Input>) => FormBinding<Input, Output>;
|
|
1500
|
+
|
|
1501
|
+
export declare interface UseFormBindingOptions<Input> {
|
|
1502
|
+
/** The mutation's input `Schema`. Optional: when omitted it is resolved from
|
|
1503
|
+
* the mounted client descriptor (`descriptors[tag].input`, the capability
|
|
1504
|
+
* map — innovation/06). Pass it explicitly to override, or when the
|
|
1505
|
+
* descriptor isn't on the client. */
|
|
1506
|
+
readonly schema?: Schema.Schema.Any;
|
|
1507
|
+
/** Initial field values. */
|
|
1508
|
+
readonly defaults?: Partial<Input>;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
/** The field shape a `<AutoForm mutation=…>` will render — from the mutation's
|
|
1512
|
+
* input Schema. Use it to render a matching skeleton while anything the form
|
|
1513
|
+
* depends on is still loading. */
|
|
1514
|
+
export declare const useFormSkeleton: (apiName: string, mutationTag: string) => ReadonlyArray<FieldDescriptor>;
|
|
1515
|
+
|
|
1516
|
+
/** Lookup a single api's runtime + cache by name. */
|
|
1517
|
+
export declare const useFrameworkApi: (apiName: string) => ApiHandle;
|
|
1518
|
+
|
|
1519
|
+
export declare const useFrameworkRuntimes: () => FrameworkRuntimes;
|
|
1520
|
+
|
|
1521
|
+
/**
|
|
1522
|
+
* Invoke a unary rpc by tag. The descriptor metadata (mounted via
|
|
1523
|
+
* `app.config.ts`'s `apis` → emitted by codegen as `appDescriptors`)
|
|
1524
|
+
* drives auto-optimistic patching.
|
|
1525
|
+
*/
|
|
1526
|
+
export declare const useMutation: <Input = unknown, Output = unknown>(apiName: string, rpcTag: string) => MutationBuilder<Input, Output>;
|
|
1527
|
+
|
|
1528
|
+
export declare const useOnRpcError: (apiName: string, listener: RpcErrorListener) => void;
|
|
1529
|
+
|
|
1530
|
+
export declare const useOutbox: (options: UseOutboxOptions) => OutboxControls;
|
|
1531
|
+
|
|
1532
|
+
export declare interface UseOutboxOptions {
|
|
1533
|
+
/** Perform one queued write (the real mutation). Throw to fail. */
|
|
1534
|
+
readonly send: (entry: OutboxEntry) => Promise<void>;
|
|
1535
|
+
/** Online override (defaults to navigator.onLine + online/offline events). */
|
|
1536
|
+
readonly online?: boolean;
|
|
1537
|
+
/** Classify a send error as a conflict (blocks replay) vs a transient
|
|
1538
|
+
* failure (retried). Default: an error with `conflict === true` or the
|
|
1539
|
+
* undo concurrency tag. */
|
|
1540
|
+
readonly isConflict?: (error: unknown) => boolean;
|
|
1541
|
+
readonly idFor?: () => string;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
/** The current subject's scopes (defaults to none if no provider). */
|
|
1545
|
+
export declare const usePermissions: () => PermissionState_2;
|
|
1546
|
+
|
|
1547
|
+
export declare const usePreview: <Input = Record<string, unknown>>(apiName: string, previewTag: string) => PreviewState<Input>;
|
|
1548
|
+
|
|
1549
|
+
export declare const useProvenance: (apiName: string, table: string, id: string, column?: string) => ProvenanceState;
|
|
1550
|
+
|
|
1551
|
+
export declare const useQueryField: (apiName: string, queryTag: string, options?: UseQueryFieldOptions) => QueryFieldState;
|
|
1552
|
+
|
|
1553
|
+
export declare interface UseQueryFieldOptions {
|
|
1554
|
+
/** Map the typed term → the source query's input. Default `{ q: term }`. */
|
|
1555
|
+
readonly input?: (term: string) => Record<string, unknown>;
|
|
1556
|
+
/** Row field used as the option label. Default `'name'`. */
|
|
1557
|
+
readonly labelField?: string;
|
|
1558
|
+
/** Row field used as the option value. Default `'id'`. */
|
|
1559
|
+
readonly valueField?: string;
|
|
1560
|
+
/** Debounce before the term reaches the query. Default 200ms. */
|
|
1561
|
+
readonly debounceMs?: number;
|
|
1562
|
+
readonly initialTerm?: string;
|
|
1563
|
+
/** Don't open the subscription until the term is non-empty (typeahead). */
|
|
1564
|
+
readonly skipUntilTerm?: boolean;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
export declare const useQueryFilters: <Row = Record<string, unknown>>(apiName: string, queryTag: string, options?: UseQueryFiltersOptions) => QueryFiltersState<Row>;
|
|
1568
|
+
|
|
1569
|
+
export declare interface UseQueryFiltersOptions {
|
|
1570
|
+
readonly initial?: Readonly<Record<string, unknown>>;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
export declare const useRecord: <R = Record<string, unknown>>(apiName: string, queryTag: string, input?: Readonly<Record<string, unknown>>) => RecordState<R>;
|
|
1574
|
+
|
|
1575
|
+
export declare const useRefreshSubscriptions: (apiName: string) => (() => void);
|
|
1576
|
+
|
|
1577
|
+
/**
|
|
1578
|
+
* Reactively gate ONE resource action. Bind a server query (`source:
|
|
1579
|
+
* '_voltro_rebac_tuples'`) that runs `can()` for the input and returns
|
|
1580
|
+
* `{ allowed }`; this hook surfaces it fail-closed + live (revoke flips it).
|
|
1581
|
+
*/
|
|
1582
|
+
export declare const useResourceCan: (apiName: string, rpcTag: string, input: ResourceCanInput, options?: SubscriptionOptions) => UseResourceCanState;
|
|
1583
|
+
|
|
1584
|
+
/**
|
|
1585
|
+
* Reactively gate MANY resources of one (action, type) in a single
|
|
1586
|
+
* subscription — the table-row case (one hook call, not one-per-row). Bind a
|
|
1587
|
+
* server query returning `{ allowedIds }` (the permitted subset); this hook
|
|
1588
|
+
* exposes it as a `Set` for membership tests, fail-closed + live.
|
|
1589
|
+
*/
|
|
1590
|
+
export declare const useResourceCans: (apiName: string, rpcTag: string, input: ResourceCansInput, options?: SubscriptionOptions) => UseResourceCansState;
|
|
1591
|
+
|
|
1592
|
+
export declare interface UseResourceCansState {
|
|
1593
|
+
/** The ids the subject may act on (membership test for per-row gating). A row
|
|
1594
|
+
* whose id is absent is denied. */
|
|
1595
|
+
readonly allowedIds: ReadonlySet<string>;
|
|
1596
|
+
readonly pending: boolean;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
export declare interface UseResourceCanState {
|
|
1600
|
+
/** Whether the subject may perform the action — fails CLOSED (false) until the
|
|
1601
|
+
* first verdict and whenever the subscription has no data. */
|
|
1602
|
+
readonly allowed: boolean;
|
|
1603
|
+
/** True before the first server verdict arrives. */
|
|
1604
|
+
readonly pending: boolean;
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
export declare const useResumableAgentStream: <E = unknown>(apiName: string, rpcTag: string, options?: ResumableAgentStreamOptions<E>) => ResumableAgentStreamControls<E>;
|
|
1608
|
+
|
|
1609
|
+
export declare const useSubscription: <T = unknown>(apiName: string, rpcTag: string, input?: Readonly<Record<string, unknown>>, options?: SubscriptionOptions) => SubscriptionState<T>;
|
|
1610
|
+
|
|
1611
|
+
/** The column shape a `<DataTable query=…>` will render — from the query's
|
|
1612
|
+
* output Schema. */
|
|
1613
|
+
export declare const useTableSkeleton: (apiName: string, queryTag: string) => ReadonlyArray<FieldDescriptor>;
|
|
1614
|
+
|
|
1615
|
+
/**
|
|
1616
|
+
* Wire a component's tracking: fire `onMount`/`onUnmount` from an effect, and
|
|
1617
|
+
* return the props with the spec's callback props wrapped. The component spreads
|
|
1618
|
+
* the returned props. The sink is the analytics transport (injected, so the
|
|
1619
|
+
* kernel stays transport-agnostic — and testable).
|
|
1620
|
+
*/
|
|
1621
|
+
export declare const useTracking: (spec: TrackingSpec, props: Record<string, unknown>, sink: TrackingSink) => Record<string, unknown>;
|
|
1622
|
+
|
|
1623
|
+
export declare const useUndo: (options: UseUndoOptions) => UndoControls;
|
|
1624
|
+
|
|
1625
|
+
export declare const useUndoLog: (apiName: string, options?: {
|
|
1626
|
+
readonly limit?: number;
|
|
1627
|
+
}) => UndoController;
|
|
1628
|
+
|
|
1629
|
+
export declare interface UseUndoOptions {
|
|
1630
|
+
/** Apply the inverse of an invocation server-side (a synthesized mutation). */
|
|
1631
|
+
readonly onUndo: (invocationId: string) => Promise<void> | void;
|
|
1632
|
+
/** Replay an invocation forward server-side. */
|
|
1633
|
+
readonly onRedo: (invocationId: string) => Promise<void> | void;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Reactive file upload for a mounted api's storage. Provider-agnostic
|
|
1638
|
+
* (filesystem/dev, s3/r2/prod) and cross-origin-safe. See the file header.
|
|
1639
|
+
*/
|
|
1640
|
+
export declare const useUpload: (apiName: string, hookOpts?: UploadOptions) => UploadHandle;
|
|
1641
|
+
|
|
1642
|
+
export declare const useWindowedSubscription: <Row = Record<string, unknown>>(apiName: string, queryTag: string, options: UseWindowedSubscriptionOptions) => WindowedSubscriptionState<Row>;
|
|
1643
|
+
|
|
1644
|
+
export declare interface UseWindowedSubscriptionOptions {
|
|
1645
|
+
readonly rowHeight: number;
|
|
1646
|
+
/** Visible viewport height in px. */
|
|
1647
|
+
readonly viewportHeight: number;
|
|
1648
|
+
/** Extra rows fetched above/below the viewport (smoother scroll). Default 5. */
|
|
1649
|
+
readonly overscan?: number;
|
|
1650
|
+
/** Total row count, if known — enables an accurate scrollbar. */
|
|
1651
|
+
readonly total?: number;
|
|
1652
|
+
/** Extra query input merged with `{ offset, limit }`. */
|
|
1653
|
+
readonly input?: Readonly<Record<string, unknown>>;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
export declare const useWorkflow: <Payload = unknown, Messages extends WorkflowClientMessages = WorkflowClientMessages>(apiName: string, workflowName: string) => WorkflowState<Payload, Messages>;
|
|
1657
|
+
|
|
1658
|
+
export declare const useWorkflowDomainEvents: (apiName: string, filters?: {
|
|
1659
|
+
readonly name?: string;
|
|
1660
|
+
readonly limit?: number;
|
|
1661
|
+
}, options?: SubscriptionOptions) => WorkflowDomainEventsState;
|
|
1662
|
+
|
|
1663
|
+
export declare const useWorkflowEventDeliveries: (apiName: string, eventId: string | undefined) => WorkflowEventDeliveriesState;
|
|
1664
|
+
|
|
1665
|
+
export declare const useWorkflowEvents: (apiName: string, runId: string | undefined) => WorkflowRunEventsState;
|
|
1666
|
+
|
|
1667
|
+
export declare const useWorkflowRun: (apiName: string, id: string | undefined) => WorkflowRunState;
|
|
1668
|
+
|
|
1669
|
+
export declare const useWorkflowRunEvents: (apiName: string, runId: string | undefined) => WorkflowRunEventsState;
|
|
1670
|
+
|
|
1671
|
+
export declare const useWorkflowRuns: (apiName: string, filters?: WorkflowRunsFilter, options?: SubscriptionOptions) => WorkflowRunsState;
|
|
1672
|
+
|
|
1673
|
+
export declare const useWorkflowRunState: (apiName: string, id: string | undefined) => WorkflowRunStateValue;
|
|
1674
|
+
|
|
1675
|
+
export declare const useWorkflowRunSteps: (apiName: string, runId: string | undefined) => WorkflowRunStepsState;
|
|
1676
|
+
|
|
1677
|
+
export declare const useWorkflowSignal: (apiName: string) => WorkflowSignalState;
|
|
1678
|
+
|
|
1679
|
+
export declare const useWorkflowUpdate: (apiName: string) => WorkflowUpdateState;
|
|
1680
|
+
|
|
1681
|
+
/** Validate a payload against an event descriptor's Schema. Pure. */
|
|
1682
|
+
export declare const validateEventPayload: (descriptor: EventDescriptor<string, unknown>, payload: unknown) => EventValidation;
|
|
1683
|
+
|
|
1684
|
+
/**
|
|
1685
|
+
* Validate `values` against an input `schema`, returning the first error per
|
|
1686
|
+
* top-level field (`{ [field]: message }`) — the shape `<AutoForm>` and custom
|
|
1687
|
+
* widgets render inline. Uses the same `decodeUnknownEither` + `ArrayFormatter`
|
|
1688
|
+
* path the store's `.validate(...)` uses, so client and server speak ONE
|
|
1689
|
+
* schema. `{ errors: 'all' }` collects every field's error in one pass.
|
|
1690
|
+
*
|
|
1691
|
+
* Client-side validation is non-authoritative UX — the server re-validates the
|
|
1692
|
+
* same schema on the mutation; this just gives instant inline feedback.
|
|
1693
|
+
*/
|
|
1694
|
+
export declare const validateFields: (schema: Schema.Schema.Any, values: unknown) => ValidationResult;
|
|
1695
|
+
|
|
1696
|
+
export declare interface ValidationResult {
|
|
1697
|
+
readonly valid: boolean;
|
|
1698
|
+
readonly errors: FieldErrors;
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
export declare type ValidationStatus = 'idle' | 'checking' | 'valid' | 'invalid';
|
|
1702
|
+
|
|
1703
|
+
/** Pure state machine: empty → idle; still settling or query in flight →
|
|
1704
|
+
* checking; otherwise the interpreted verdict. Tested directly so the
|
|
1705
|
+
* async/debounce wiring around it stays thin. */
|
|
1706
|
+
export declare const validationStatus: (args: {
|
|
1707
|
+
readonly value: string;
|
|
1708
|
+
readonly debouncedValue: string;
|
|
1709
|
+
/** Subscription result; `undefined` = in flight. */
|
|
1710
|
+
readonly data: unknown;
|
|
1711
|
+
readonly interpret: (data: unknown) => {
|
|
1712
|
+
readonly valid: boolean;
|
|
1713
|
+
readonly message?: string;
|
|
1714
|
+
};
|
|
1715
|
+
/** Empty value is `idle` (default true). */
|
|
1716
|
+
readonly skipEmpty?: boolean;
|
|
1717
|
+
}) => AsyncValidationResult;
|
|
1718
|
+
|
|
1719
|
+
/** The default widget kinds the framework can render from a schema. `'custom'`
|
|
1720
|
+
* means "no default widget" — the field needs a render-prop (a nested object,
|
|
1721
|
+
* an array of objects, or a multi-branch union). Mirrors innovation/01's set. */
|
|
1722
|
+
export declare type WidgetKind = 'text' | 'textarea' | 'number' | 'checkbox' | 'switch' | 'select' | 'radio' | 'async-select' | 'multi-select' | 'date' | 'datetime' | 'daterange' | 'file' | 'hidden' | 'custom';
|
|
1723
|
+
|
|
1724
|
+
export declare interface WindowedSubscriptionState<Row> {
|
|
1725
|
+
/** The in-window rows (live). */
|
|
1726
|
+
readonly rows: ReadonlyArray<Row>;
|
|
1727
|
+
readonly window: WindowSpec;
|
|
1728
|
+
/** Wire to the scroll container's `onScroll`. */
|
|
1729
|
+
readonly onScroll: (e: UIEvent_2<HTMLElement>) => void;
|
|
1730
|
+
readonly topSpacer: number;
|
|
1731
|
+
readonly bottomSpacer: number;
|
|
1732
|
+
readonly loading: boolean;
|
|
1733
|
+
readonly error: unknown | undefined;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
export declare interface WindowSpec {
|
|
1737
|
+
/** First row index in the window (incl. overscan). */
|
|
1738
|
+
readonly startIndex: number;
|
|
1739
|
+
/** Exclusive end index of the window. */
|
|
1740
|
+
readonly endIndex: number;
|
|
1741
|
+
/** Query offset = startIndex. */
|
|
1742
|
+
readonly offset: number;
|
|
1743
|
+
/** Query limit = window size. */
|
|
1744
|
+
readonly limit: number;
|
|
1745
|
+
/** Pixel height of the rows ABOVE the window (scrollbar fidelity). */
|
|
1746
|
+
readonly topSpacer: number;
|
|
1747
|
+
/** Pixel height of the rows BELOW the window (0 when total unknown). */
|
|
1748
|
+
readonly bottomSpacer: number;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
export declare interface WorkflowClientMessages {
|
|
1752
|
+
readonly signals?: Readonly<Record<string, unknown>>;
|
|
1753
|
+
readonly updates?: Readonly<Record<string, {
|
|
1754
|
+
readonly payload: unknown;
|
|
1755
|
+
readonly result: unknown;
|
|
1756
|
+
}>>;
|
|
1757
|
+
readonly queries?: Readonly<Record<string, {
|
|
1758
|
+
readonly payload: unknown;
|
|
1759
|
+
readonly result: unknown;
|
|
1760
|
+
}>>;
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
export declare interface WorkflowDomainEventsState extends SubscriptionState<ReadonlyArray<WorkflowDomainEventRow>> {
|
|
1764
|
+
readonly events: ReadonlyArray<WorkflowDomainEventRow>;
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
export declare interface WorkflowEventDeliveriesState extends SubscriptionState<ReadonlyArray<WorkflowEventDeliveryRow>> {
|
|
1768
|
+
readonly deliveries: ReadonlyArray<WorkflowEventDeliveryRow>;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
export declare interface WorkflowRunError {
|
|
1772
|
+
readonly tag: string | null;
|
|
1773
|
+
readonly message: string | null;
|
|
1774
|
+
/** The step that failed, if a step (vs the run body) carried the error. */
|
|
1775
|
+
readonly step: string | undefined;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
export { WorkflowRunEventRow }
|
|
1779
|
+
|
|
1780
|
+
export declare interface WorkflowRunEventsState extends SubscriptionState<ReadonlyArray<WorkflowRunEventRow>> {
|
|
1781
|
+
readonly events: ReadonlyArray<WorkflowRunEventRow>;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
export { WorkflowRunRow }
|
|
1785
|
+
|
|
1786
|
+
export declare interface WorkflowRunsFilter {
|
|
1787
|
+
readonly tag?: string;
|
|
1788
|
+
readonly status?: WorkflowRunStatus;
|
|
1789
|
+
readonly limit?: number;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
export declare interface WorkflowRunsState extends SubscriptionState<ReadonlyArray<WorkflowRunRow>> {
|
|
1793
|
+
readonly runs: ReadonlyArray<WorkflowRunRow>;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
export declare interface WorkflowRunState extends SubscriptionState<ReadonlyArray<WorkflowRunRow>> {
|
|
1797
|
+
readonly run: WorkflowRunRow | undefined;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
export declare interface WorkflowRunStateValue {
|
|
1801
|
+
readonly run: WorkflowRunRow | undefined;
|
|
1802
|
+
readonly status: WorkflowRunStatus | undefined;
|
|
1803
|
+
readonly steps: ReadonlyArray<WorkflowRunStepRow>;
|
|
1804
|
+
readonly events: ReadonlyArray<WorkflowRunEventRow>;
|
|
1805
|
+
/** The running step, else the most recently started one. */
|
|
1806
|
+
readonly currentStep: WorkflowRunStepRow | undefined;
|
|
1807
|
+
/** Present only while the run is parked on a signal/update wait. */
|
|
1808
|
+
readonly waitingFor: WorkflowWaitingFor | undefined;
|
|
1809
|
+
readonly error: WorkflowRunError | undefined;
|
|
1810
|
+
readonly traceId: string | null | undefined;
|
|
1811
|
+
readonly loading: boolean;
|
|
1812
|
+
readonly cancel: () => Promise<void>;
|
|
1813
|
+
readonly resume: () => Promise<void>;
|
|
1814
|
+
readonly signal: (signalName: string, payload?: unknown) => Promise<{
|
|
1815
|
+
readonly eventId: string;
|
|
1816
|
+
}>;
|
|
1817
|
+
readonly update: (updateName: string, payload?: unknown, options?: {
|
|
1818
|
+
readonly timeoutMs?: number;
|
|
1819
|
+
}) => Promise<WorkflowUpdateResult>;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
export { WorkflowRunStatus }
|
|
1823
|
+
|
|
1824
|
+
export { WorkflowRunStepRow }
|
|
1825
|
+
|
|
1826
|
+
export declare interface WorkflowRunStepsState extends SubscriptionState<ReadonlyArray<WorkflowRunStepRow>> {
|
|
1827
|
+
readonly steps: ReadonlyArray<WorkflowRunStepRow>;
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
export declare interface WorkflowSignalState {
|
|
1831
|
+
readonly signal: (run: Pick<WorkflowRunHandle, 'id'>, signalName: string, payload?: unknown) => Promise<{
|
|
1832
|
+
readonly eventId: string;
|
|
1833
|
+
}>;
|
|
1834
|
+
readonly pending: boolean;
|
|
1835
|
+
readonly error: unknown | undefined;
|
|
1836
|
+
readonly data: {
|
|
1837
|
+
readonly eventId: string;
|
|
1838
|
+
} | undefined;
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
export declare interface WorkflowState<Payload, Messages extends WorkflowClientMessages = WorkflowClientMessages> {
|
|
1842
|
+
readonly start: (payload: Payload) => Promise<WorkflowRunHandle>;
|
|
1843
|
+
readonly cancel: (run: Pick<WorkflowRunHandle, 'workflowName' | 'executionId'>) => Promise<void>;
|
|
1844
|
+
readonly resume: (run: Pick<WorkflowRunHandle, 'workflowName' | 'executionId'>) => Promise<void>;
|
|
1845
|
+
readonly signal: <Name extends string>(run: Pick<WorkflowRunHandle, 'id'>, signalName: Name, payload?: SignalPayload<Messages, Name>) => Promise<{
|
|
1846
|
+
readonly eventId: string;
|
|
1847
|
+
}>;
|
|
1848
|
+
readonly update: <Name extends string>(run: Pick<WorkflowRunHandle, 'id'>, updateName: Name, payload?: UpdatePayload<Messages, Name>, options?: {
|
|
1849
|
+
readonly timeoutMs?: number;
|
|
1850
|
+
}) => Promise<UpdateResult<Messages, Name>>;
|
|
1851
|
+
readonly pending: boolean;
|
|
1852
|
+
readonly error: unknown | undefined;
|
|
1853
|
+
readonly data: WorkflowRunHandle | undefined;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
export { WorkflowUpdateResult }
|
|
1857
|
+
|
|
1858
|
+
export declare interface WorkflowUpdateState {
|
|
1859
|
+
readonly update: (run: Pick<WorkflowRunHandle, 'id'>, updateName: string, payload?: unknown, options?: {
|
|
1860
|
+
readonly timeoutMs?: number;
|
|
1861
|
+
}) => Promise<WorkflowUpdateResult>;
|
|
1862
|
+
readonly pending: boolean;
|
|
1863
|
+
readonly error: unknown | undefined;
|
|
1864
|
+
readonly data: WorkflowUpdateResult | undefined;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
/** A workflow parked on `awaitSignal`/`awaitUpdate` — the name + which kind,
|
|
1868
|
+
* derived from the run-events handshake. Drives ApprovalControls visibility. */
|
|
1869
|
+
export declare interface WorkflowWaitingFor {
|
|
1870
|
+
readonly name: string;
|
|
1871
|
+
readonly kind: 'signal' | 'update';
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
/**
|
|
1875
|
+
* Return `props` with each callback the spec names wrapped so invoking it ALSO
|
|
1876
|
+
* fires its resolved event to `sink` (the original callback still runs).
|
|
1877
|
+
* Lifecycle keys (onMount/onUnmount) are skipped — those fire from effects.
|
|
1878
|
+
* Pure: returns a new props object, mutates nothing.
|
|
1879
|
+
*/
|
|
1880
|
+
export declare const wrapTrackedCallbacks: (spec: TrackingSpec, props: Record<string, unknown>, sink: TrackingSink) => Record<string, unknown>;
|
|
1881
|
+
|
|
1882
|
+
export { }
|