@lunora/client 1.0.0-alpha.10 → 1.0.0-alpha.12
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/auth/index.d.mts +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/index.d.mts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.mjs +4 -4
- package/dist/packem_shared/{LunoraClient-CgZ6FhKP.mjs → LunoraClient-wh6w9Ivn.mjs} +548 -40
- package/dist/packem_shared/SubscriptionRegistry-Cxr70og-.mjs +1 -0
- package/dist/packem_shared/{createInMemoryPersistence-CW82inU5.mjs → createInMemoryPersistence-DlFjWtOm.mjs} +13 -1
- package/dist/packem_shared/{createInMemoryQueryCache-B1PQ9Twl.mjs → createInMemoryQueryCache-4AkTV38-.mjs} +13 -1
- package/dist/packem_shared/{createServerClient-BxkNcRlR.mjs → createServerClient-C5GMCGSQ.mjs} +1 -1
- package/dist/packem_shared/{lunora-client.d-B5vWSgvD.d.mts → lunora-client.d-DTwbfUWF.d.mts} +121 -6
- package/dist/packem_shared/{lunora-client.d-B5vWSgvD.d.ts → lunora-client.d-DTwbfUWF.d.ts} +121 -6
- package/dist/packem_shared/{preload.d-3XJD-2hM.d.mts → preload.d-BEp0JJeu.d.mts} +1 -1
- package/dist/packem_shared/{preload.d-CKZR675M.d.ts → preload.d-CK2IYf5B.d.ts} +1 -1
- package/dist/packem_shared/{subscription-C1Jy7HiF.mjs → subscription-DoyO04-2.mjs} +10 -0
- package/dist/query/index.d.mts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/ssr/index.d.mts +3 -3
- package/dist/ssr/index.d.ts +3 -3
- package/dist/ssr/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/SubscriptionRegistry-Dn-7k7eo.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { S as SubscriptionRegistry } from './subscription-DoyO04-2.mjs';
|
|
@@ -101,5 +101,17 @@ const createIndexedDbPersistence = (options = {}) => {
|
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
103
|
};
|
|
104
|
+
const resolvePersistenceAdapter = (option, autoProbe = true) => {
|
|
105
|
+
if (option === false) {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
if (option) {
|
|
109
|
+
return option;
|
|
110
|
+
}
|
|
111
|
+
if (!autoProbe || typeof indexedDB === "undefined") {
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
return createIndexedDbPersistence();
|
|
115
|
+
};
|
|
104
116
|
|
|
105
|
-
export { createInMemoryPersistence, createIndexedDbPersistence };
|
|
117
|
+
export { createInMemoryPersistence, createIndexedDbPersistence, resolvePersistenceAdapter };
|
|
@@ -134,5 +134,17 @@ const createIndexedDbQueryCache = (options = {}) => {
|
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
136
|
};
|
|
137
|
+
const resolveQueryCacheAdapter = (option) => {
|
|
138
|
+
if (option === false) {
|
|
139
|
+
return void 0;
|
|
140
|
+
}
|
|
141
|
+
if (option) {
|
|
142
|
+
return option;
|
|
143
|
+
}
|
|
144
|
+
if (typeof indexedDB === "undefined") {
|
|
145
|
+
return void 0;
|
|
146
|
+
}
|
|
147
|
+
return createIndexedDbQueryCache();
|
|
148
|
+
};
|
|
137
149
|
|
|
138
|
-
export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey };
|
|
150
|
+
export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey, resolveQueryCacheAdapter };
|
package/dist/packem_shared/{lunora-client.d-B5vWSgvD.d.mts → lunora-client.d-DTwbfUWF.d.mts}
RENAMED
|
@@ -271,8 +271,16 @@ interface LunoraClientOptions {
|
|
|
271
271
|
* standalone client, which keeps using {@link LunoraClientOptions.persistence}.
|
|
272
272
|
*/
|
|
273
273
|
outbox?: OutboxSink;
|
|
274
|
-
/**
|
|
275
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Durable store for the offline mutation queue. Tri-state — an explicit
|
|
276
|
+
* {@link PersistenceAdapter} is used as-is; `false` opts out (the queue stays
|
|
277
|
+
* in memory, lost on reload); omitted (the default) auto-probes a durable
|
|
278
|
+
* IndexedDB store when the `indexedDB` global is present (browsers), otherwise
|
|
279
|
+
* in-memory, so SSR/Node/React-Native keep the in-memory behaviour and only
|
|
280
|
+
* environments that can persist do. Pass `createAsyncStoragePersistence()` on
|
|
281
|
+
* React Native.
|
|
282
|
+
*/
|
|
283
|
+
persistence?: false | PersistenceAdapter;
|
|
276
284
|
/**
|
|
277
285
|
* App/schema version stamped onto every persisted queued write and cached
|
|
278
286
|
* read. Bump it on a breaking change to a function signature or query shape:
|
|
@@ -289,11 +297,13 @@ interface LunoraClientOptions {
|
|
|
289
297
|
*/
|
|
290
298
|
persistenceVersion?: string;
|
|
291
299
|
/**
|
|
292
|
-
* Durable store for the read cache (Pillar 2). When
|
|
300
|
+
* Durable store for the read cache (Pillar 2). When active, query results
|
|
293
301
|
* are persisted as their subscriptions advance and hydrated on construction
|
|
294
302
|
* so a reload renders cached data before the socket reconnects, then resumes
|
|
295
|
-
* the live subscription from the persisted cursor.
|
|
296
|
-
*
|
|
303
|
+
* the live subscription from the persisted cursor. Tri-state — an explicit
|
|
304
|
+
* {@link QueryCacheAdapter} is used as-is; `false` opts out (reads stay in
|
|
305
|
+
* memory only); omitted (the default) auto-probes IndexedDB exactly like
|
|
306
|
+
* {@link LunoraClientOptions.persistence}.
|
|
297
307
|
*/
|
|
298
308
|
queryCache?: QueryCacheAdapter | false;
|
|
299
309
|
reconnect?: ReconnectOptions;
|
|
@@ -348,6 +358,7 @@ interface RpcEnvelope {
|
|
|
348
358
|
type RpcResponseBody = {
|
|
349
359
|
error: {
|
|
350
360
|
code: string;
|
|
361
|
+
data?: unknown;
|
|
351
362
|
message: string;
|
|
352
363
|
};
|
|
353
364
|
} | {
|
|
@@ -1141,6 +1152,19 @@ interface SyncWatermark {
|
|
|
1141
1152
|
checkpoint?: number;
|
|
1142
1153
|
mutationId?: number;
|
|
1143
1154
|
}
|
|
1155
|
+
/** An `Error` carrying the server's machine-readable `code` and (for a `LunoraError`) structured `data`. The client's public error contract for RPC/batch failures. */
|
|
1156
|
+
type LunoraClientError = Error & {
|
|
1157
|
+
code?: string;
|
|
1158
|
+
data?: unknown;
|
|
1159
|
+
};
|
|
1160
|
+
/** One demuxed result slot of a {@link LunoraClient.batch} call (plan 088). */
|
|
1161
|
+
type BatchSlot = {
|
|
1162
|
+
error: LunoraClientError;
|
|
1163
|
+
ok: false;
|
|
1164
|
+
} | {
|
|
1165
|
+
ok: true;
|
|
1166
|
+
value: unknown;
|
|
1167
|
+
};
|
|
1144
1168
|
/**
|
|
1145
1169
|
* Lunora browser/edge client. Talks RPC over HTTP and real-time deltas over
|
|
1146
1170
|
* a single multiplexed WebSocket.
|
|
@@ -1488,6 +1512,25 @@ declare class LunoraClient {
|
|
|
1488
1512
|
shardKey?: string;
|
|
1489
1513
|
}): Promise<ReturnOf<F>>;
|
|
1490
1514
|
/**
|
|
1515
|
+
* Batch several independent calls into ONE round trip (plan 088). Each call is
|
|
1516
|
+
* dispatched server-side exactly as an individual RPC — per-shard
|
|
1517
|
+
* authorization, `(identity, mutationId)` idempotency, and custom-mutator
|
|
1518
|
+
* watermark ordering are all preserved — and the worker splits the batch by
|
|
1519
|
+
* shard so calls to different shards fan out to their own DOs. Results are
|
|
1520
|
+
* demuxed back in input order; a failing call does NOT fail the batch (its
|
|
1521
|
+
* slot carries `{ ok: false, error }`, with `.code`/`.data` reconstructed like
|
|
1522
|
+
* a single call). Args/results ride the value codec (bytes/bigint survive).
|
|
1523
|
+
*
|
|
1524
|
+
* No promise pipelining and no capability passing — a call's args cannot
|
|
1525
|
+
* reference another call's result (see plan 088 §fence; capabilities are
|
|
1526
|
+
* incompatible with DO hibernation).
|
|
1527
|
+
*/
|
|
1528
|
+
batch(calls: ReadonlyArray<{
|
|
1529
|
+
args?: Record<string, unknown>;
|
|
1530
|
+
fn: FunctionReference;
|
|
1531
|
+
shardKey?: string;
|
|
1532
|
+
}>): Promise<BatchSlot[]>;
|
|
1533
|
+
/**
|
|
1491
1534
|
* Invoke a mutation. Errors propagate as rejections.
|
|
1492
1535
|
*
|
|
1493
1536
|
* Offline-queue semantics: a mutation is queued (and replayed on reconnect)
|
|
@@ -2192,5 +2235,77 @@ declare class LunoraClient {
|
|
|
2192
2235
|
*/
|
|
2193
2236
|
private clearQueryCacheForIdentityChange;
|
|
2194
2237
|
private flushOfflineQueue;
|
|
2238
|
+
/**
|
|
2239
|
+
* Partition already-gated writes into the encodable ones (returned) and reject
|
|
2240
|
+
* the rest terminally. A write whose args can't be wire-encoded (e.g. a RegExp
|
|
2241
|
+
* or class instance in a `v.any()` field) can NEVER replay — the codec failure
|
|
2242
|
+
* is deterministic, not transient. Rejecting here is essential: otherwise
|
|
2243
|
+
* `encodeWire` throws mid-flush, is classified as transient (a codec error has
|
|
2244
|
+
* no `.code`), and re-queues forever — a silent hang where the caller's Promise
|
|
2245
|
+
* never settles and the optimistic write never rolls back. Encoding is cheap;
|
|
2246
|
+
* the flush is the slow reconnect path.
|
|
2247
|
+
*/
|
|
2248
|
+
private encodableOrSettleTerminal;
|
|
2249
|
+
/**
|
|
2250
|
+
* Identity guard for one queued write about to replay: a write stamped under
|
|
2251
|
+
* one identity must never replay under another. The live `queuedIdentities`
|
|
2252
|
+
* map is the source of truth for the current session; a hydrated write whose
|
|
2253
|
+
* id isn't in the map falls back to the stamp persisted with the record
|
|
2254
|
+
* (`item.identity`), so a reload can't replay another user's queued writes.
|
|
2255
|
+
* Only legacy records (persisted before stamps were durable —
|
|
2256
|
+
* `item.identity === undefined`) replay under whatever identity is current.
|
|
2257
|
+
*
|
|
2258
|
+
* `Map.get` returns `undefined` for unstamped/hydrated ids and `item.identity`
|
|
2259
|
+
* is `undefined` for legacy records; a persisted `null` (queued while signed
|
|
2260
|
+
* out) is a real value that must not collapse into `undefined` — hence the
|
|
2261
|
+
* explicit `=== undefined` check rather than `??`. Returns `true` when the
|
|
2262
|
+
* write may replay; otherwise settles it `OFFLINE_IDENTITY_CHANGED` and returns
|
|
2263
|
+
* `false`. Either way the live stamp is consumed.
|
|
2264
|
+
*/
|
|
2265
|
+
private passesReplayIdentityGate;
|
|
2266
|
+
/** Settle a write that replayed successfully: confirm its optimistic layer against the echoed commit cursor BEFORE resolving, so the gapless drop is in place when the awaiter (and any confirming frame) observes the settle. */
|
|
2267
|
+
private settleReplaySuccess;
|
|
2268
|
+
/** Settle a write the server reached a coded verdict on: replaying would re-trigger the same failure (a poison-message loop), so drop it. */
|
|
2269
|
+
private settleReplayTerminal;
|
|
2270
|
+
/**
|
|
2271
|
+
* Replay already-identity-gated writes one at a time on the single-call `/rpc`
|
|
2272
|
+
* path, preserving FIFO order (parallel `.then()` chains would race the
|
|
2273
|
+
* ordering callers depend on). Each replays under its stable `mutationId` so
|
|
2274
|
+
* the server dedups a write it already committed (exactly-once). A coded error
|
|
2275
|
+
* is a server verdict (drop it); a codeless (transport/transient) failure stops
|
|
2276
|
+
* the flush and re-queues this write and every unreplayed one for the next
|
|
2277
|
+
* reconnect — their callers stay pending, and the identity guard re-applies on
|
|
2278
|
+
* retry via each record's persisted stamp.
|
|
2279
|
+
*/
|
|
2280
|
+
private replaySequential;
|
|
2281
|
+
/**
|
|
2282
|
+
* Coalesce already-identity-gated writes for a single shard into ONE
|
|
2283
|
+
* `/_lunora/rpc-batch` round trip (plan 088 follow-on). The worker forwards
|
|
2284
|
+
* them to the shard DO, which replays each through its single-call dispatch, so
|
|
2285
|
+
* per-entry `mutationId` idempotency and in-order application are inherited from
|
|
2286
|
+
* the proven path. Per-slot demux mirrors {@link replaySequential}'s
|
|
2287
|
+
* classification: success confirms the optimistic layer against the echoed
|
|
2288
|
+
* `commitCursor`; a coded application verdict is terminal; a transient shard
|
|
2289
|
+
* failure (`SHARD_UNAVAILABLE`/`SHARD_ERROR`), a missing slot, or a whole-batch
|
|
2290
|
+
* transport failure re-queues for the next reconnect (never dropping a durable
|
|
2291
|
+
* write). A whole-batch coded rejection (bad request / authorization denial the
|
|
2292
|
+
* server reached a verdict on) is terminal for every entry.
|
|
2293
|
+
*
|
|
2294
|
+
* Returns the writes that must be re-queued and `stop` — `true` when the whole
|
|
2295
|
+
* chunk failed at the transport level, so the caller leaves later chunks queued
|
|
2296
|
+
* rather than sending on. The caller re-queues once, in order, so requeuing is
|
|
2297
|
+
* NOT done here.
|
|
2298
|
+
*/
|
|
2299
|
+
private replayBatched;
|
|
2300
|
+
/**
|
|
2301
|
+
* Demux a `/_lunora/rpc-batch` reply back onto the queued writes it replayed,
|
|
2302
|
+
* in input order. Each slot's envelope classifies its write the same way
|
|
2303
|
+
* {@link replaySequential} does: a success confirms the optimistic layer
|
|
2304
|
+
* against the echoed `commitCursor`; a coded application verdict is terminal;
|
|
2305
|
+
* a transient shard failure ({@link TRANSIENT_BATCH_ERROR_CODES}) or a slot the
|
|
2306
|
+
* server never returned is returned for the caller to re-queue.
|
|
2307
|
+
* @returns the writes that must be re-queued (transient slots), in input order
|
|
2308
|
+
*/
|
|
2309
|
+
private settleReplayBatchSlots;
|
|
2195
2310
|
}
|
|
2196
|
-
export {
|
|
2311
|
+
export { SubscriptionCallback as $, ArgsOf as A, BookmarkStorage as B, CachedQuery as C, DEFAULT_MAX_BUFFER as D, ScheduleRecord as E, FunctionReference as F, GlobalFacetResult as G, SchedulerPoolStatus as H, SchedulerStatus as I, ServerMessage as J, ServerPokeEndMessage as K, LunoraClient as L, MutationCallOptions as M, ServerPokePartMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeStartMessage as T, User as U, ShardTrafficEntry as V, ShardTrafficResult as W, StorageListPage as X, StorageObject as Y, StreamHandle as Z, StreamIterable as _, Unsubscribe as a, SubscriptionRegistry as a0, SubscriptionState as a1, SyncWatermark as a2, WorkflowInstanceAction as a3, WorkflowInstanceDetail as a4, WorkflowInstancePage as a5, WorkflowInstanceStatus as a6, WorkflowInstanceSummary as a7, WorkflowStepDetail as a8, createLocalStore as a9, createStream as aa, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, ClientMessage as f, ClientShapeSubscribeMessage as g, ClientShapeUnsubscribeMessage as h, ConnectionStatus as i, FunctionArgumentDescriptor as j, FunctionDescriptor as k, GlobalFacetValue as l, GlobalFilterClause as m, GlobalTableInfo as n, GlobalTablePage as o, LunoraClientError as p, LunoraClientOptions as q, MutationSettledEvent as r, OptimisticLocalStore as s, OptimisticUpdate as t, OutboxMutation as u, OutboxSink as v, PersistedMutation as w, RowOp as x, RpcEnvelope as y, RpcResponseBody as z };
|
|
@@ -271,8 +271,16 @@ interface LunoraClientOptions {
|
|
|
271
271
|
* standalone client, which keeps using {@link LunoraClientOptions.persistence}.
|
|
272
272
|
*/
|
|
273
273
|
outbox?: OutboxSink;
|
|
274
|
-
/**
|
|
275
|
-
|
|
274
|
+
/**
|
|
275
|
+
* Durable store for the offline mutation queue. Tri-state — an explicit
|
|
276
|
+
* {@link PersistenceAdapter} is used as-is; `false` opts out (the queue stays
|
|
277
|
+
* in memory, lost on reload); omitted (the default) auto-probes a durable
|
|
278
|
+
* IndexedDB store when the `indexedDB` global is present (browsers), otherwise
|
|
279
|
+
* in-memory, so SSR/Node/React-Native keep the in-memory behaviour and only
|
|
280
|
+
* environments that can persist do. Pass `createAsyncStoragePersistence()` on
|
|
281
|
+
* React Native.
|
|
282
|
+
*/
|
|
283
|
+
persistence?: false | PersistenceAdapter;
|
|
276
284
|
/**
|
|
277
285
|
* App/schema version stamped onto every persisted queued write and cached
|
|
278
286
|
* read. Bump it on a breaking change to a function signature or query shape:
|
|
@@ -289,11 +297,13 @@ interface LunoraClientOptions {
|
|
|
289
297
|
*/
|
|
290
298
|
persistenceVersion?: string;
|
|
291
299
|
/**
|
|
292
|
-
* Durable store for the read cache (Pillar 2). When
|
|
300
|
+
* Durable store for the read cache (Pillar 2). When active, query results
|
|
293
301
|
* are persisted as their subscriptions advance and hydrated on construction
|
|
294
302
|
* so a reload renders cached data before the socket reconnects, then resumes
|
|
295
|
-
* the live subscription from the persisted cursor.
|
|
296
|
-
*
|
|
303
|
+
* the live subscription from the persisted cursor. Tri-state — an explicit
|
|
304
|
+
* {@link QueryCacheAdapter} is used as-is; `false` opts out (reads stay in
|
|
305
|
+
* memory only); omitted (the default) auto-probes IndexedDB exactly like
|
|
306
|
+
* {@link LunoraClientOptions.persistence}.
|
|
297
307
|
*/
|
|
298
308
|
queryCache?: QueryCacheAdapter | false;
|
|
299
309
|
reconnect?: ReconnectOptions;
|
|
@@ -348,6 +358,7 @@ interface RpcEnvelope {
|
|
|
348
358
|
type RpcResponseBody = {
|
|
349
359
|
error: {
|
|
350
360
|
code: string;
|
|
361
|
+
data?: unknown;
|
|
351
362
|
message: string;
|
|
352
363
|
};
|
|
353
364
|
} | {
|
|
@@ -1141,6 +1152,19 @@ interface SyncWatermark {
|
|
|
1141
1152
|
checkpoint?: number;
|
|
1142
1153
|
mutationId?: number;
|
|
1143
1154
|
}
|
|
1155
|
+
/** An `Error` carrying the server's machine-readable `code` and (for a `LunoraError`) structured `data`. The client's public error contract for RPC/batch failures. */
|
|
1156
|
+
type LunoraClientError = Error & {
|
|
1157
|
+
code?: string;
|
|
1158
|
+
data?: unknown;
|
|
1159
|
+
};
|
|
1160
|
+
/** One demuxed result slot of a {@link LunoraClient.batch} call (plan 088). */
|
|
1161
|
+
type BatchSlot = {
|
|
1162
|
+
error: LunoraClientError;
|
|
1163
|
+
ok: false;
|
|
1164
|
+
} | {
|
|
1165
|
+
ok: true;
|
|
1166
|
+
value: unknown;
|
|
1167
|
+
};
|
|
1144
1168
|
/**
|
|
1145
1169
|
* Lunora browser/edge client. Talks RPC over HTTP and real-time deltas over
|
|
1146
1170
|
* a single multiplexed WebSocket.
|
|
@@ -1488,6 +1512,25 @@ declare class LunoraClient {
|
|
|
1488
1512
|
shardKey?: string;
|
|
1489
1513
|
}): Promise<ReturnOf<F>>;
|
|
1490
1514
|
/**
|
|
1515
|
+
* Batch several independent calls into ONE round trip (plan 088). Each call is
|
|
1516
|
+
* dispatched server-side exactly as an individual RPC — per-shard
|
|
1517
|
+
* authorization, `(identity, mutationId)` idempotency, and custom-mutator
|
|
1518
|
+
* watermark ordering are all preserved — and the worker splits the batch by
|
|
1519
|
+
* shard so calls to different shards fan out to their own DOs. Results are
|
|
1520
|
+
* demuxed back in input order; a failing call does NOT fail the batch (its
|
|
1521
|
+
* slot carries `{ ok: false, error }`, with `.code`/`.data` reconstructed like
|
|
1522
|
+
* a single call). Args/results ride the value codec (bytes/bigint survive).
|
|
1523
|
+
*
|
|
1524
|
+
* No promise pipelining and no capability passing — a call's args cannot
|
|
1525
|
+
* reference another call's result (see plan 088 §fence; capabilities are
|
|
1526
|
+
* incompatible with DO hibernation).
|
|
1527
|
+
*/
|
|
1528
|
+
batch(calls: ReadonlyArray<{
|
|
1529
|
+
args?: Record<string, unknown>;
|
|
1530
|
+
fn: FunctionReference;
|
|
1531
|
+
shardKey?: string;
|
|
1532
|
+
}>): Promise<BatchSlot[]>;
|
|
1533
|
+
/**
|
|
1491
1534
|
* Invoke a mutation. Errors propagate as rejections.
|
|
1492
1535
|
*
|
|
1493
1536
|
* Offline-queue semantics: a mutation is queued (and replayed on reconnect)
|
|
@@ -2192,5 +2235,77 @@ declare class LunoraClient {
|
|
|
2192
2235
|
*/
|
|
2193
2236
|
private clearQueryCacheForIdentityChange;
|
|
2194
2237
|
private flushOfflineQueue;
|
|
2238
|
+
/**
|
|
2239
|
+
* Partition already-gated writes into the encodable ones (returned) and reject
|
|
2240
|
+
* the rest terminally. A write whose args can't be wire-encoded (e.g. a RegExp
|
|
2241
|
+
* or class instance in a `v.any()` field) can NEVER replay — the codec failure
|
|
2242
|
+
* is deterministic, not transient. Rejecting here is essential: otherwise
|
|
2243
|
+
* `encodeWire` throws mid-flush, is classified as transient (a codec error has
|
|
2244
|
+
* no `.code`), and re-queues forever — a silent hang where the caller's Promise
|
|
2245
|
+
* never settles and the optimistic write never rolls back. Encoding is cheap;
|
|
2246
|
+
* the flush is the slow reconnect path.
|
|
2247
|
+
*/
|
|
2248
|
+
private encodableOrSettleTerminal;
|
|
2249
|
+
/**
|
|
2250
|
+
* Identity guard for one queued write about to replay: a write stamped under
|
|
2251
|
+
* one identity must never replay under another. The live `queuedIdentities`
|
|
2252
|
+
* map is the source of truth for the current session; a hydrated write whose
|
|
2253
|
+
* id isn't in the map falls back to the stamp persisted with the record
|
|
2254
|
+
* (`item.identity`), so a reload can't replay another user's queued writes.
|
|
2255
|
+
* Only legacy records (persisted before stamps were durable —
|
|
2256
|
+
* `item.identity === undefined`) replay under whatever identity is current.
|
|
2257
|
+
*
|
|
2258
|
+
* `Map.get` returns `undefined` for unstamped/hydrated ids and `item.identity`
|
|
2259
|
+
* is `undefined` for legacy records; a persisted `null` (queued while signed
|
|
2260
|
+
* out) is a real value that must not collapse into `undefined` — hence the
|
|
2261
|
+
* explicit `=== undefined` check rather than `??`. Returns `true` when the
|
|
2262
|
+
* write may replay; otherwise settles it `OFFLINE_IDENTITY_CHANGED` and returns
|
|
2263
|
+
* `false`. Either way the live stamp is consumed.
|
|
2264
|
+
*/
|
|
2265
|
+
private passesReplayIdentityGate;
|
|
2266
|
+
/** Settle a write that replayed successfully: confirm its optimistic layer against the echoed commit cursor BEFORE resolving, so the gapless drop is in place when the awaiter (and any confirming frame) observes the settle. */
|
|
2267
|
+
private settleReplaySuccess;
|
|
2268
|
+
/** Settle a write the server reached a coded verdict on: replaying would re-trigger the same failure (a poison-message loop), so drop it. */
|
|
2269
|
+
private settleReplayTerminal;
|
|
2270
|
+
/**
|
|
2271
|
+
* Replay already-identity-gated writes one at a time on the single-call `/rpc`
|
|
2272
|
+
* path, preserving FIFO order (parallel `.then()` chains would race the
|
|
2273
|
+
* ordering callers depend on). Each replays under its stable `mutationId` so
|
|
2274
|
+
* the server dedups a write it already committed (exactly-once). A coded error
|
|
2275
|
+
* is a server verdict (drop it); a codeless (transport/transient) failure stops
|
|
2276
|
+
* the flush and re-queues this write and every unreplayed one for the next
|
|
2277
|
+
* reconnect — their callers stay pending, and the identity guard re-applies on
|
|
2278
|
+
* retry via each record's persisted stamp.
|
|
2279
|
+
*/
|
|
2280
|
+
private replaySequential;
|
|
2281
|
+
/**
|
|
2282
|
+
* Coalesce already-identity-gated writes for a single shard into ONE
|
|
2283
|
+
* `/_lunora/rpc-batch` round trip (plan 088 follow-on). The worker forwards
|
|
2284
|
+
* them to the shard DO, which replays each through its single-call dispatch, so
|
|
2285
|
+
* per-entry `mutationId` idempotency and in-order application are inherited from
|
|
2286
|
+
* the proven path. Per-slot demux mirrors {@link replaySequential}'s
|
|
2287
|
+
* classification: success confirms the optimistic layer against the echoed
|
|
2288
|
+
* `commitCursor`; a coded application verdict is terminal; a transient shard
|
|
2289
|
+
* failure (`SHARD_UNAVAILABLE`/`SHARD_ERROR`), a missing slot, or a whole-batch
|
|
2290
|
+
* transport failure re-queues for the next reconnect (never dropping a durable
|
|
2291
|
+
* write). A whole-batch coded rejection (bad request / authorization denial the
|
|
2292
|
+
* server reached a verdict on) is terminal for every entry.
|
|
2293
|
+
*
|
|
2294
|
+
* Returns the writes that must be re-queued and `stop` — `true` when the whole
|
|
2295
|
+
* chunk failed at the transport level, so the caller leaves later chunks queued
|
|
2296
|
+
* rather than sending on. The caller re-queues once, in order, so requeuing is
|
|
2297
|
+
* NOT done here.
|
|
2298
|
+
*/
|
|
2299
|
+
private replayBatched;
|
|
2300
|
+
/**
|
|
2301
|
+
* Demux a `/_lunora/rpc-batch` reply back onto the queued writes it replayed,
|
|
2302
|
+
* in input order. Each slot's envelope classifies its write the same way
|
|
2303
|
+
* {@link replaySequential} does: a success confirms the optimistic layer
|
|
2304
|
+
* against the echoed `commitCursor`; a coded application verdict is terminal;
|
|
2305
|
+
* a transient shard failure ({@link TRANSIENT_BATCH_ERROR_CODES}) or a slot the
|
|
2306
|
+
* server never returned is returned for the caller to re-queue.
|
|
2307
|
+
* @returns the writes that must be re-queued (transient slots), in input order
|
|
2308
|
+
*/
|
|
2309
|
+
private settleReplayBatchSlots;
|
|
2195
2310
|
}
|
|
2196
|
-
export {
|
|
2311
|
+
export { SubscriptionCallback as $, ArgsOf as A, BookmarkStorage as B, CachedQuery as C, DEFAULT_MAX_BUFFER as D, ScheduleRecord as E, FunctionReference as F, GlobalFacetResult as G, SchedulerPoolStatus as H, SchedulerStatus as I, ServerMessage as J, ServerPokeEndMessage as K, LunoraClient as L, MutationCallOptions as M, ServerPokePartMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeStartMessage as T, User as U, ShardTrafficEntry as V, ShardTrafficResult as W, StorageListPage as X, StorageObject as Y, StreamHandle as Z, StreamIterable as _, Unsubscribe as a, SubscriptionRegistry as a0, SubscriptionState as a1, SyncWatermark as a2, WorkflowInstanceAction as a3, WorkflowInstanceDetail as a4, WorkflowInstancePage as a5, WorkflowInstanceStatus as a6, WorkflowInstanceSummary as a7, WorkflowStepDetail as a8, createLocalStore as a9, createStream as aa, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, ClientMessage as f, ClientShapeSubscribeMessage as g, ClientShapeUnsubscribeMessage as h, ConnectionStatus as i, FunctionArgumentDescriptor as j, FunctionDescriptor as k, GlobalFacetValue as l, GlobalFilterClause as m, GlobalTableInfo as n, GlobalTablePage as o, LunoraClientError as p, LunoraClientOptions as q, MutationSettledEvent as r, OptimisticLocalStore as s, OptimisticUpdate as t, OutboxMutation as u, OutboxSink as v, PersistedMutation as w, RowOp as x, RpcEnvelope as y, RpcResponseBody as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-
|
|
1
|
+
import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DTwbfUWF.mjs";
|
|
2
2
|
/**
|
|
3
3
|
* Run a query once on the server (during SSR) and capture its result in a
|
|
4
4
|
* serializable {@link Preloaded} token. Embed the token in the rendered HTML and
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-
|
|
1
|
+
import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DTwbfUWF.js";
|
|
2
2
|
/**
|
|
3
3
|
* Run a query once on the server (during SSR) and capture its result in a
|
|
4
4
|
* serializable {@link Preloaded} token. Embed the token in the rendered HTML and
|
|
@@ -8,12 +8,22 @@ const stableStringify = (value) => {
|
|
|
8
8
|
if (value === void 0) {
|
|
9
9
|
return "null";
|
|
10
10
|
}
|
|
11
|
+
if (typeof value === "bigint") {
|
|
12
|
+
throw new TypeError("stableStringify: cannot use a bigint in a cache key (query/subscription/shape args) — pass it as a string");
|
|
13
|
+
}
|
|
11
14
|
if (value === null || typeof value !== "object") {
|
|
12
15
|
return JSON.stringify(value);
|
|
13
16
|
}
|
|
14
17
|
if (Array.isArray(value)) {
|
|
15
18
|
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
|
16
19
|
}
|
|
20
|
+
const proto = Object.getPrototypeOf(value);
|
|
21
|
+
if (proto !== null && proto !== Object.prototype) {
|
|
22
|
+
const name = value.constructor?.name ?? "value";
|
|
23
|
+
throw new TypeError(
|
|
24
|
+
`stableStringify: cannot use a ${name} in a cache key (query/subscription/shape args) — only plain objects, arrays, and JSON primitives are supported`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
17
27
|
const record = value;
|
|
18
28
|
const keys = Object.keys(record).toSorted(compareKeys);
|
|
19
29
|
const parts = [];
|
package/dist/query/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-
|
|
2
|
-
export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DTwbfUWF.mjs";
|
|
2
|
+
export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DTwbfUWF.mjs";
|
|
3
3
|
import '@lunora/runtime';
|
|
4
4
|
/**
|
|
5
5
|
* The sentinel a framework adapter resolves its reactive args to when it wants
|
package/dist/query/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-
|
|
2
|
-
export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DTwbfUWF.js";
|
|
2
|
+
export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DTwbfUWF.js";
|
|
3
3
|
import '@lunora/runtime';
|
|
4
4
|
/**
|
|
5
5
|
* The sentinel a framework adapter resolves its reactive args to when it wants
|
package/dist/ssr/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
2
|
-
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-
|
|
3
|
-
export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-
|
|
1
|
+
import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DTwbfUWF.mjs";
|
|
2
|
+
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DTwbfUWF.mjs";
|
|
3
|
+
export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-BEp0JJeu.mjs";
|
|
4
4
|
import '@lunora/runtime';
|
|
5
5
|
/**
|
|
6
6
|
* Structural shape of a better-auth `getSession` call's resolved value.
|
package/dist/ssr/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
2
|
-
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-
|
|
3
|
-
export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-
|
|
1
|
+
import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DTwbfUWF.js";
|
|
2
|
+
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DTwbfUWF.js";
|
|
3
|
+
export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-CK2IYf5B.js";
|
|
4
4
|
import '@lunora/runtime';
|
|
5
5
|
/**
|
|
6
6
|
* Structural shape of a better-auth `getSession` call's resolved value.
|
package/dist/ssr/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { getServerSession } from '../packem_shared/getServerSession-8jXewqxd.mjs';
|
|
2
2
|
export { deserializePreloaded, serializePreloaded } from '../packem_shared/deserializePreloaded-C0eJTY_W.mjs';
|
|
3
|
-
export { createServerClient } from '../packem_shared/createServerClient-
|
|
3
|
+
export { createServerClient } from '../packem_shared/createServerClient-C5GMCGSQ.mjs';
|
|
4
4
|
export { preloadQuery, preloadedQueryResult } from '../packem_shared/preloadQuery-lobFkD2Z.mjs';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { S as SubscriptionRegistry } from './subscription-C1Jy7HiF.mjs';
|