@helipod/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/dist/chunk-DW55SNHW.js +286 -0
- package/dist/chunk-DW55SNHW.js.map +1 -0
- package/dist/chunk-I7ZJFW4E.js +2232 -0
- package/dist/chunk-I7ZJFW4E.js.map +1 -0
- package/dist/client-mJZjEkhK.d.ts +1144 -0
- package/dist/index.d.ts +268 -0
- package/dist/index.js +642 -0
- package/dist/index.js.map +1 -0
- package/dist/outbox-fs.d.ts +102 -0
- package/dist/outbox-fs.js +361 -0
- package/dist/outbox-fs.js.map +1 -0
- package/dist/outbox-storage-C6VHkXs9.d.ts +191 -0
- package/dist/react.d.ts +114 -0
- package/dist/react.js +139 -0
- package/dist/react.js.map +1 -0
- package/package.json +72 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { P as PendingMutation, a as PoisonPolicy, O as OutboxLockManager, C as ClientTransport } from './client-mJZjEkhK.js';
|
|
2
|
+
export { A as AUTH_REFRESH_UDF_PATH, b as AnyFunctionRef, c as AnyFunctionReference, d as ClientResetInfo, D as DEFAULT_DRAIN_CHUNK_SIZE, e as DEFAULT_DRAIN_INTERVAL_MS, f as DrainHost, F as FunctionArgs, g as FunctionReference, h as FunctionReturnType, H as HelipodClient, L as LoopbackLike, M as MutationFailedInfo, N as NON_REPLAYABLE_MUTATION_DROPPED, i as OFFLINE_IDENTITY_CHANGED, j as OptimisticLocalStore, k as OptimisticStoreView, l as OptimisticUpdate, m as OptimisticUpdateFn, n as OutboxBroadcastLike, o as OutboxBroadcastMessage, p as OutboxDrain, q as OutboxDrainOptions, r as PendingMutationEntry, s as PendingSummary, Q as QueryErrorListener, t as QueryListener, R as RefArgs, u as RefReturn, W as WebSocketTransportOptions, v as anyApi, w as computeDrainBackoff, x as createOptimisticLocalStore, y as getFunctionPath, z as loopbackTransport, B as reconnectDelayMs, E as webSocketTransport } from './client-mJZjEkhK.js';
|
|
3
|
+
import { O as OutboxEntry, a as OutboxStorage } from './outbox-storage-C6VHkXs9.js';
|
|
4
|
+
export { D as DEFAULT_OUTBOX_MAX_QUEUE_SIZE, H as HydrateResult, I as IndexedDBOutboxOptions, b as OfflineClientResetError, c as OutboxEntryError, d as OutboxEntryStatus, e as OutboxMeta, f as OutboxOverflowError, g as defaultMintClientId, i as indexedDBOutbox, m as memoryOutbox, h as mintIdentity } from './outbox-storage-C6VHkXs9.js';
|
|
5
|
+
import { ClientMutationRef, ClientMessage } from '@helipod/sync';
|
|
6
|
+
export { mintEncodedDocumentId as mintDocumentId } from '@helipod/id-codec';
|
|
7
|
+
import '@helipod/values';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The IndexedDB-backed `OutboxStorage` (verdict §(d) decision 8, `docs/dev/research/offline-outbox/
|
|
11
|
+
* verdict.md`). ONE database, `helipod-outbox` — the whole seam (the shared mutation queue AND
|
|
12
|
+
* per-clientId identity) lives together so an origin eviction takes BOTH atomically. That is
|
|
13
|
+
* verdict §(g) hazard 1 ("whole-origin eviction... co-evict — one database") pinned structurally:
|
|
14
|
+
* there is no separate identity store to fall out of sync with the queue, because there is only
|
|
15
|
+
* one store to begin with.
|
|
16
|
+
*
|
|
17
|
+
* Schema (v1):
|
|
18
|
+
* - `entries` — keyPath `["clientId", "seq"]` (the durable identity pair, verdict §(b)'s governing
|
|
19
|
+
* invariant: `(clientId, seq) -> payload` written exactly once); index `order`
|
|
20
|
+
* (drain FIFO across the WHOLE shared queue, every clientId); index `status`
|
|
21
|
+
* (candidate scans — e.g. everything still `unsent`/`inflight` — consumed from a
|
|
22
|
+
* later task onward).
|
|
23
|
+
* - `meta` — keyPath `"clientId"`; one row per clientId, `{clientId, nextSeq, deployment}`.
|
|
24
|
+
*
|
|
25
|
+
* Write-behind: every mutating call (`append`/`updateStatus`/`dequeue`/`setMeta`) enqueues a
|
|
26
|
+
* pending op and schedules (once) a microtask flush that opens ONE `readwrite` transaction across
|
|
27
|
+
* both stores and applies every op queued since the last flush, in call order. Callers that fire
|
|
28
|
+
* several appends synchronously in the same microtask turn get ONE transaction, not N.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** Bump when the persisted entry shape changes incompatibly. A hydrate that finds an entry
|
|
32
|
+
* stamped with a different version DROPS it (verdict §(g) hazard 10) — never runs it, never
|
|
33
|
+
* guesses a migration. */
|
|
34
|
+
declare const OUTBOX_VERSION = 1;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* S4 — `DeliveryPolicy`. Routes transport lifecycle events (v1: only *close*) into log
|
|
38
|
+
* transitions. The v1 policy is verdict §(c) event 6 verbatim: at close, NO optimistic layer of
|
|
39
|
+
* any kind survives into a new session (the ts-gate is only sound over a feed whose ts is
|
|
40
|
+
* monotone for THIS client, and a reconnect's resubscribe baseline arrives with the fresh
|
|
41
|
+
* session's ts — carrying a completed layer across would replay it on top of its own echo).
|
|
42
|
+
*
|
|
43
|
+
* - `unsent` → **retained** (never hit the wire; safe to (re)send on reconnect — T6).
|
|
44
|
+
* - `inflight` → the promise **rejects** with `MutationUndeliveredError` and its layer **drops**
|
|
45
|
+
* (outcome genuinely unknowable — no server dedup exists; a blind resend would
|
|
46
|
+
* double-apply) — UNLESS the S4 swap is `armed` AND this entry's durable append
|
|
47
|
+
* has already committed, in which case it **parks** instead (Task 2): the promise
|
|
48
|
+
* stays PENDING (a future drain resolves it under its recorded `(clientId, seq)`),
|
|
49
|
+
* while its layer still drops (the no-layer-crosses-a-session rule is unchanged).
|
|
50
|
+
* - `completed`→ already resolved at `MutationResponse` (D3); its layer **drops** too.
|
|
51
|
+
* - `parked` → already parked by an earlier close, with no drain yet built to resend it
|
|
52
|
+
* (T2's honest boundary — T4 owns the drain): left exactly as is.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Rejection for a mutation whose outcome is unknowable because the transport dropped before its
|
|
57
|
+
* `MutationResponse` arrived. Typed so apps can distinguish "the server rejected this" (a plain
|
|
58
|
+
* `Error` from the handler) from "we never learned what happened" (retry is unsafe — there is no
|
|
59
|
+
* server-side dedup yet). The message deliberately contains "connection closed".
|
|
60
|
+
*/
|
|
61
|
+
declare class MutationUndeliveredError extends Error {
|
|
62
|
+
constructor(message?: string);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Shared identity-fingerprint primitives for the durable outbox (verdict §(d) hazard 9 / spec
|
|
67
|
+
* §(k)7). `client.ts`'s live `setAuth`/`setSessionFingerprint` and `headless-drain.ts`'s one-shot
|
|
68
|
+
* `drainOutboxOnce` must compute the EXACT SAME `identityFingerprint` for the same underlying
|
|
69
|
+
* identity, or the two never agree — a durable entry stamped by a live tab under a managed
|
|
70
|
+
* session's `sessionFingerprintKey` hash would otherwise look "foreign" to the headless drain's own
|
|
71
|
+
* differently-formatted hash and terminal-fail with `OFFLINE_IDENTITY_CHANGED` even though nothing
|
|
72
|
+
* about the identity actually changed. One shared module, not two hand-synced copies, is how that's
|
|
73
|
+
* kept impossible by construction.
|
|
74
|
+
*/
|
|
75
|
+
/** SHA-256 hex digest of `input`. */
|
|
76
|
+
declare function sha256Hex(input: string): Promise<string>;
|
|
77
|
+
/** The string a managed `createAuthClient` session's outbox fingerprint hashes (never the raw
|
|
78
|
+
* `sessionId` alone) — `client.ts#setSessionFingerprint` and `headless-drain.ts`'s `getSessionId`
|
|
79
|
+
* option both route through this ONE function so the "session:" prefix convention can never drift
|
|
80
|
+
* between the two call sites (spec decision 9). */
|
|
81
|
+
declare function sessionFingerprintKey(sessionId: string): string;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The `Connect` resume handshake's pure computation (verdict §(c) event 6, §(e)) — `held` (every
|
|
85
|
+
* durable `(clientId, seq)` still awaiting a verdict) and `ackedThrough` (the contiguous
|
|
86
|
+
* settled-prefix per clientId, for server-side retention pruning), plus the wire message itself.
|
|
87
|
+
*
|
|
88
|
+
* Extracted from `client.ts` (T3) so a SECOND caller with no `HelipodClient` can send the SAME
|
|
89
|
+
* handshake shape — the headless drain (`headless-drain.ts`, the Background Sync seam). A Service
|
|
90
|
+
* Worker has no live in-memory `MutationLog`, only the durable `OutboxStorage` rows, so
|
|
91
|
+
* {@link outboxHeldFromStore} computes `held` straight from those instead of a live
|
|
92
|
+
* `PendingMutation` log ({@link outboxHeldFromLog}, `HelipodClient`'s own source). Both feed the
|
|
93
|
+
* SAME {@link outboxAckedThrough}/{@link buildConnectMessage} — the wire shape is identical either
|
|
94
|
+
* way, only the source of `held` differs.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/** `held` from a LIVE `HelipodClient`'s in-memory log — every entry with a recorded `(clientId,
|
|
98
|
+
* seq)` whose status is still unsettled. */
|
|
99
|
+
declare function outboxHeldFromLog(entries: Iterable<PendingMutation>): ClientMutationRef[];
|
|
100
|
+
/** `held` from a store-only host (the headless drain — no live log, only persisted rows) — the same
|
|
101
|
+
* three statuses, read straight off the persisted `OutboxEntry.status` (identical strings, identical
|
|
102
|
+
* meaning, to the live `PendingMutation.status.type` above). */
|
|
103
|
+
declare function outboxHeldFromStore(entries: Iterable<OutboxEntry>): ClientMutationRef[];
|
|
104
|
+
/** The highest CONTIGUOUS settled-prefix seq per clientId (verdict §(c) Retention / spec decision
|
|
105
|
+
* 3). Under the FIFO one-unacked-chunk drain a seq can never settle past an unsettled earlier one,
|
|
106
|
+
* so for each clientId the settled prefix is exactly `(lowest still-held seq) - 1`; a clientId
|
|
107
|
+
* whose lowest held seq is 0 has acked nothing and is omitted. */
|
|
108
|
+
declare function outboxAckedThrough(held: ClientMutationRef[]): ClientMutationRef[];
|
|
109
|
+
/** Build the `Connect` resume handshake wire message. `sessionId` is a fresh per-connect id (the
|
|
110
|
+
* server routes the handshake by the transport-level session, so this field is only
|
|
111
|
+
* informational); `clientId` is likewise informational server-side — `handleConnect` classifies
|
|
112
|
+
* purely off each `held`/`ackedThrough` entry's OWN `clientId`/`seq` pair, never the top-level
|
|
113
|
+
* field — so a caller whose held set spans several prior tab-sessions' clientIds (the headless
|
|
114
|
+
* drain) can safely omit it. */
|
|
115
|
+
declare function buildConnectMessage(sessionId: string, clientId: string | undefined, held: ClientMutationRef[]): Extract<ClientMessage, {
|
|
116
|
+
type: "Connect";
|
|
117
|
+
}>;
|
|
118
|
+
|
|
119
|
+
interface HeadlessDrainOptions {
|
|
120
|
+
/** The ws(s) sync endpoint. Ignored when `_transport` is injected (tests). */
|
|
121
|
+
url: string;
|
|
122
|
+
/** Defaults to `indexedDBOutbox()` — IndexedDB exists in a Service Worker just as it does in a
|
|
123
|
+
* tab, so the SAME durable queue a live client wrote is readable here with no extra plumbing. */
|
|
124
|
+
outbox?: OutboxStorage;
|
|
125
|
+
/** Distinguishes the drain's Web Locks name per deployment, matching a live client's own
|
|
126
|
+
* `outboxDeployment` constructor option (`client.ts:320`'s naming) — MUST agree with whatever a
|
|
127
|
+
* live tab configured, or the two will never contend for the same lock. Defaults to `"default"`. */
|
|
128
|
+
deployment?: string;
|
|
129
|
+
/** SW-readable auth (the app owns SW-readable token storage — this function only documents the
|
|
130
|
+
* constraint, it does not build one). Replayed as `SetAuth` BEFORE `Connect`, exactly as a
|
|
131
|
+
* reconnecting `HelipodClient` replays its last-set token. */
|
|
132
|
+
getAuthToken?: () => Promise<string | null>;
|
|
133
|
+
/** For a `createAuthClient`-managed session (spec decision 9): resolve the PERSISTED
|
|
134
|
+
* `SessionInfo.sessionId` so this drain computes the outbox `identityFingerprint` the exact same
|
|
135
|
+
* way a live tab's `setSessionFingerprint` does (`sha256Hex(sessionFingerprintKey(sessionId))`,
|
|
136
|
+
* never a token hash) — otherwise every entry a managed session stamped looks "foreign" here and
|
|
137
|
+
* terminal-fails with `OFFLINE_IDENTITY_CHANGED` on every headless drain, composition the live
|
|
138
|
+
* client never hits. Read the SAME storage row the auth client persists to — by default
|
|
139
|
+
* `SESSION_STORAGE_KEY` (`"helipod.session"`, exported from `auth-client.ts`) in `localStorage`,
|
|
140
|
+
* or wherever a custom `SessionStorage`/`localStorageSession(key)` was configured to write it; a
|
|
141
|
+
* Service Worker reads it via `clients.matchAll()`-relayed message, a mirrored IndexedDB copy, or
|
|
142
|
+
* any other SW-reachable channel the app wires up — this function only documents the contract, it
|
|
143
|
+
* does not build the plumbing. When this resolves to a non-null id, it takes priority over
|
|
144
|
+
* `getAuthToken`'s token-hash fingerprint (which still governs `SetAuth` on the wire); omit it (or
|
|
145
|
+
* resolve `null`) for a client that never adopted a managed session — the token-hash fingerprint
|
|
146
|
+
* (or `"anon"`) applies exactly as before this option existed. */
|
|
147
|
+
getSessionId?: () => Promise<string | null>;
|
|
148
|
+
/** How a coded (terminal, server-recorded) failure is handled — `"skip"` (default: settle
|
|
149
|
+
* terminally and continue) or `"pause"` (halt the whole drain and surface via `onPause`).
|
|
150
|
+
*
|
|
151
|
+
* Prefer the default `"skip"` in headless contexts (a Service Worker's `sync` handler, a cron-like
|
|
152
|
+
* invocation, etc.) — there is no live UI here to observe an `onPause` callback and call `resume()`
|
|
153
|
+
* on the drain's behalf, so a paused drain just sits paused until some LATER invocation happens to
|
|
154
|
+
* clear it. Worse, `"pause"` combined with a below-floor `STALE_CLIENT` verdict can livelock: the
|
|
155
|
+
* reset path re-queues the stale entry (`revertActive`), the next invocation re-flushes it, the
|
|
156
|
+
* server replies `STALE_CLIENT` again, and the drain re-pauses on the SAME entry every single run
|
|
157
|
+
* — with nothing headless to break the cycle. `"skip"` settles it terminally (once) instead and
|
|
158
|
+
* moves on. */
|
|
159
|
+
poisonPolicy?: PoisonPolicy;
|
|
160
|
+
/** The whole-drain wall-clock budget — after this the socket is closed and the current counts are
|
|
161
|
+
* returned, whatever state the drain is in. Default 30 000ms. */
|
|
162
|
+
timeoutMs?: number;
|
|
163
|
+
/** The Web Locks manager — `undefined` probes the ambient `navigator.locks`, `null` forces
|
|
164
|
+
* single-tab (no contention check at all — ALWAYS drains), an object is used directly (tests
|
|
165
|
+
* inject a fake). Mirrors `OutboxDrainOptions.locks`. */
|
|
166
|
+
locks?: OutboxLockManager | null;
|
|
167
|
+
/** @internal test seam — inject a transport instead of opening a real WebSocket. Kept
|
|
168
|
+
* underscore-internal: not part of the documented public surface. */
|
|
169
|
+
_transport?: ClientTransport;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Drain the durable outbox once: connect, hand `Connect`+`MutationBatch` traffic to the SAME
|
|
173
|
+
* {@link OutboxDrain} state machine a live tab uses, and resolve once the queue is empty/terminal
|
|
174
|
+
* or `timeoutMs` elapses — whichever comes first. Safe to call from a Service Worker's `sync` event
|
|
175
|
+
* handler inside `event.waitUntil(...)`, or from any other script with no live `HelipodClient`.
|
|
176
|
+
*/
|
|
177
|
+
declare function drainOutboxOnce(opts: HeadlessDrainOptions): Promise<{
|
|
178
|
+
drained: number;
|
|
179
|
+
failed: number;
|
|
180
|
+
remaining: number;
|
|
181
|
+
}>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* `createAuthClient` — a thin token-lifecycle manager over a `HelipodClient` (auth slice A1).
|
|
185
|
+
* Sign-in flows stay ordinary app mutations; the app hands the mint result to `setSession`. From
|
|
186
|
+
* there this manages: persistence (default `localStorage`, memory fallback), applying the access
|
|
187
|
+
* token via `client.setAuth` + re-applying on reconnect (SetAuth replay handles the wire side),
|
|
188
|
+
* refresh scheduling at ~80% of the access TTL, a Web-Locks single-refresher, a BroadcastChannel
|
|
189
|
+
* pair broadcast to sibling tabs, `REFRESH_STALE` wait-for-broadcast, and terminal-clear +
|
|
190
|
+
* `onSignedOut` on `REFRESH_EXPIRED`/`REFRESH_REUSED`. The outbox fingerprint is switched to the
|
|
191
|
+
* stable `sessionId` while a session is managed (spec decision 9).
|
|
192
|
+
*
|
|
193
|
+
* Non-browser hosts fall back to in-process serialization (no Web Locks) and a no-op broadcast; two
|
|
194
|
+
* independent PROCESSES sharing one refresh token is documented as unsupported (spec decision 5).
|
|
195
|
+
*/
|
|
196
|
+
/** The persisted mint result — the raw pair + the stable ids the manager needs across a reload. */
|
|
197
|
+
interface SessionInfo {
|
|
198
|
+
token: string;
|
|
199
|
+
refreshToken: string;
|
|
200
|
+
sessionId: string;
|
|
201
|
+
userId: string;
|
|
202
|
+
/** Absolute wall-clock ms when the ACCESS token expires (mint `expiresAt`). Drives the 80% schedule. */
|
|
203
|
+
expiresAt: number;
|
|
204
|
+
}
|
|
205
|
+
/** The minimal `HelipodClient` surface `createAuthClient` needs (kept structural for testability).
|
|
206
|
+
* `mutation` deliberately returns `Promise<unknown>` (not a generic) so `HelipodClient`'s
|
|
207
|
+
* overloaded `mutation(...): Promise<Value>` is structurally assignable; call sites cast. */
|
|
208
|
+
interface AuthManagedClient {
|
|
209
|
+
setAuth(token: string | null): void;
|
|
210
|
+
setSessionFingerprint(sessionId: string | null): void;
|
|
211
|
+
/** `opts.transient` is threaded straight to `HelipodClient.mutation`'s own escape hatch — the
|
|
212
|
+
* refresh call below always passes `{ transient: true }` so a refresh mutation never durably
|
|
213
|
+
* enqueues, even when the app configured an `outbox` (see the file doc's outbox-fingerprint
|
|
214
|
+
* paragraph and `client.ts#mutation`'s doc for why replaying a refresh is never safe). */
|
|
215
|
+
mutation(ref: string, args?: Record<string, unknown>, opts?: {
|
|
216
|
+
transient?: boolean;
|
|
217
|
+
}): Promise<unknown>;
|
|
218
|
+
}
|
|
219
|
+
/** Pluggable synchronous session store (same shape idea as the outbox storage seam). */
|
|
220
|
+
interface SessionStorage {
|
|
221
|
+
load(): SessionInfo | null;
|
|
222
|
+
save(info: SessionInfo): void;
|
|
223
|
+
clear(): void;
|
|
224
|
+
}
|
|
225
|
+
/** A minimal single-refresher lock seam (a subset of the Web Locks API). Non-browser → in-process. */
|
|
226
|
+
interface RefreshLock {
|
|
227
|
+
run<T>(fn: () => Promise<T>): Promise<T>;
|
|
228
|
+
}
|
|
229
|
+
/** A minimal cross-tab broadcast seam over the new pair. */
|
|
230
|
+
interface PairBroadcast {
|
|
231
|
+
post(info: SessionInfo): void;
|
|
232
|
+
onMessage(cb: (info: SessionInfo) => void): void;
|
|
233
|
+
close(): void;
|
|
234
|
+
}
|
|
235
|
+
interface CreateAuthClientOptions {
|
|
236
|
+
storage?: SessionStorage;
|
|
237
|
+
lock?: RefreshLock;
|
|
238
|
+
broadcast?: PairBroadcast;
|
|
239
|
+
/** Injectable clock (tests). Defaults to `Date.now`. */
|
|
240
|
+
now?: () => number;
|
|
241
|
+
/** Refresh at this fraction of the access TTL (default 0.8). */
|
|
242
|
+
refreshAtFraction?: number;
|
|
243
|
+
/** Called when the session terminally ends (REFRESH_EXPIRED / REFRESH_REUSED, or clearSession). */
|
|
244
|
+
onSignedOut?: () => void;
|
|
245
|
+
/** Fixed function path for the refresh mutation (default "auth:refresh"). */
|
|
246
|
+
refreshPath?: string;
|
|
247
|
+
}
|
|
248
|
+
interface AuthClient {
|
|
249
|
+
setSession(info: SessionInfo): void;
|
|
250
|
+
clearSession(): void;
|
|
251
|
+
getSessionInfo(): SessionInfo | null;
|
|
252
|
+
close(): void;
|
|
253
|
+
}
|
|
254
|
+
/** The default `localStorage` key `localStorageSession()` persists under — a `SessionInfo` JSON
|
|
255
|
+
* blob, `.sessionId` being the field a headless host needs for `headless-drain.ts`'s `getSessionId`
|
|
256
|
+
* option (mirroring the SAME managed-session fingerprint a live tab's `setSessionFingerprint`
|
|
257
|
+
* computes). Exported so a Service Worker (which shares `localStorage`'s *origin* but typically not
|
|
258
|
+
* a synchronous API to it) or any other headless host can name the same storage row without
|
|
259
|
+
* hand-copying the string literal. A custom `storage`/key (via `localStorageSession(key)` or a
|
|
260
|
+
* fully custom `SessionStorage`) is, of course, this app's own convention to document instead. */
|
|
261
|
+
declare const SESSION_STORAGE_KEY = "helipod.session";
|
|
262
|
+
/** localStorage-backed store with an in-memory fallback wherever localStorage is unavailable/throws. */
|
|
263
|
+
declare function localStorageSession(key?: string): SessionStorage;
|
|
264
|
+
/** In-memory store — nothing survives a reload; the default fallback and a test seam. */
|
|
265
|
+
declare function memorySession(): SessionStorage;
|
|
266
|
+
declare function createAuthClient(client: AuthManagedClient, opts?: CreateAuthClientOptions): AuthClient;
|
|
267
|
+
|
|
268
|
+
export { type AuthClient, type AuthManagedClient, ClientTransport, type CreateAuthClientOptions, type HeadlessDrainOptions, MutationUndeliveredError, OUTBOX_VERSION, OutboxEntry, OutboxLockManager, OutboxStorage, type PairBroadcast, PoisonPolicy, type RefreshLock, SESSION_STORAGE_KEY, type SessionInfo, type SessionStorage, buildConnectMessage, createAuthClient, drainOutboxOnce, localStorageSession, memorySession, outboxAckedThrough, outboxHeldFromLog, outboxHeldFromStore, sessionFingerprintKey, sha256Hex };
|