@voltro/client 0.28.0 → 0.30.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 +655 -0
- package/dist/index.d.ts +117 -7
- package/dist/index.js +512 -460
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ import { EventDescriptor as EventDescriptor_2 } from '@voltro/protocol';
|
|
|
7
7
|
import { Fiber } from 'effect';
|
|
8
8
|
import { ManagedRuntime } from 'effect';
|
|
9
9
|
import { ReactNode } from 'react';
|
|
10
|
+
import { Rpc } from '@effect/rpc';
|
|
11
|
+
import { RpcClient } from '@effect/rpc';
|
|
12
|
+
import { RpcClientError } from '@effect/rpc';
|
|
13
|
+
import { RpcGroup } from '@effect/rpc';
|
|
10
14
|
import { Schema } from 'effect';
|
|
11
15
|
import { Stream } from 'effect';
|
|
12
16
|
import { SubscriptionEvent } from '@voltro/protocol';
|
|
@@ -175,6 +179,13 @@ export declare interface ApiHandle {
|
|
|
175
179
|
readonly errorBus: RpcErrorBus;
|
|
176
180
|
}
|
|
177
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Apply preload seeds from the hydration payload, BEFORE the first client
|
|
184
|
+
* render. Idempotent (a Map upsert) so a re-hydration or a repeated key is
|
|
185
|
+
* harmless — last write wins, matching the store-seed rule.
|
|
186
|
+
*/
|
|
187
|
+
export declare const applyPreloadSeeds: (seeds: ReadonlyArray<PreloadSeed> | undefined) => void;
|
|
188
|
+
|
|
178
189
|
/**
|
|
179
190
|
* Apply seeds from the hydration payload, BEFORE the first client render.
|
|
180
191
|
*
|
|
@@ -226,6 +237,43 @@ export declare interface AutoApplyTarget {
|
|
|
226
237
|
readonly shapeItem?: ((input: Record<string, unknown>, currentOrOptimisticId: unknown) => Record<string, unknown>) | undefined;
|
|
227
238
|
}
|
|
228
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Build one api's runtime + rpc client + subscription cache over a WebSocket.
|
|
242
|
+
*
|
|
243
|
+
* The returned `runtime` owns the socket; dispose it (`runtime.dispose()`, after
|
|
244
|
+
* `cache.destroy(runtime)`) to tear the connection down. A fresh cache is bound
|
|
245
|
+
* per resolved runtime — cross-runtime cache reuse is unsafe (its fibers
|
|
246
|
+
* reference the old runtime).
|
|
247
|
+
*
|
|
248
|
+
* Rejects if the runtime fails to resolve the client (e.g. the socket never
|
|
249
|
+
* opens); the caller's reconnect logic decides what to do with that.
|
|
250
|
+
*/
|
|
251
|
+
export declare const buildApiRuntime: (options: BuildApiRuntimeOptions) => Promise<BuiltApiRuntime>;
|
|
252
|
+
|
|
253
|
+
export declare interface BuildApiRuntimeOptions {
|
|
254
|
+
/** Stable api name — used only to tag the client's Context. */
|
|
255
|
+
readonly name: string;
|
|
256
|
+
/** WebSocket URL of the api (`ws(s)://host:port/ws`). */
|
|
257
|
+
readonly wsUrl: string;
|
|
258
|
+
/** The api's rpc group (its typed procedure surface). */
|
|
259
|
+
readonly group: RpcGroup.RpcGroup<Rpc.Any>;
|
|
260
|
+
/** Per-connection auth headers (see {@link ResolvableHeaders}). */
|
|
261
|
+
readonly headers?: ResolvableHeaders | undefined;
|
|
262
|
+
/** How to construct a WebSocket. Web wraps `globalThis.WebSocket` with
|
|
263
|
+
* tracking + a connect-timeout; RN passes a plain `globalThis.WebSocket`.
|
|
264
|
+
* Injected so this module touches no environment global directly. */
|
|
265
|
+
readonly webSocketConstructor: (url: string, protocols?: string | ReadonlyArray<string>) => globalThis.WebSocket;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** The transport-level pieces of one api's client stack. Combined with the
|
|
269
|
+
* api's descriptor map + inspect base URL, this is an `ApiHandle`. */
|
|
270
|
+
export declare interface BuiltApiRuntime {
|
|
271
|
+
readonly runtime: AnyRuntime;
|
|
272
|
+
readonly cache: SubscriptionCache;
|
|
273
|
+
readonly client: RpcClient.RpcClient<Rpc.Any, RpcClientError.RpcClientError>;
|
|
274
|
+
readonly errorBus: RpcErrorBus;
|
|
275
|
+
}
|
|
276
|
+
|
|
229
277
|
declare interface CacheEntry {
|
|
230
278
|
readonly key: string;
|
|
231
279
|
/** First element of the keyArr — the rpc tag (e.g. 'todos.list'). Used
|
|
@@ -820,6 +868,8 @@ export declare class LoadingSubscriptionCache extends SubscriptionCache {
|
|
|
820
868
|
};
|
|
821
869
|
}
|
|
822
870
|
|
|
871
|
+
export declare const makePreloadSeedBag: () => PreloadSeedBag;
|
|
872
|
+
|
|
823
873
|
export declare const makeStoreSeedBag: () => StoreSeedBag;
|
|
824
874
|
|
|
825
875
|
/** Exported for tests: the inspect URL this hook fetches. */
|
|
@@ -1000,6 +1050,27 @@ export declare interface PersistOptions<S> {
|
|
|
1000
1050
|
readonly migrate?: (stored: unknown) => Partial<S> | undefined;
|
|
1001
1051
|
}
|
|
1002
1052
|
|
|
1053
|
+
/** Options `usePreloadedSubscription` accepts. It OWNS `initialSnapshot` (the
|
|
1054
|
+
* preload payload supplies it), so callers pass only `skip` — `fallback` and
|
|
1055
|
+
* `initialSnapshot` are its own concern. */
|
|
1056
|
+
export declare type PreloadedSubscriptionOptions = Pick<SubscriptionOptions<never>, 'skip'>;
|
|
1057
|
+
|
|
1058
|
+
/** One preloaded subscription snapshot, as it travels in the hydration payload. */
|
|
1059
|
+
export declare interface PreloadSeed {
|
|
1060
|
+
/** The api mount name the subscription reads from (first arg of `useSubscription`). */
|
|
1061
|
+
readonly api: string;
|
|
1062
|
+
/** `stableKey([rpcTag, input])` — identical to the SubscriptionCache's own key,
|
|
1063
|
+
* so the seed and the live subscription address the same entry. */
|
|
1064
|
+
readonly key: string;
|
|
1065
|
+
/** The server-fetched snapshot value. */
|
|
1066
|
+
readonly value: unknown;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
/** Collects preload seeds for ONE request. The server creates one per render. */
|
|
1070
|
+
export declare interface PreloadSeedBag {
|
|
1071
|
+
readonly seeds: PreloadSeed[];
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1003
1074
|
/** Structural mirror of @voltro/runtime's PreviewDiff (client stays decoupled). */
|
|
1004
1075
|
export declare interface PreviewDiff {
|
|
1005
1076
|
readonly rows: ReadonlyArray<PreviewRowDiff>;
|
|
@@ -1089,6 +1160,17 @@ export declare interface QueryFiltersState<Row> {
|
|
|
1089
1160
|
readonly error: unknown | undefined;
|
|
1090
1161
|
}
|
|
1091
1162
|
|
|
1163
|
+
/**
|
|
1164
|
+
* The preloaded snapshot for `(api, rpcTag, input)`, or `undefined` when none was
|
|
1165
|
+
* seeded. On the SERVER it reads the current request's bag directly, so the SSR
|
|
1166
|
+
* markup and the client hydration render see the SAME value (no hydration
|
|
1167
|
+
* flicker); on the CLIENT it reads the hydration-applied registry.
|
|
1168
|
+
*
|
|
1169
|
+
* A seed value is never `undefined` (it round-trips through JSON, so the worst
|
|
1170
|
+
* case is `null`), which is why `undefined` unambiguously means "not seeded".
|
|
1171
|
+
*/
|
|
1172
|
+
export declare const readPreloadedSnapshot: (api: string, rpcTag: string, input: Readonly<Record<string, unknown>>) => unknown;
|
|
1173
|
+
|
|
1092
1174
|
export declare interface RecordState<R> {
|
|
1093
1175
|
readonly record: R | undefined;
|
|
1094
1176
|
readonly loading: boolean;
|
|
@@ -1112,9 +1194,17 @@ export declare const reportClientError: (error: unknown, context?: Record<string
|
|
|
1112
1194
|
* module-global flags + any pending grace-period timer). */
|
|
1113
1195
|
export declare const _resetFrameworkRuntimesWarning: () => void;
|
|
1114
1196
|
|
|
1197
|
+
/** Drop all applied client-side seeds. Tests only. */
|
|
1198
|
+
export declare const resetPreloadSeeds: () => void;
|
|
1199
|
+
|
|
1115
1200
|
/** Test helper: forget every defined store. NEVER call this in app code. */
|
|
1116
1201
|
export declare const resetStoreRegistryForTests: () => void;
|
|
1117
1202
|
|
|
1203
|
+
/** Auth headers to attach to every rpc MESSAGE frame, resolved on EVERY
|
|
1204
|
+
* (re)connect so a rotating token (a `() => Promise<…>` thunk) is fetched anew
|
|
1205
|
+
* each connection rather than frozen at first build. */
|
|
1206
|
+
export declare type ResolvableHeaders = Readonly<Record<string, string>> | (() => Readonly<Record<string, string>> | Promise<Readonly<Record<string, string>>>);
|
|
1207
|
+
|
|
1118
1208
|
export declare const resolveByTag: (client: unknown, tag: string) => unknown;
|
|
1119
1209
|
|
|
1120
1210
|
/** Resolve one map entry against the props. Pure. */
|
|
@@ -1282,6 +1372,14 @@ export declare const schemaToColumns: (schema: Schema.Schema.Any) => ReadonlyArr
|
|
|
1282
1372
|
*/
|
|
1283
1373
|
export declare const schemaToFields: (schema: Schema.Schema.Any) => ReadonlyArray<FieldDescriptor>;
|
|
1284
1374
|
|
|
1375
|
+
/**
|
|
1376
|
+
* Seed a subscription's first value for THIS request's hydration. Call it on the
|
|
1377
|
+
* server during a render — a loader, a layout loader — with the value a
|
|
1378
|
+
* `ctx.query` already fetched, and `usePreloadedSubscription(api, rpcTag, input)`
|
|
1379
|
+
* shows it at the first paint without any serialization step of your own.
|
|
1380
|
+
*/
|
|
1381
|
+
export declare const seedPreloadedSubscription: (api: string, rpcTag: string, input: Readonly<Record<string, unknown>>, value: unknown) => void;
|
|
1382
|
+
|
|
1285
1383
|
/**
|
|
1286
1384
|
* Seed a store for THIS request's hydration. Call it anywhere on the server
|
|
1287
1385
|
* during a render — a loader, a layout loader — and the value reaches the
|
|
@@ -1351,6 +1449,12 @@ export declare type SequenceResult<Ctx> = {
|
|
|
1351
1449
|
* at boot, next to your toast provider. */
|
|
1352
1450
|
export declare const setMutationNotifier: (notifier: MutationNotifier | undefined) => void;
|
|
1353
1451
|
|
|
1452
|
+
/**
|
|
1453
|
+
* Install the request-scoped bag resolver. Server-side only; pass `null` to
|
|
1454
|
+
* uninstall (tests). `@voltro/web/ssr` registers it, backed by its own ALS.
|
|
1455
|
+
*/
|
|
1456
|
+
export declare const setPreloadSeedResolver: (resolver: (() => PreloadSeedBag | null) | null) => void;
|
|
1457
|
+
|
|
1354
1458
|
/**
|
|
1355
1459
|
* Install the request-scoped bag resolver. Server-side only; pass `null` to
|
|
1356
1460
|
* uninstall (tests).
|
|
@@ -2134,13 +2238,6 @@ export declare interface UploadResult {
|
|
|
2134
2238
|
|
|
2135
2239
|
export declare type UploadStatus = 'idle' | 'uploading' | 'success' | 'error';
|
|
2136
2240
|
|
|
2137
|
-
/**
|
|
2138
|
-
* Invoke a server `defineAction` procedure by tag. Unlike `useMutation`,
|
|
2139
|
-
* an action has no optimistic / cache surface — it's a unary call whose
|
|
2140
|
-
* effects (sends, captures, side-effecting writes the framework must NOT
|
|
2141
|
-
* preview locally) only become visible when the server pushes a delta on
|
|
2142
|
-
* an independent subscription.
|
|
2143
|
-
*/
|
|
2144
2241
|
export declare const useAction: <Input = unknown, Output = unknown>(apiName: string, rpcTag: string) => ActionState<Input, Output>;
|
|
2145
2242
|
|
|
2146
2243
|
export declare const useAgent: (apiName: string, rpcTag: string) => AgentControls;
|
|
@@ -2332,6 +2429,19 @@ export declare interface UseOutboxOptions {
|
|
|
2332
2429
|
/** The current subject's scopes (defaults to none if no provider). */
|
|
2333
2430
|
export declare const usePermissions: () => PermissionState_2;
|
|
2334
2431
|
|
|
2432
|
+
/**
|
|
2433
|
+
* Subscribe to a streaming rpc, seeding the first value from the SSR preload
|
|
2434
|
+
* payload when one exists.
|
|
2435
|
+
*
|
|
2436
|
+
* @param apiName The api mount name (as in `useSubscription`).
|
|
2437
|
+
* @param rpcTag The rpc tag (e.g. `'projects.list'`).
|
|
2438
|
+
* @param input The rpc payload; part of the preload lookup key AND the
|
|
2439
|
+
* subscription's cache key (identical `stableKey`).
|
|
2440
|
+
* @param options `{ skip }` — defers the subscription. `initialSnapshot`
|
|
2441
|
+
* comes from the preload payload, not from here.
|
|
2442
|
+
*/
|
|
2443
|
+
export declare function usePreloadedSubscription<T = unknown>(apiName: string, rpcTag: string, input?: Readonly<Record<string, unknown>>, options?: PreloadedSubscriptionOptions): SubscriptionState<T> | SubscriptionIdle;
|
|
2444
|
+
|
|
2335
2445
|
export declare const usePreview: <Input = Record<string, unknown>>(apiName: string, previewTag: string) => PreviewState<Input>;
|
|
2336
2446
|
|
|
2337
2447
|
export declare const useProvenance: (apiName: string, table: string, id: string, column?: string) => ProvenanceState;
|