@lunora/client 1.0.0-alpha.51 → 1.0.0-alpha.53
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 +54 -39
- package/dist/index.d.ts +54 -39
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/LunoraClient-Cgu6xN-X.mjs +1 -0
- package/dist/packem_shared/{SubscriptionRegistry-D5Xu-a39.mjs → SubscriptionRegistry-BF75d3VP.mjs} +1 -1
- package/dist/packem_shared/createCallRunner-Bwcrfh76.mjs +1 -0
- package/dist/packem_shared/createLocalStore-DwN-1uXg.mjs +1 -0
- package/dist/packem_shared/{createServerClient-BxPCzuUt.mjs → createServerClient-CNzt_8I6.mjs} +1 -1
- package/dist/packem_shared/createSnapshotPrecondition-_2YMNXlG.mjs +1 -0
- package/dist/packem_shared/{local-store-BD0RFD7A.mjs → local-store-Bb62Gev5.mjs} +1 -1
- package/dist/packem_shared/{lunora-client.d-K16SL8Tj.d.ts → lunora-client.d-DT9XhMHZ.d.ts} +35 -20
- package/dist/packem_shared/{lunora-client.d-BOmxvSrG.d.mts → lunora-client.d-Dkd6-fpN.d.mts} +35 -20
- package/dist/packem_shared/{preload.d-CM8-Mg2A.d.ts → preload.d-Ch-D-Pfo.d.ts} +1 -1
- package/dist/packem_shared/{preload.d-BprjXhJi.d.mts → preload.d-CxLsgsd8.d.mts} +1 -1
- package/dist/packem_shared/wire-key-HxFZXRbI.mjs +1 -0
- package/dist/query/index.d.mts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/ssr/index.d.mts +2 -2
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/LunoraClient-CWDiiVcr.mjs +0 -1
- package/dist/packem_shared/createLocalStore-C_UKH_Ok.mjs +0 -1
- package/dist/packem_shared/createMutationRunner-C0i1P5RS.mjs +0 -1
- package/dist/packem_shared/createSnapshotPrecondition-CP3e1HVS.mjs +0 -1
- package/dist/packem_shared/wire-key-BEmRM5ls.mjs +0 -1
package/dist/auth/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { L as LunoraClient } from "../packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
2
2
|
import { U as User } from "../packem_shared/types.d-CsuRAQvb.mjs";
|
|
3
3
|
import '@lunora/runtime';
|
|
4
4
|
interface IdentityStore {
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { L as LunoraClient } from "../packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
2
2
|
import { U as User } from "../packem_shared/types.d-CsuRAQvb.js";
|
|
3
3
|
import '@lunora/runtime';
|
|
4
4
|
interface IdentityStore {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { o as PersistenceAdapter, B as BookmarkStorage, H as HttpStreamRef, m as HttpStreamArgsOf, n as HttpStreamChunkOf,
|
|
2
|
-
export type { C as CachedQuery, q as ClientMessage, r as ClientShapeSubscribeMessage, s as ClientShapeUnsubscribeMessage, t as FunctionArgumentDescriptor, h as FunctionDescriptor, l as GlobalFacetResult, u as GlobalFacetValue, j as GlobalFilterClause, G as GlobalTableInfo, k as GlobalTablePage, v as HttpStreamCallArgs, L as LunoraClientOptions, w as OutboxMutation, x as OutboxSink, y as PersistedMutation, P as Preloaded, z as RowOp, D as RpcEnvelope, E as RpcResponseBody, b as ScheduleRecord, I as SchedulerPoolStatus, c as SchedulerStatus, J as ServerMessage, K as ServerPokeEndMessage, M as ServerPokePartMessage, N as ServerPokeStartMessage, T as ShardTrafficEntry, S as ShardTrafficResult, i as StorageListPage, V as StorageObject, a as Unsubscribe, U as User, g as WorkflowInstanceAction, f as WorkflowInstanceDetail, e as WorkflowInstancePage, d as WorkflowInstanceStatus, X as WorkflowInstanceSummary, Y as WorkflowStepDetail, W as WsTokenProvider } from "./packem_shared/types.d-CsuRAQvb.mjs";
|
|
3
|
-
import { C as ConnectionStatus, S as SubscriptionError, b as StreamIterable,
|
|
4
|
-
export { type B as BatchSlot, c as CONFLICT_ERROR_CODE, type d as ClientDebugShard, type e as ClientDebugSnapshot, type f as ClientDebugSubscription, type g as ClientQueryRef, D as DEFAULT_MAX_BUFFER, type h as LunoraClientError, type i as LunoraErrorCode, type j as MutationSettledEvent, type O as OptimisticLocalStore, type k as OptimisticUpdate, type l as StreamHandle, type m as SubscriptionCallback, type a as SubscriptionErrorCallback, n as SubscriptionRegistry, type o as SubscriptionState, type p as SyncWatermark, q as createClientQuery, r as createLocalStore, s as createStream, t as getErrorCode, u as getRetryAfterMs, v as isConflictError, w as isForbiddenError, x as isRateLimitedError, y as isUnauthorizedError } from "./packem_shared/lunora-client.d-
|
|
5
|
-
export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-
|
|
1
|
+
import { o as PersistenceAdapter, B as BookmarkStorage, H as HttpStreamRef, m as HttpStreamArgsOf, n as HttpStreamChunkOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, p as ReconnectOptions, F as FunctionReference } from "./packem_shared/types.d-CsuRAQvb.mjs";
|
|
2
|
+
export type { A as ArgsOf, C as CachedQuery, q as ClientMessage, r as ClientShapeSubscribeMessage, s as ClientShapeUnsubscribeMessage, t as FunctionArgumentDescriptor, h as FunctionDescriptor, l as GlobalFacetResult, u as GlobalFacetValue, j as GlobalFilterClause, G as GlobalTableInfo, k as GlobalTablePage, v as HttpStreamCallArgs, L as LunoraClientOptions, w as OutboxMutation, x as OutboxSink, y as PersistedMutation, P as Preloaded, R as ReturnOf, z as RowOp, D as RpcEnvelope, E as RpcResponseBody, b as ScheduleRecord, I as SchedulerPoolStatus, c as SchedulerStatus, J as ServerMessage, K as ServerPokeEndMessage, M as ServerPokePartMessage, N as ServerPokeStartMessage, T as ShardTrafficEntry, S as ShardTrafficResult, i as StorageListPage, V as StorageObject, a as Unsubscribe, U as User, g as WorkflowInstanceAction, f as WorkflowInstanceDetail, e as WorkflowInstancePage, d as WorkflowInstanceStatus, X as WorkflowInstanceSummary, Y as WorkflowStepDetail, W as WsTokenProvider } from "./packem_shared/types.d-CsuRAQvb.mjs";
|
|
3
|
+
import { C as ConnectionStatus, S as SubscriptionError, b as StreamIterable, L as LunoraClient } from "./packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
4
|
+
export { type A as ActionCallOptions, type B as BatchSlot, c as CONFLICT_ERROR_CODE, type d as ClientDebugShard, type e as ClientDebugSnapshot, type f as ClientDebugSubscription, type g as ClientQueryRef, D as DEFAULT_MAX_BUFFER, type h as LunoraClientError, type i as LunoraErrorCode, type M as MutationCallOptions, type j as MutationSettledEvent, type O as OptimisticLocalStore, type k as OptimisticUpdate, type l as StreamHandle, type m as SubscriptionCallback, type a as SubscriptionErrorCallback, n as SubscriptionRegistry, type o as SubscriptionState, type p as SyncWatermark, q as createClientQuery, r as createLocalStore, s as createStream, t as getErrorCode, u as getRetryAfterMs, v as isConflictError, w as isForbiddenError, x as isRateLimitedError, y as isUnauthorizedError } from "./packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
5
|
+
export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-CxLsgsd8.mjs";
|
|
6
6
|
export type { AuthCapabilities, AuthConfigInfo, AuthImpersonation, AuthPage, AuthSession, AuthUser, AuthUserFieldSpec, CronJobInfo, KvKeyEntry, KvKeyListResult, KvNamespaceSummary, KvValueResult, PipelineLogColumnMap, PipelineLogCursor, PipelineLogField, PipelineLogPage, PipelineLogQuery, PipelineLogRow, VectorIndexSummary, VectorQueryMatch } from '@lunora/runtime';
|
|
7
7
|
declare const anyApi: Record<string, Record<string, unknown>>;
|
|
8
8
|
/**
|
|
@@ -124,6 +124,47 @@ interface AsyncStoragePersistenceOptions {
|
|
|
124
124
|
declare const createAsyncStoragePersistence: (options: AsyncStoragePersistenceOptions) => PersistenceAdapter;
|
|
125
125
|
/** Default in-memory bookmark store. Survives the lifetime of the client. */
|
|
126
126
|
declare const createInMemoryBookmarkStorage: () => BookmarkStorage;
|
|
127
|
+
/**
|
|
128
|
+
* Reactive sinks an adapter binds to its own primitive's setters (a React
|
|
129
|
+
* `useState`, a Solid signal, a Vue ref, a Svelte store). The runner pushes into
|
|
130
|
+
* them; how they store the value is the adapter's concern (e.g. Solid and React
|
|
131
|
+
* wrap function-valued results in a thunk so the setter stores them rather than
|
|
132
|
+
* invoking them).
|
|
133
|
+
*/
|
|
134
|
+
interface CallRunnerSinks<R> {
|
|
135
|
+
/** Receives the normalized {@link Error} when the latest invocation rejects. */
|
|
136
|
+
setError: (error: Error) => void;
|
|
137
|
+
/** Receives `true` while at least one invocation is in flight (ref-counted across overlapping calls), else `false`. */
|
|
138
|
+
setPending: (pending: boolean) => void;
|
|
139
|
+
/** Receives the resolved value when the latest invocation succeeds. */
|
|
140
|
+
setResult: (result: R) => void;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Build the framework-neutral half of an adapter's write primitive — the `mutate`
|
|
144
|
+
* of `useMutation`/`createMutation`/`mutation`, and the `call` of
|
|
145
|
+
* `useAction`/`createAction`/`action`.
|
|
146
|
+
*
|
|
147
|
+
* It owns the orchestration every adapter otherwise copy-pastes: ref-counting
|
|
148
|
+
* overlapping invocations into `setPending` (so the flag clears only once the
|
|
149
|
+
* last settles), normalizing a thrown non-`Error`, and routing success/failure to
|
|
150
|
+
* `setResult`/`setError` before re-throwing the SAME instance (so a typed error's
|
|
151
|
+
* `.code`/`.data` survive for both the `catch` and the template).
|
|
152
|
+
*
|
|
153
|
+
* `invoke` is a pre-bound thunk — `(args, options) => client.mutation(fn, args, options)`
|
|
154
|
+
* or `(args, options) => client.action(fn, args, options)`. Binding at the call
|
|
155
|
+
* site is what keeps this one function: the runner never inspects `options`, it
|
|
156
|
+
* only forwards them, so the option type is inferred from the closure rather
|
|
157
|
+
* than hard-coded per procedure kind. What actually keeps `optimisticUpdate` off
|
|
158
|
+
* an action is the adapter's exported handle type, not this file.
|
|
159
|
+
*
|
|
160
|
+
* `data`/`error` track the LATEST invocation, not the last to settle: overlapping
|
|
161
|
+
* calls can resolve out of order, so an earlier call that finishes later must not
|
|
162
|
+
* clobber a newer call's outcome. Each invocation takes a monotonic token and
|
|
163
|
+
* writes the value sinks only while it is still the most recent one — otherwise a
|
|
164
|
+
* double-click could leave the UI showing the first click's result, or an error
|
|
165
|
+
* for a call that succeeded.
|
|
166
|
+
*/
|
|
167
|
+
declare const createCallRunner: <A, O, R>(invoke: (args: A, options?: O) => Promise<R>, sinks: CallRunnerSinks<R>) => ((args: A, options?: O) => Promise<R>);
|
|
127
168
|
interface TabCoordinatorOptions {
|
|
128
169
|
/**
|
|
129
170
|
* BroadcastChannel name. Defaults to `"lunora-bridge"`.
|
|
@@ -409,36 +450,6 @@ interface HttpStreamOptions {
|
|
|
409
450
|
* @experimental Reconnect/POST-body/wire-fidelity design questions are still open, so the shape may change.
|
|
410
451
|
*/
|
|
411
452
|
declare const httpStream: <Ref extends HttpStreamRef>(route: Ref, args?: HttpStreamArgsOf<Ref>, options?: HttpStreamOptions) => StreamIterable<HttpStreamChunkOf<Ref>>;
|
|
412
|
-
/** The single transport method a mutation runner needs — narrowed so adapters can test against a stub. */
|
|
413
|
-
interface MutationCapableClient<F extends FunctionReference> {
|
|
414
|
-
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Reactive sinks an adapter binds to its own primitive's setters (a Solid
|
|
418
|
-
* signal, a Vue ref, a Svelte store). The runner pushes into them; how they
|
|
419
|
-
* store the value is the adapter's concern (e.g. Solid wraps function-valued
|
|
420
|
-
* results in a thunk).
|
|
421
|
-
*/
|
|
422
|
-
interface MutationRunnerSinks<R> {
|
|
423
|
-
/** Receives the normalized {@link Error} when an invocation rejects. */
|
|
424
|
-
setError: (error: Error) => void;
|
|
425
|
-
/** Receives `true` while at least one invocation is in flight (ref-counted across overlapping calls), else `false`. */
|
|
426
|
-
setPending: (pending: boolean) => void;
|
|
427
|
-
/** Receives the resolved value when an invocation succeeds. */
|
|
428
|
-
setResult: (result: R) => void;
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Build the framework-neutral `mutate` half of an adapter's mutation hook.
|
|
432
|
-
*
|
|
433
|
-
* Owns the orchestration every adapter otherwise copy-pastes: ref-counts
|
|
434
|
-
* overlapping invocations into `setPending` (so it only clears once the last
|
|
435
|
-
* settles), normalizes a thrown non-`Error`, and routes success/failure to
|
|
436
|
-
* `setResult`/`setError` before re-throwing. Each adapter (`@lunora/react`,
|
|
437
|
-
* `/solid`, `/svelte`, `/vue`) binds the three sinks to its own reactive
|
|
438
|
-
* setters, so this logic lives in exactly one place. Optimistic-update options
|
|
439
|
-
* pass straight through to `client.mutation`.
|
|
440
|
-
*/
|
|
441
|
-
declare const createMutationRunner: <F extends FunctionReference>(client: MutationCapableClient<F>, function_: F, sinks: MutationRunnerSinks<ReturnOf<F>>) => ((args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>);
|
|
442
453
|
/**
|
|
443
454
|
* The structural surface of a TanStack `Transaction` a bound custom mutator
|
|
444
455
|
* returns — its `isPersisted.promise` resolves once the write is persisted and
|
|
@@ -722,9 +733,13 @@ declare const createReconnect: (options?: ReconnectOptions, random?: () => numbe
|
|
|
722
733
|
* `() => boolean` precondition that compares it against the value at replay time.
|
|
723
734
|
*
|
|
724
735
|
* When the precondition is checked (on queue drain / reconnect) it re-reads the
|
|
725
|
-
* query's current
|
|
726
|
-
*
|
|
727
|
-
*
|
|
736
|
+
* query's current state via {@link LunoraClient.peekActiveQuerySnapshot}. The
|
|
737
|
+
* comparison only runs when a live subscription backed **both** reads; if either
|
|
738
|
+
* read found no active subscription (e.g. the originating component unmounted
|
|
739
|
+
* before replay), the precondition returns `true` (not stale) because absence of
|
|
740
|
+
* a subscription is not evidence the value changed — the read simply cannot see
|
|
741
|
+
* it. When both reads did have a live subscription and the value differs, the
|
|
742
|
+
* precondition returns `false` and the offline mutation is dropped as stale.
|
|
728
743
|
* @example
|
|
729
744
|
* ```ts
|
|
730
745
|
* client.mutation(api.todos.update, { id, text }, {
|
|
@@ -821,4 +836,4 @@ declare const sendToSw: (sw: ServiceWorker | null, message: ClientToSwMessage, e
|
|
|
821
836
|
* Create a reply for a client message (call from inside the SW).
|
|
822
837
|
*/
|
|
823
838
|
declare const createReply: (original: ClientToSwMessage, payload?: unknown) => SwToClientMessage;
|
|
824
|
-
export { type
|
|
839
|
+
export { type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, ClientServiceWorker, type ClientSwOptions, type ClientToSwMessage, type ConnectionStatus, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamOptions, type HttpStreamRef, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, LunoraClient, type MutationDelta, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type OptimisticMessage, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, RETIRE_AFTER_DURABLE_SEQ_ADVANCE, type ReconcileDurableMessage, type ReconnectCalculator, type ReconnectOptions, type ServiceWorkerStatus, type StreamIterable, type SubscriptionError, type SwToClientMessage, TabCoordinator, anyApi, applyDelta, createAsyncStoragePersistence, createCallRunner, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutatorRunner, createReconnect, createReply, createSnapshotPrecondition, httpStream, isMutationDelta, maxSeq, queryCacheKey, reconcileOptimistic, sendToSw };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { o as PersistenceAdapter, B as BookmarkStorage, H as HttpStreamRef, m as HttpStreamArgsOf, n as HttpStreamChunkOf,
|
|
2
|
-
export type { C as CachedQuery, q as ClientMessage, r as ClientShapeSubscribeMessage, s as ClientShapeUnsubscribeMessage, t as FunctionArgumentDescriptor, h as FunctionDescriptor, l as GlobalFacetResult, u as GlobalFacetValue, j as GlobalFilterClause, G as GlobalTableInfo, k as GlobalTablePage, v as HttpStreamCallArgs, L as LunoraClientOptions, w as OutboxMutation, x as OutboxSink, y as PersistedMutation, P as Preloaded, z as RowOp, D as RpcEnvelope, E as RpcResponseBody, b as ScheduleRecord, I as SchedulerPoolStatus, c as SchedulerStatus, J as ServerMessage, K as ServerPokeEndMessage, M as ServerPokePartMessage, N as ServerPokeStartMessage, T as ShardTrafficEntry, S as ShardTrafficResult, i as StorageListPage, V as StorageObject, a as Unsubscribe, U as User, g as WorkflowInstanceAction, f as WorkflowInstanceDetail, e as WorkflowInstancePage, d as WorkflowInstanceStatus, X as WorkflowInstanceSummary, Y as WorkflowStepDetail, W as WsTokenProvider } from "./packem_shared/types.d-CsuRAQvb.js";
|
|
3
|
-
import { C as ConnectionStatus, S as SubscriptionError, b as StreamIterable,
|
|
4
|
-
export { type B as BatchSlot, c as CONFLICT_ERROR_CODE, type d as ClientDebugShard, type e as ClientDebugSnapshot, type f as ClientDebugSubscription, type g as ClientQueryRef, D as DEFAULT_MAX_BUFFER, type h as LunoraClientError, type i as LunoraErrorCode, type j as MutationSettledEvent, type O as OptimisticLocalStore, type k as OptimisticUpdate, type l as StreamHandle, type m as SubscriptionCallback, type a as SubscriptionErrorCallback, n as SubscriptionRegistry, type o as SubscriptionState, type p as SyncWatermark, q as createClientQuery, r as createLocalStore, s as createStream, t as getErrorCode, u as getRetryAfterMs, v as isConflictError, w as isForbiddenError, x as isRateLimitedError, y as isUnauthorizedError } from "./packem_shared/lunora-client.d-
|
|
5
|
-
export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-
|
|
1
|
+
import { o as PersistenceAdapter, B as BookmarkStorage, H as HttpStreamRef, m as HttpStreamArgsOf, n as HttpStreamChunkOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, p as ReconnectOptions, F as FunctionReference } from "./packem_shared/types.d-CsuRAQvb.js";
|
|
2
|
+
export type { A as ArgsOf, C as CachedQuery, q as ClientMessage, r as ClientShapeSubscribeMessage, s as ClientShapeUnsubscribeMessage, t as FunctionArgumentDescriptor, h as FunctionDescriptor, l as GlobalFacetResult, u as GlobalFacetValue, j as GlobalFilterClause, G as GlobalTableInfo, k as GlobalTablePage, v as HttpStreamCallArgs, L as LunoraClientOptions, w as OutboxMutation, x as OutboxSink, y as PersistedMutation, P as Preloaded, R as ReturnOf, z as RowOp, D as RpcEnvelope, E as RpcResponseBody, b as ScheduleRecord, I as SchedulerPoolStatus, c as SchedulerStatus, J as ServerMessage, K as ServerPokeEndMessage, M as ServerPokePartMessage, N as ServerPokeStartMessage, T as ShardTrafficEntry, S as ShardTrafficResult, i as StorageListPage, V as StorageObject, a as Unsubscribe, U as User, g as WorkflowInstanceAction, f as WorkflowInstanceDetail, e as WorkflowInstancePage, d as WorkflowInstanceStatus, X as WorkflowInstanceSummary, Y as WorkflowStepDetail, W as WsTokenProvider } from "./packem_shared/types.d-CsuRAQvb.js";
|
|
3
|
+
import { C as ConnectionStatus, S as SubscriptionError, b as StreamIterable, L as LunoraClient } from "./packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
4
|
+
export { type A as ActionCallOptions, type B as BatchSlot, c as CONFLICT_ERROR_CODE, type d as ClientDebugShard, type e as ClientDebugSnapshot, type f as ClientDebugSubscription, type g as ClientQueryRef, D as DEFAULT_MAX_BUFFER, type h as LunoraClientError, type i as LunoraErrorCode, type M as MutationCallOptions, type j as MutationSettledEvent, type O as OptimisticLocalStore, type k as OptimisticUpdate, type l as StreamHandle, type m as SubscriptionCallback, type a as SubscriptionErrorCallback, n as SubscriptionRegistry, type o as SubscriptionState, type p as SyncWatermark, q as createClientQuery, r as createLocalStore, s as createStream, t as getErrorCode, u as getRetryAfterMs, v as isConflictError, w as isForbiddenError, x as isRateLimitedError, y as isUnauthorizedError } from "./packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
5
|
+
export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-Ch-D-Pfo.js";
|
|
6
6
|
export type { AuthCapabilities, AuthConfigInfo, AuthImpersonation, AuthPage, AuthSession, AuthUser, AuthUserFieldSpec, CronJobInfo, KvKeyEntry, KvKeyListResult, KvNamespaceSummary, KvValueResult, PipelineLogColumnMap, PipelineLogCursor, PipelineLogField, PipelineLogPage, PipelineLogQuery, PipelineLogRow, VectorIndexSummary, VectorQueryMatch } from '@lunora/runtime';
|
|
7
7
|
declare const anyApi: Record<string, Record<string, unknown>>;
|
|
8
8
|
/**
|
|
@@ -124,6 +124,47 @@ interface AsyncStoragePersistenceOptions {
|
|
|
124
124
|
declare const createAsyncStoragePersistence: (options: AsyncStoragePersistenceOptions) => PersistenceAdapter;
|
|
125
125
|
/** Default in-memory bookmark store. Survives the lifetime of the client. */
|
|
126
126
|
declare const createInMemoryBookmarkStorage: () => BookmarkStorage;
|
|
127
|
+
/**
|
|
128
|
+
* Reactive sinks an adapter binds to its own primitive's setters (a React
|
|
129
|
+
* `useState`, a Solid signal, a Vue ref, a Svelte store). The runner pushes into
|
|
130
|
+
* them; how they store the value is the adapter's concern (e.g. Solid and React
|
|
131
|
+
* wrap function-valued results in a thunk so the setter stores them rather than
|
|
132
|
+
* invoking them).
|
|
133
|
+
*/
|
|
134
|
+
interface CallRunnerSinks<R> {
|
|
135
|
+
/** Receives the normalized {@link Error} when the latest invocation rejects. */
|
|
136
|
+
setError: (error: Error) => void;
|
|
137
|
+
/** Receives `true` while at least one invocation is in flight (ref-counted across overlapping calls), else `false`. */
|
|
138
|
+
setPending: (pending: boolean) => void;
|
|
139
|
+
/** Receives the resolved value when the latest invocation succeeds. */
|
|
140
|
+
setResult: (result: R) => void;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Build the framework-neutral half of an adapter's write primitive — the `mutate`
|
|
144
|
+
* of `useMutation`/`createMutation`/`mutation`, and the `call` of
|
|
145
|
+
* `useAction`/`createAction`/`action`.
|
|
146
|
+
*
|
|
147
|
+
* It owns the orchestration every adapter otherwise copy-pastes: ref-counting
|
|
148
|
+
* overlapping invocations into `setPending` (so the flag clears only once the
|
|
149
|
+
* last settles), normalizing a thrown non-`Error`, and routing success/failure to
|
|
150
|
+
* `setResult`/`setError` before re-throwing the SAME instance (so a typed error's
|
|
151
|
+
* `.code`/`.data` survive for both the `catch` and the template).
|
|
152
|
+
*
|
|
153
|
+
* `invoke` is a pre-bound thunk — `(args, options) => client.mutation(fn, args, options)`
|
|
154
|
+
* or `(args, options) => client.action(fn, args, options)`. Binding at the call
|
|
155
|
+
* site is what keeps this one function: the runner never inspects `options`, it
|
|
156
|
+
* only forwards them, so the option type is inferred from the closure rather
|
|
157
|
+
* than hard-coded per procedure kind. What actually keeps `optimisticUpdate` off
|
|
158
|
+
* an action is the adapter's exported handle type, not this file.
|
|
159
|
+
*
|
|
160
|
+
* `data`/`error` track the LATEST invocation, not the last to settle: overlapping
|
|
161
|
+
* calls can resolve out of order, so an earlier call that finishes later must not
|
|
162
|
+
* clobber a newer call's outcome. Each invocation takes a monotonic token and
|
|
163
|
+
* writes the value sinks only while it is still the most recent one — otherwise a
|
|
164
|
+
* double-click could leave the UI showing the first click's result, or an error
|
|
165
|
+
* for a call that succeeded.
|
|
166
|
+
*/
|
|
167
|
+
declare const createCallRunner: <A, O, R>(invoke: (args: A, options?: O) => Promise<R>, sinks: CallRunnerSinks<R>) => ((args: A, options?: O) => Promise<R>);
|
|
127
168
|
interface TabCoordinatorOptions {
|
|
128
169
|
/**
|
|
129
170
|
* BroadcastChannel name. Defaults to `"lunora-bridge"`.
|
|
@@ -409,36 +450,6 @@ interface HttpStreamOptions {
|
|
|
409
450
|
* @experimental Reconnect/POST-body/wire-fidelity design questions are still open, so the shape may change.
|
|
410
451
|
*/
|
|
411
452
|
declare const httpStream: <Ref extends HttpStreamRef>(route: Ref, args?: HttpStreamArgsOf<Ref>, options?: HttpStreamOptions) => StreamIterable<HttpStreamChunkOf<Ref>>;
|
|
412
|
-
/** The single transport method a mutation runner needs — narrowed so adapters can test against a stub. */
|
|
413
|
-
interface MutationCapableClient<F extends FunctionReference> {
|
|
414
|
-
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Reactive sinks an adapter binds to its own primitive's setters (a Solid
|
|
418
|
-
* signal, a Vue ref, a Svelte store). The runner pushes into them; how they
|
|
419
|
-
* store the value is the adapter's concern (e.g. Solid wraps function-valued
|
|
420
|
-
* results in a thunk).
|
|
421
|
-
*/
|
|
422
|
-
interface MutationRunnerSinks<R> {
|
|
423
|
-
/** Receives the normalized {@link Error} when an invocation rejects. */
|
|
424
|
-
setError: (error: Error) => void;
|
|
425
|
-
/** Receives `true` while at least one invocation is in flight (ref-counted across overlapping calls), else `false`. */
|
|
426
|
-
setPending: (pending: boolean) => void;
|
|
427
|
-
/** Receives the resolved value when an invocation succeeds. */
|
|
428
|
-
setResult: (result: R) => void;
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Build the framework-neutral `mutate` half of an adapter's mutation hook.
|
|
432
|
-
*
|
|
433
|
-
* Owns the orchestration every adapter otherwise copy-pastes: ref-counts
|
|
434
|
-
* overlapping invocations into `setPending` (so it only clears once the last
|
|
435
|
-
* settles), normalizes a thrown non-`Error`, and routes success/failure to
|
|
436
|
-
* `setResult`/`setError` before re-throwing. Each adapter (`@lunora/react`,
|
|
437
|
-
* `/solid`, `/svelte`, `/vue`) binds the three sinks to its own reactive
|
|
438
|
-
* setters, so this logic lives in exactly one place. Optimistic-update options
|
|
439
|
-
* pass straight through to `client.mutation`.
|
|
440
|
-
*/
|
|
441
|
-
declare const createMutationRunner: <F extends FunctionReference>(client: MutationCapableClient<F>, function_: F, sinks: MutationRunnerSinks<ReturnOf<F>>) => ((args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>);
|
|
442
453
|
/**
|
|
443
454
|
* The structural surface of a TanStack `Transaction` a bound custom mutator
|
|
444
455
|
* returns — its `isPersisted.promise` resolves once the write is persisted and
|
|
@@ -722,9 +733,13 @@ declare const createReconnect: (options?: ReconnectOptions, random?: () => numbe
|
|
|
722
733
|
* `() => boolean` precondition that compares it against the value at replay time.
|
|
723
734
|
*
|
|
724
735
|
* When the precondition is checked (on queue drain / reconnect) it re-reads the
|
|
725
|
-
* query's current
|
|
726
|
-
*
|
|
727
|
-
*
|
|
736
|
+
* query's current state via {@link LunoraClient.peekActiveQuerySnapshot}. The
|
|
737
|
+
* comparison only runs when a live subscription backed **both** reads; if either
|
|
738
|
+
* read found no active subscription (e.g. the originating component unmounted
|
|
739
|
+
* before replay), the precondition returns `true` (not stale) because absence of
|
|
740
|
+
* a subscription is not evidence the value changed — the read simply cannot see
|
|
741
|
+
* it. When both reads did have a live subscription and the value differs, the
|
|
742
|
+
* precondition returns `false` and the offline mutation is dropped as stale.
|
|
728
743
|
* @example
|
|
729
744
|
* ```ts
|
|
730
745
|
* client.mutation(api.todos.update, { id, text }, {
|
|
@@ -821,4 +836,4 @@ declare const sendToSw: (sw: ServiceWorker | null, message: ClientToSwMessage, e
|
|
|
821
836
|
* Create a reply for a client message (call from inside the SW).
|
|
822
837
|
*/
|
|
823
838
|
declare const createReply: (original: ClientToSwMessage, payload?: unknown) => SwToClientMessage;
|
|
824
|
-
export { type
|
|
839
|
+
export { type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, ClientServiceWorker, type ClientSwOptions, type ClientToSwMessage, type ConnectionStatus, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamOptions, type HttpStreamRef, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, LunoraClient, type MutationDelta, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type OptimisticMessage, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, RETIRE_AFTER_DURABLE_SEQ_ADVANCE, type ReconcileDurableMessage, type ReconnectCalculator, type ReconnectOptions, type ServiceWorkerStatus, type StreamIterable, type SubscriptionError, type SwToClientMessage, TabCoordinator, anyApi, applyDelta, createAsyncStoragePersistence, createCallRunner, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutatorRunner, createReconnect, createReply, createSnapshotPrecondition, httpStream, isMutationDelta, maxSeq, queryCacheKey, reconcileOptimistic, sendToSw };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{anyApi as o}from"./packem_shared/anyApi-CBOws2ZA.mjs";import{RETIRE_AFTER_DURABLE_SEQ_ADVANCE as a,maxSeq as
|
|
1
|
+
import{anyApi as o}from"./packem_shared/anyApi-CBOws2ZA.mjs";import{RETIRE_AFTER_DURABLE_SEQ_ADVANCE as a,maxSeq as p,reconcileOptimistic as c}from"./packem_shared/RETIRE_AFTER_DURABLE_SEQ_ADVANCE-DoEHtuR8.mjs";import{createAsyncStoragePersistence as n}from"./packem_shared/createAsyncStoragePersistence-yBu2KWAp.mjs";import{default as f}from"./packem_shared/createInMemoryBookmarkStorage-BooZhW0n.mjs";import{createCallRunner as s}from"./packem_shared/createCallRunner-Bwcrfh76.mjs";import{createClientQuery as u}from"./packem_shared/createClientQuery-TKD_52cT.mjs";import{TabCoordinator as y}from"./packem_shared/TabCoordinator-DVKG2RlZ.mjs";import{a as E,i as C}from"./packem_shared/delta-merge-BoVuM-rE.mjs";import{CONFLICT_ERROR_CODE as A,getErrorCode as D,getRetryAfterMs as _,isConflictError as I,isForbiddenError as M,isRateLimitedError as Q,isUnauthorizedError as h}from"./packem_shared/CONFLICT_ERROR_CODE-LjU7z0mB.mjs";import{httpStream as L}from"./packem_shared/httpStream-x6q-x4yK.mjs";import{c as T}from"./packem_shared/local-store-Bb62Gev5.mjs";import{LunoraClient as g}from"./packem_shared/LunoraClient-Cgu6xN-X.mjs";import{createMutatorRunner as U}from"./packem_shared/createMutatorRunner-CuMRJpUx.mjs";import{O as B}from"./packem_shared/offline-queue-BdQFXDz_.mjs";import{createInMemoryPersistence as N,createIndexedDbPersistence as v}from"./packem_shared/createInMemoryPersistence-BPdQiujT.mjs";import{preloadQuery as z,preloadedQueryResult as K}from"./packem_shared/preloadQuery-uFy24PCR.mjs";import{createInMemoryQueryCache as W,createIndexedDbQueryCache as X,queryCacheKey as j}from"./packem_shared/createInMemoryQueryCache-HMIq2XtS.mjs";import{createReconnect as H}from"./packem_shared/createReconnect-CjTmjJDH.mjs";import{default as Y}from"./packem_shared/createSnapshotPrecondition-_2YMNXlG.mjs";import{DEFAULT_MAX_BUFFER as $,createStream as ee}from"./packem_shared/DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as oe}from"./packem_shared/SubscriptionRegistry-BF75d3VP.mjs";import{ClientServiceWorker as ae}from"./packem_shared/ClientServiceWorker-DXnBXeWK.mjs";import{createReply as ce,sendToSw as me}from"./packem_shared/createReply-CwFABEJs.mjs";export{A as CONFLICT_ERROR_CODE,ae as ClientServiceWorker,$ as DEFAULT_MAX_BUFFER,g as LunoraClient,B as OfflineQueue,a as RETIRE_AFTER_DURABLE_SEQ_ADVANCE,oe as SubscriptionRegistry,y as TabCoordinator,o as anyApi,E as applyDelta,n as createAsyncStoragePersistence,s as createCallRunner,u as createClientQuery,f as createInMemoryBookmarkStorage,N as createInMemoryPersistence,W as createInMemoryQueryCache,v as createIndexedDbPersistence,X as createIndexedDbQueryCache,T as createLocalStore,U as createMutatorRunner,H as createReconnect,ce as createReply,Y as createSnapshotPrecondition,ee as createStream,D as getErrorCode,_ as getRetryAfterMs,L as httpStream,I as isConflictError,M as isForbiddenError,C as isMutationDelta,Q as isRateLimitedError,h as isUnauthorizedError,p as maxSeq,z as preloadQuery,K as preloadedQueryResult,j as queryCacheKey,c as reconcileOptimistic,me as sendToSw};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as f}from"@lunora/errors";import{i as z,a as V,P as j}from"./delta-merge-BoVuM-rE.mjs";import{d as b,e as D}from"./wire-codec-D4iww4NV.mjs";import{s as x}from"./wire-key-HxFZXRbI.mjs";import J from"./createInMemoryBookmarkStorage-BooZhW0n.mjs";import{ClientQueryStore as Y}from"./createClientQuery-TKD_52cT.mjs";import{TabCoordinator as X}from"./TabCoordinator-DVKG2RlZ.mjs";import{httpStream as Z}from"./httpStream-x6q-x4yK.mjs";import{d as O,n as P,f as R,a as ee,c as te}from"./local-store-Bb62Gev5.mjs";import{O as se,n as N,i as re,r as ne}from"./offline-queue-BdQFXDz_.mjs";import{resolvePersistenceAdapter as ie}from"./createInMemoryPersistence-BPdQiujT.mjs";import{resolveQueryCacheAdapter as ae,queryCacheKey as H}from"./createInMemoryQueryCache-HMIq2XtS.mjs";import{createReconnect as K}from"./createReconnect-CjTmjJDH.mjs";import oe from"./createSnapshotPrecondition-_2YMNXlG.mjs";import{createStream as ce}from"./DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as g}from"./SubscriptionRegistry-BF75d3VP.mjs";const F=500,he=(h,e)=>{if(h.size<e)return;const t=h.keys().next().value;t!==void 0&&h.delete(t)};class C{listeners=new Set;add(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}emit(...e){const[t]=e;for(const s of this.listeners)try{s(t)}catch{}}clear(){this.listeners.clear()}}const de="/_lunora/rpc",B="/_lunora/rpc-batch",ue="/_lunora/ws",L=h=>h===void 0||h===""?"":`&bucket=${encodeURIComponent(h)}`,E=h=>{for(let e=h.length-1;e>=0;e-=1)h[e]?.()},le=(h,e)=>{for(const t of e)t.op==="delete"?h.delete(t.key):t.value!==void 0&&h.set(t.key,t.value)},fe="lunora-ping",me=3e4,pe=1e4,ye=250,Se=64,be="/_lunora/admin/shard-traffic",Te="/_lunora/admin/scheduled",ke="/_lunora/admin/scheduled/status",ve="/_lunora/admin/scheduled/ws",ge="/_lunora/admin/scheduled/cancel",Ce="/_lunora/admin/scheduled/dead",_e="/_lunora/admin/scheduled/dead/retry",we="/_lunora/admin/scheduled/dead/cancel",Ee="/_lunora/admin/workflows/instances",Ae="/_lunora/admin/workflows/instance",Ie="/_lunora/admin/workflows/status",M="/_lunora/admin/storage",Oe="/_lunora/admin/storage/url",Pe="/_lunora/admin/storage/buckets",Re="/_lunora/admin/functions",He="/_lunora/admin/cron-jobs",Fe="/_lunora/admin/cron-jobs/run",Le="/_lunora/admin/openapi",Me="/_lunora/admin/openrpc",Ue="/_lunora/admin/global/tables",xe="/_lunora/admin/global/table",Ne="/_lunora/admin/global/facet",Ke="/_lunora/admin/vector/indexes",Be="/_lunora/admin/vector/query",We="/_lunora/admin/logs/archive",qe="/_lunora/admin/kv/namespaces",De="/_lunora/admin/kv/keys",U="/_lunora/admin/kv/value",$e="/_lunora/admin/auth/users",Qe="/_lunora/admin/auth/sessions",Ge="/_lunora/admin/auth/users/create",ze="/_lunora/admin/auth/users/role",Ve="/_lunora/admin/auth/users/ban",je="/_lunora/admin/auth/users/unban",Je="/_lunora/admin/auth/users/password",Ye="/_lunora/admin/auth/users/remove",Xe="/_lunora/admin/auth/users/impersonate",Ze="/_lunora/admin/auth/sessions/revoke",et="/_lunora/admin/auth/sessions/revoke-all",tt="/_lunora/admin/auth/capabilities",st="/_lunora/admin/auth/users/update",rt="/_lunora/admin/auth/accounts",nt="/_lunora/admin/auth/accounts/unlink",it="/_lunora/admin/auth/passkeys",at="/_lunora/admin/auth/passkeys/delete",ot="/_lunora/admin/auth/two-factor/disable",ct="/_lunora/admin/auth/organizations",ht="/_lunora/admin/auth/organizations/members",dt="/_lunora/admin/auth/organizations/invitations",ut="/_lunora/admin/auth/organizations/members/remove",lt="/_lunora/admin/auth/organizations/invitations/cancel",ft="/_lunora/admin/auth/config",mt="/_lunora/admin/auth/organizations/create",pt="/_lunora/admin/auth/organizations/update",yt="/_lunora/admin/auth/organizations/remove",St="/_lunora/admin/auth/organizations/members/add",bt="/_lunora/admin/auth/organizations/members/invite",Tt="/_lunora/admin/auth/organizations/members/role",kt="/_lunora/admin/auth/organizations/teams",vt="/_lunora/admin/auth/organizations/teams/create",gt="/_lunora/admin/auth/organizations/teams/update",Ct="/_lunora/admin/auth/organizations/teams/remove",_t="/_lunora/admin/auth/organizations/teams/members",wt="/_lunora/admin/auth/organizations/teams/members/add",Et="/_lunora/admin/auth/organizations/teams/members/remove",At="/_lunora/admin/auth/organizations/roles",It="/_lunora/admin/auth/organizations/roles/create",Ot="/_lunora/admin/auth/organizations/roles/update",Pt="/_lunora/admin/auth/organizations/roles/remove",Rt="/api/auth",Ht="/get-session",W=h=>h.startsWith("https://")?`wss://${h.slice(8)}`:h.startsWith("http://")?`ws://${h.slice(7)}`:h,k=(h,e)=>`${h.endsWith("/")?h.slice(0,-1):h}${e}`,y=(h,e)=>{const t=new URLSearchParams;for(const[r,n]of Object.entries(e))n!==void 0&&n!==""&&t.set(r,String(n));const s=t.toString();return s===""?h:`${h}?${s}`},Ft=[j],m=h=>h??"",$=(h,e)=>{const t=h.error,s=typeof t?.code=="string"?t.code:void 0,r=typeof t?.message=="string"?t.message:void 0;return{code:s,messageText:(typeof h.message=="string"?h.message:void 0)??r??e}},Lt=h=>{const{code:e,messageText:t}=$(h,"stream error");return e===void 0?new Error(t):new f(e,t)},q=h=>{const{code:e,messageText:t}=$(h,"subscription error");return{message:t,...e===void 0?{}:{code:e}}},A=(h,e)=>{for(const t of h)try{t(e)}catch{}},Mt=new TextDecoder,Ut=h=>{if(typeof h=="string")return h;if(h instanceof ArrayBuffer)return Mt.decode(h)},S=(h,e)=>{if(!h.socket||h.wsState!=="open")return!1;try{return h.socket.send(JSON.stringify(e)),!0}catch{return!1}},_=h=>{const e=new Error(h.message??"request failed");return e.code=h.code,h.data!==void 0&&(e.data=b(h.data)),h.hint!==void 0&&(e.hint=h.hint),h.docsUrl!==void 0&&(e.docsUrl=h.docsUrl),e},v=(h,e)=>{try{return D(h)}catch(t){const s=t instanceof Error?t.message:String(t);throw new TypeError(`LunoraClient: cannot encode ${e} — ${s}`,t instanceof Error?{cause:t}:void 0)}},xt=(h,e)=>{const t=Array.from({length:e});for(const s of h){if(typeof s.id!="number"||s.id<0||s.id>=e)continue;const r=s.body;t[s.id]=r&&"error"in r&&r.error?{error:_(r.error),ok:!1}:{ok:!0,value:b(r?.result)}}return t.map(s=>s??{error:new Error("batch call returned no result"),ok:!1})},Nt=new Set(["SHARD_ERROR","SHARD_UNAVAILABLE"]),Kt=Promise.resolve();class Q{static MAX_POKE_BUFFERS=256;static createClientQuery(e,t){return{defaultValue:t,key:e}}url;wsUrl;clientQueryStore;wsToken;authBasePath;fetchImpl;WebSocketImpl;bookmark;reconnectOptions;connectTimeoutMs;heartbeatIntervalMs;offlineQueue;outbox;clientId;shardCursors=new Map;defaultShardKey;readyResolved=!1;readyResolve;readyPromise;clientWatermarks=new Map;outboxMutationCounter=0;onPersistenceError;persistence;persistenceVersion;outboxLeaderRelease;queryCache;hydratedQueryCache=new Map;pendingCacheWrites=new Map;cacheFlushTimer;subscriptions=new g;tabCoordinator;leaderStatus;leaderWasEverConnected=!1;connections=new Map;defaultConnectionContext;connectionContexts=new Map;connectionContextHolders=new Map;authToken=null;authSubject=void 0;queuedIdentities=new Map;queuedOfflineShardKeys=new Set;closed=!1;authTokenListeners=new C;statusListeners=new C;tokenExpiredListeners=new C;mutationSettledListeners=new C;pendingChangeListeners=new C;whisperHandlers=new Map;lastStatus="idle";nextSubId=0;nextStreamId=0;streams=new Map;shapeSubscriptions=new Map;pokeBuffers=new Map;nextShapeId=0;constructor(e){this.url=e.url,this.wsUrl=e.wsUrl??k(W(e.url),ue),this.wsToken=e.wsToken;const t=e.authBasePath??Rt;this.authBasePath=t.endsWith("/")?t.slice(0,-1):t,this.fetchImpl=e.fetch??(typeof fetch=="function"?fetch.bind(globalThis):void 0),this.WebSocketImpl=e.WebSocket??(typeof WebSocket=="function"?WebSocket:void 0),this.bookmark=e.bookmarkStorage??J(),this.reconnectOptions=e.reconnect,this.heartbeatIntervalMs=e.heartbeatIntervalMs??me,this.connectTimeoutMs=e.connectTimeoutMs??pe,this.defaultConnectionContext=e.connectionContext,this.persistence=ie(e.persistence,e.outbox===void 0),this.persistenceVersion=e.persistenceVersion,this.queryCache=ae(e.queryCache),this.onPersistenceError=e.offlineQueue?.onPersistenceError,this.clientQueryStore=new Y,e.crossTabSync?(this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start()):this.tabCoordinator=void 0,e.hydrateOnStart&&this.queryCache?this.readyPromise=new Promise(s=>{this.readyResolve=s}):(this.readyResolved=!0,this.readyPromise=Kt),this.offlineQueue=new se(e.offlineQueue,{onEvict:(s,r)=>{this.emitItemSettled(s,"rejected",r)},onSizeChange:s=>{this.pendingChangeListeners.emit(s)},persistence:this.persistence,version:e.persistenceVersion}),this.outbox=e.outbox,this.clientId=e.clientId??`client-${N()}`,this.persistence&&queueMicrotask(()=>{this.hydrateAsOutboxLeader()}),this.queryCache&&queueMicrotask(()=>{(async()=>{try{await this.hydrateQueryCache()}catch{}finally{this.readyResolved=!0,this.readyResolve?.()}})().catch(()=>{})})}setAuthToken(e,t){const s=this.authToken!==e,r=this.identityFingerprint();this.authToken=e,t!==void 0&&(this.authSubject=t);const n=this.identityFingerprint();if(n!==r&&(s?this.rejectQueuedForIdentityChange():(this.restampQueuedIdentity(r,n),this.restampWatermarks(r,n)),this.tabCoordinator)){const i=this.tabCoordinator.isLeader();this.tabCoordinator.stop(),this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start(),i&&this.tabCoordinator.promoteImmediately()}s&&this.authTokenListeners.emit(e)}getAuthToken(){return this.authToken}currentIdentity(){return this.identityFingerprint()}clientIdentifier(){return this.clientId}confirmedMutationWatermark(e){return this.clientWatermarks.get(this.identityFingerprint()??"")?.get(e??"")??0}async callMutator(e,t,s){const r=s?.clientSeq;if(r!==void 0&&(!Number.isInteger(r)||r<=0))throw new f("INTERNAL",`callMutator: clientSeq must be a positive integer, got ${String(r)}`);const n=s?.shardKey??"",i=this.identityFingerprint();let a;const o=await this.rpc(e,t,s?.shardKey,{captureBookmark:!0,clientId:this.clientId,clientSeq:r,onMutationAck:d=>{a=d}});if(a!==void 0&&a>(this.clientWatermarks.get(i??"")?.get(n)??0)){let d=this.clientWatermarks.get(i??"");d===void 0&&(d=new Map,this.clientWatermarks.set(i??"",d)),d.set(n,a)}return{applied:a===void 0||a===r,result:o}}onAuthTokenChange(e){return this.authTokenListeners.add(e)}async getCurrentUser(){if(this.closed||!this.fetchImpl)return null;const e={};this.authToken&&(e.authorization=`Bearer ${this.authToken}`);try{const t=await this.fetchImpl(k(this.url,`${this.authBasePath}${Ht}`),{credentials:"include",headers:e,method:"GET"});return t.ok?(await t.json())?.user??null:null}catch{return null}}setWsToken(e){if(this.wsToken!==e){this.wsToken=e;for(const t of this.connections.values())if(t.socket)try{t.socket.close()}catch{}}}setConnectionContext(e,t={}){const s=m(t.shardKey);e===void 0?this.connectionContexts.delete(s):this.connectionContexts.set(s,e),this.refreshConnectionContext(s)}acquireConnectionContext(e,t={}){const s=m(t.shardKey),r={context:e},n=this.connectionContextHolders.get(s);n?n.push(r):this.connectionContextHolders.set(s,[r]),this.refreshConnectionContext(s);let i=!1;return()=>{if(i)return;i=!0;const a=this.connectionContextHolders.get(s);if(!a)return;const o=a.indexOf(r);o!==-1&&a.splice(o,1),a.length===0&&this.connectionContextHolders.delete(s),this.refreshConnectionContext(s)}}whisperSubscribe(e,t,s={}){const r=m(s.shardKey);let n=this.whisperHandlers.get(r);n||(n=new Map,this.whisperHandlers.set(r,n));let i=n.get(e);const a=i===void 0;if(i||(i=new Set,n.set(e,i)),i.add(t),this.ensureSocket(s.shardKey),a){const o=this.getConnection(s.shardKey);o&&S(o,{topic:e,type:"whisper_subscribe"})}return()=>{const o=this.whisperHandlers.get(r),c=o?.get(e);if(!c?.delete(t)||c.size>0)return;o?.delete(e),o?.size===0&&this.whisperHandlers.delete(r);const d=this.getConnection(s.shardKey);d&&S(d,{topic:e,type:"whisper_unsubscribe"})}}whisper(e,t,s={}){this.ensureSocket(s.shardKey);const r=this.getConnection(s.shardKey);r&&S(r,{data:v(t??null,`whisper data for topic '${e}'`),topic:e,type:"whisper"})}onTokenExpired(e){return this.tokenExpiredListeners.add(e)}connectionStatus(){return this.computeStatus()}onConnectionStatus(e){const t=this.statusListeners.add(e);return e(this.computeStatus()),t}pendingCount(){return this.offlineQueue.size}debug(){const e=[],t=this.clientWatermarks.get(this.identityFingerprint()??""),s=new Set([...this.connections.keys(),...t?.keys()??[]]);for(const n of s){const i=this.connections.get(n);e.push({confirmedMutationWatermark:t?.get(n)??0,hasSocket:i?.socket!==void 0,shardKey:n===""?void 0:n,wasEverConnected:i?.wasEverConnected??!1,wsState:i?.wsState??"idle"})}const r=this.subscriptions.all().map(n=>({acked:n.acked,functionPath:n.fn.__lunoraRef,id:n.id,kind:"query",lastMutationId:n.lastMutationId,pendingOptimisticLayers:n.optimisticLayers.length,serverCursor:n.serverCursor,shardKey:n.shardKey,subscriberCount:n.callbacks.size}));for(const n of this.shapeSubscriptions.values())r.push({acked:n.serverCursor!==void 0,functionPath:`shape:${n.name}`,id:n.id,kind:"shape",lastMutationId:n.lastMutationId,pendingOptimisticLayers:0,rowCount:n.rows.size,serverCursor:n.serverCursor,shardKey:n.shardKey,subscriberCount:n.callbacks.size});return{clientId:this.clientId,closed:this.closed,connectionStatus:this.computeStatus(),pendingWrites:this.offlineQueue.size,shards:e.toSorted((n,i)=>(n.shardKey??"").localeCompare(i.shardKey??"")),subscriptions:r.toSorted((n,i)=>n.functionPath.localeCompare(i.functionPath))}}onPendingChange(e){const t=this.pendingChangeListeners.add(e);return e(this.offlineQueue.size),t}onMutationSettled(e){return this.mutationSettledListeners.add(e)}getWebSocketImpl(){return this.WebSocketImpl}getClientQuery(e){return this.clientQueryStore.get(e)}setClientQuery(e,t){this.clientQueryStore.set(e,t)}subscribeClientQuery(e,t){return this.clientQueryStore.subscribe(e,t)}resetClientQuery(e){this.clientQueryStore.reset(e)}snapshotPrecondition(e,t,s){return oe(this,e,t,s)}whenReady(){return this.readyPromise}get isReady(){return this.readyResolved}peekHydratedQuery(e,t,s){if(!this.readyResolved)return;const r=x(t),n=H(e,r,s),i=this.hydratedQueryCache.get(n);if(i!==void 0)return i.identity===this.identityFingerprint()?i.value:void 0}peekActiveQuerySnapshot(e,t,s){const r=g.key(e,t,s),n=this.subscriptions.get(r);return{present:n!==void 0,value:n?.lastValue}}async query(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey,{attachBookmark:!0})}async batch(e){if(this.assertOpen(),!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");if(e.length===0)return[];const t=await this.fetchImpl(k(this.url,B),{body:JSON.stringify({calls:e.map((n,i)=>({args:v(n.args??{},`args for batch call '${n.fn.__lunoraRef}'`),functionPath:n.fn.__lunoraRef,id:i,shardKey:n.shardKey}))}),headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"}),s=t.headers.get("x-d1-bookmark");s&&this.bookmark.set(s);let r;try{r=await t.json()}catch{throw new f("INTERNAL",`LunoraClient: batch response was not JSON (status ${t.status.toString()})`)}if(!t.ok||r.error&&!r.results)throw r.error?_(r.error):new f("INTERNAL",`LunoraClient: batch request failed (status ${t.status.toString()})`);for(const n of r.results??[]){const i=n.body?.commitCursor;typeof n.id=="number"&&typeof i=="number"&&this.recordShardCursor(e[n.id]?.shardKey,i)}return xt(r.results??[],e.length)}async mutation(e,t,s={}){this.assertOpen();const r=t,n=s.mutationId??N(),{confirms:i,rollbacks:a}=this.applyOptimisticUpdates(e.__lunoraRef,r,s.shardKey,s.optimistic);s.optimisticUpdate&&this.applyOptimisticUpdate(s.optimisticUpdate,t,s.shardKey,a,i);const{hasSocket:o,wasEverConnected:c,wsState:d}=this.connectionGateState(s.shardKey),{queueBeforeFirstConnect:u}=this.offlineQueue,l=c||u,p=this.WebSocketImpl!==void 0&&l;if(d!=="open"&&!o&&p||d==="connecting"&&l)return this.enqueueOfflineMutation(e,r,s.shardKey,n,a,i,s.precondition);try{let w;const G=await this.rpc(e.__lunoraRef,r,s.shardKey,{captureBookmark:!0,mutationId:n,onCommitCursor:I=>{w=I}});for(const I of i)I(w);return G}catch(w){throw E(a),w}}async action(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey)}async importRows(e,t,s={}){this.assertOpen();const r=Math.max(1,Math.trunc(s.chunkSize??500)),n=s.toArgs??(c=>({rows:c})),i=t.length;let a=0,o=0;for(let c=0;c<i;c+=r){const d=t.slice(c,c+r),u=o;await this.mutation(e,n(d),{...s.importId===void 0?{}:{mutationId:`${s.importId}:${String(u)}`},shardKey:s.shardKey}),o+=1,a+=d.length,s.onProgress?.({done:a,total:i})}return{chunks:o,imported:a}}async shardTraffic(e){this.assertOpen();const t=await this.adminFetch(be,"POST",{table:e});return{failed:t.failed??0,ok:t.ok??0,shards:t.shards??[]}}async listScheduledJobs(){return this.assertOpen(),(await this.adminFetch(Te,"GET")).records??[]}async schedulerStatus(){this.assertOpen();const e=await this.adminFetch(ke,"GET");return{backlog:e.backlog??0,inFlight:e.inFlight??0,pools:e.pools??[]}}async cancelScheduledJob(e){return this.assertOpen(),{cancelled:(await this.adminFetch(ge,"POST",{id:e})).cancelled===!0}}async listDeadJobs(){return this.assertOpen(),(await this.adminFetch(Ce,"GET")).records??[]}async retryDeadJob(e){return this.assertOpen(),{retried:(await this.adminFetch(_e,"POST",{id:e})).retried===!0}}async removeDeadJob(e){return this.assertOpen(),{removed:(await this.adminFetch(we,"POST",{id:e})).removed===!0}}async listWorkflowInstances(e){this.assertOpen();const t=new URLSearchParams({name:e.name});e.status!==void 0&&t.set("status",e.status),e.page!==void 0&&t.set("page",String(e.page)),e.perPage!==void 0&&t.set("perPage",String(e.perPage));const s=await this.adminFetch(`${Ee}?${t.toString()}`,"GET");return{configured:s.configured,instances:s.instances??[],page:s.page??1,perPage:s.perPage??e.perPage??0,totalCount:s.totalCount}}async getWorkflowInstance(e){this.assertOpen();const t=new URLSearchParams({id:e.id,name:e.name}),s=await this.adminFetch(`${Ae}?${t.toString()}`,"GET");return{createdOn:s.createdOn,endedOn:s.endedOn,error:s.error,id:s.id??e.id,output:s.output,params:s.params,startedOn:s.startedOn,status:s.status??"unknown",steps:s.steps??[]}}async setWorkflowInstanceStatus(e){return this.assertOpen(),{status:(await this.adminFetch(Ie,"POST",{action:e.action,id:e.id,name:e.name})).status??"unknown"}}subscribeScheduledJobs(e){if(this.assertOpen(),this.WebSocketImpl===void 0)return()=>{};const t=k(W(this.url),ve),s=K(this.reconnectOptions),r={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,socket:void 0};let n,i=!1;const a=()=>{i||(n=setTimeout(d,s.next()))},o=u=>{if(i||this.WebSocketImpl===void 0)return;const l=u===void 0?t:`${t}?token=${encodeURIComponent(u)}`;this.openManagedSocket(r,l,this.connectTimeoutMs,{onClose:()=>{a()},onMessage:p=>{try{const T=JSON.parse(typeof p.data=="string"?p.data:"");T.type==="jobs"&&Array.isArray(T.records)&&e(T.records)}catch{}},onOpen:()=>{s.reset()}})},c=async u=>{let l;try{l=await u()}catch{a();return}o(l)},d=()=>{if(i||this.WebSocketImpl===void 0)return;const{wsToken:u}=this;if(typeof u=="function"){c(u).catch(()=>{});return}o(u)};return d(),()=>{i=!0,n!==void 0&&clearTimeout(n),r.connectTimer!==void 0&&(clearTimeout(r.connectTimer),r.connectTimer=void 0),this.stopHeartbeat(r),r.socket?.close()}}async listFunctions(){return this.assertOpen(),(await this.adminFetch(Re,"GET")).functions??[]}async getCronJobs(){return this.assertOpen(),(await this.adminFetch(He,"GET")).jobs??[]}async runCronJob(e){this.assertOpen();const t=await this.adminFetch(Fe,"POST",{name:e});return{name:t.name??e,ran:t.ran===!0}}async fetchOpenApi(){return this.assertOpen(),await this.adminFetch(Le,"GET")}async fetchOpenRpc(){return this.assertOpen(),await this.adminFetch(Me,"GET")}async listStorageObjects(e={}){this.assertOpen();const t=y(M,{bucket:e.bucket,cursor:e.cursor,limit:e.limit,prefix:e.prefix}),s=await this.adminFetch(t,"GET");return{cursor:s.cursor,objects:s.objects??[]}}async deleteStorageObject(e,t){this.assertOpen();const s=`${M}?key=${encodeURIComponent(e)}${L(t?.bucket)}`,r=await this.adminFetch(s,"DELETE");return{deleted:r.deleted??!0,key:r.key??e}}async listStorageBuckets(){return this.assertOpen(),(await this.adminFetch(Pe,"GET")).buckets??[]}async uploadStorageObject(e){this.assertOpen();const t=`${M}?key=${encodeURIComponent(e.key)}${L(e.bucket)}`,s=await this.adminFetch(t,"PUT",e.body,e.contentType);return{etag:s.etag,key:s.key??e.key}}async signedStorageUrl(e,t){this.assertOpen();const s=t?.expiresInSeconds,r=s===void 0?"":`&expiresIn=${encodeURIComponent(s.toString())}`,n=`${Oe}?key=${encodeURIComponent(e)}${r}${L(t?.bucket)}`,i=await this.adminFetch(n,"GET");if(typeof i.url!="string")throw new TypeError("LunoraClient: storage URL endpoint returned no `url`");return i.url}async listGlobalTables(){return this.assertOpen(),await this.adminFetch(Ue,"GET")}async readGlobalTablePage(e){this.assertOpen();const t=new URLSearchParams({table:e.table});return e.limit!==void 0&&t.set("limit",String(e.limit)),e.offset!==void 0&&t.set("offset",String(e.offset)),e.filters!==void 0&&e.filters.length>0&&t.set("filters",JSON.stringify(e.filters)),await this.adminFetch(`${xe}?${t.toString()}`,"GET")}async facetGlobalColumn(e){this.assertOpen();const t=new URLSearchParams({column:e.column,table:e.table});return e.limit!==void 0&&t.set("limit",String(e.limit)),e.filters!==void 0&&e.filters.length>0&&t.set("filters",JSON.stringify(e.filters)),await this.adminFetch(`${Ne}?${t.toString()}`,"GET")}async listVectorIndexes(){return this.assertOpen(),(await this.adminFetch(Ke,"GET")).indexes??[]}async queryVectorIndex(e){return this.assertOpen(),(await this.adminFetch(Be,"POST",e)).matches??[]}async queryLogArchive(e={}){this.assertOpen();const t=await this.adminFetch(We,"POST",e);return{nextCursor:t.nextCursor,rows:t.rows??[]}}async listKvNamespaces(){return this.assertOpen(),(await this.adminFetch(qe,"GET")).namespaces??[]}async listKvKeys(e){this.assertOpen();const t=y(De,{cursor:e.cursor,limit:e.limit,namespace:e.namespace,prefix:e.prefix});return await this.adminFetch(t,"GET")}async getKvValue(e){this.assertOpen();const t=y(U,{key:e.key,namespace:e.namespace});return await this.adminFetch(t,"GET")}async putKvValue(e){this.assertOpen(),await this.adminFetch(U,"PUT",e)}async deleteKvKey(e){this.assertOpen();const t=y(U,{key:e.key,namespace:e.namespace});await this.adminFetch(t,"DELETE")}async listAuthUsers(e={}){this.assertOpen();const t=y($e,{filterField:e.filterField,filterValue:e.filterValue,limit:e.limit,offset:e.offset,search:e.search,searchField:e.searchField,sortBy:e.sortBy,sortDirection:e.sortDirection});return await this.adminFetch(t,"GET")}async createAuthUser(e){return await this.adminFetch(Ge,"POST",e)}async setAuthUserRole(e){return await this.adminFetch(ze,"POST",e)}async banAuthUser(e){return await this.adminFetch(Ve,"POST",e)}async unbanAuthUser(e){return await this.adminFetch(je,"POST",e)}async setAuthUserPassword(e){await this.adminFetch(Je,"POST",e)}async removeAuthUser(e){await this.adminFetch(Ye,"POST",e)}async impersonateAuthUser(e){return await this.adminFetch(Xe,"POST",e)}async revokeAuthSession(e){await this.adminFetch(Ze,"POST",e)}async revokeAuthUserSessions(e){await this.adminFetch(et,"POST",e)}async getAuthCapabilities(){return await this.adminFetch(tt,"GET")}async updateAuthUser(e){return await this.adminFetch(st,"POST",e)}async listAuthAccounts(e){return await this.adminFetch(y(rt,{userId:e.userId}),"GET")}async unlinkAuthAccount(e){await this.adminFetch(nt,"POST",e)}async listAuthPasskeys(e){return await this.adminFetch(y(it,{userId:e.userId}),"GET")}async deleteAuthPasskey(e){await this.adminFetch(at,"POST",e)}async disableAuthTwoFactor(e){await this.adminFetch(ot,"POST",e)}async listAuthOrganizations(e={}){return await this.adminFetch(y(ct,{limit:e.limit,offset:e.offset}),"GET")}async listAuthOrgMembers(e){const t=y(ht,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async listAuthOrgInvitations(e){const t=y(dt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async removeAuthOrgMember(e){await this.adminFetch(ut,"POST",e)}async cancelAuthOrgInvitation(e){await this.adminFetch(lt,"POST",e)}async getAuthConfig(){return await this.adminFetch(ft,"GET")}async createAuthOrganization(e){return await this.adminFetch(mt,"POST",e)}async updateAuthOrganization(e){return await this.adminFetch(pt,"POST",e)}async deleteAuthOrganization(e){await this.adminFetch(yt,"POST",e)}async addAuthOrgMember(e){return await this.adminFetch(St,"POST",e)}async inviteAuthOrgMember(e){return await this.adminFetch(bt,"POST",e)}async setAuthOrgMemberRole(e){return await this.adminFetch(Tt,"POST",e)}async listAuthOrgTeams(e){const t=y(kt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgTeam(e){return await this.adminFetch(vt,"POST",e)}async updateAuthOrgTeam(e){return await this.adminFetch(gt,"POST",e)}async removeAuthOrgTeam(e){await this.adminFetch(Ct,"POST",e)}async listAuthOrgTeamMembers(e){const t=y(_t,{limit:e.limit,offset:e.offset,teamId:e.teamId});return await this.adminFetch(t,"GET")}async addAuthOrgTeamMember(e){return await this.adminFetch(wt,"POST",e)}async removeAuthOrgTeamMember(e){await this.adminFetch(Et,"POST",e)}async listAuthOrgRoles(e){const t=y(At,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgRole(e){return await this.adminFetch(It,"POST",e)}async updateAuthOrgRole(e){return await this.adminFetch(Ot,"POST",e)}async deleteAuthOrgRole(e){await this.adminFetch(Pt,"POST",e)}async listAuthSessions(e={}){this.assertOpen();const t=y(Qe,{limit:e.limit,offset:e.offset,userId:e.userId});return await this.adminFetch(t,"GET")}subscribe(e,t,s,r={}){this.assertOpen();const n=t??{},i=g.key(e.__lunoraRef,n,r.shardKey);let a=this.subscriptions.get(i);const o=s,c=r.onError;if(!a){this.nextSubId+=1;const u=`sub_${this.nextSubId.toString()}`,l=x(n),p=this.takeHydratedCache(e.__lunoraRef,l,r.shardKey);a={acked:!1,args:n,argsKey:l,callbacks:new Set,checkpointCallbacks:new Set,errorCallbacks:new Set,fn:e,id:u,lastValue:p?.value,optimisticLayers:[],serverBase:p?.value,serverCursor:p?.serverCursor,shardKey:r.shardKey,...p?.serverEpoch===void 0?{}:{serverEpoch:p.serverEpoch}},this.subscriptions.add(a)}if(a.callbacks.add(o),c&&a.errorCallbacks.add(c),r.onCheckpoint&&a.checkpointCallbacks.add(r.onCheckpoint),a.lastValue!==void 0)try{o(a.lastValue)}catch{}this.ensureSocket(r.shardKey),this.sendSubscribeIfOpen(a);const d=a;return()=>{d.callbacks.delete(o),c&&d.errorCallbacks.delete(c),r.onCheckpoint&&d.checkpointCallbacks.delete(r.onCheckpoint),d.callbacks.size===0&&(this.sendOrQueueUnsubscribe(d.shardKey,d.id,"unsubscribe"),this.subscriptions.remove(d))}}subscribeShape(e,t,s={}){this.assertOpen(),this.nextShapeId+=1;const r=`shape_${this.nextShapeId.toString()}`,n={args:e.args,callbacks:new Set([t]),errorCallbacks:s.onError?new Set([s.onError]):new Set,id:r,name:e.name,onCheckpoint:s.onCheckpoint,rows:new Map,shardKey:s.shardKey,wireArgs:e.args===void 0?void 0:v(e.args,`shape args for '${e.name}'`)};return this.shapeSubscriptions.set(r,n),this.ensureSocket(s.shardKey),this.sendShapeSubscribeIfOpen(n),()=>{this.shapeSubscriptions.delete(r),this.sendOrQueueUnsubscribe(n.shardKey,r,"shape_unsubscribe")}}stream(e,t,s={}){if(this.assertOpen(),this.WebSocketImpl===void 0)throw new f("INTERNAL","LunoraClient: streams require a WebSocket implementation");this.nextStreamId+=1;const r=`stream_${this.nextStreamId.toString()}`,{shardKey:n}=s,i=t??{},{handle:a,iterable:o}=ce({maxBuffer:s.maxBuffer,onCancel:()=>{const l=this.getConnection(n);l&&S(l,{id:r,type:"unsubscribe"}),this.streams.delete(r)}});this.ensureSocket(n);const c=this.getConnection(n),d={id:r,query:{args:v(i,`stream args for '${e.__lunoraRef}'`),functionPath:e.__lunoraRef,shardKey:n},type:"stream"};if(this.streams.set(r,{durable:s.durable===!0,handle:a,lastSeq:0,message:d,shardKey:n}),!(c?.wsState==="open"&&S(c,d))&&c){for(c.pendingStreams=c.pendingStreams??[];c.pendingStreams.length>=Se;){const p=c.pendingStreams.shift()?.id,T=p?this.streams.get(p):void 0;T&&(T.handle.fail(new f("STREAM_QUEUE_OVERFLOW","stream-start frame evicted while socket was unreachable")),this.streams.delete(p))}c.pendingStreams.push(d)}return o}httpStream(e,t,s={}){if(this.closed)throw new f("CLIENT_CLOSED","LunoraClient is closed");if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const r={...this.authToken?{authorization:`Bearer ${this.authToken}`}:{},...s.headers};return Z(e,t,{baseUrl:this.url,fetch:this.fetchImpl,headers:r,maxBuffer:s.maxBuffer,signal:s.signal})}close(){this.closed=!0,this.outboxLeaderRelease?.(),this.outboxLeaderRelease=void 0;for(const e of this.streams.values())e.handle.fail(new f("CLIENT_CLOSED","LunoraClient closed"));this.streams.clear();for(const e of this.connections.values())this.teardownConnection(e);this.offlineQueue.clear(),this.queuedIdentities.clear(),this.cacheFlushTimer!==void 0&&(clearTimeout(this.cacheFlushTimer),this.cacheFlushTimer=void 0),this.pendingCacheWrites.size>0&&this.flushQueryCacheWrites().catch(()=>{}),this.authTokenListeners.clear(),this.statusListeners.clear(),this.tokenExpiredListeners.clear(),this.mutationSettledListeners.clear(),this.pendingChangeListeners.clear(),this.whisperHandlers.clear(),this.shapeSubscriptions.clear(),this.pokeBuffers.clear(),this.tabCoordinator?.stop(),this.tabCoordinator=void 0}assertOpen(){if(this.closed)throw new f("INTERNAL","LunoraClient is closed")}teardownConnection(e){if(e.reconnectTimer!==void 0&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),this.stopHeartbeat(e),e.socket){try{e.socket.close()}catch{}e.socket=void 0}e.wsState="closed"}createTabCoordinator(){const e=`lunora-bridge::${this.url}::${this.identityFingerprint()??"anon"}`;return new X({channelName:e,onBecomeLeader:()=>{for(const t of this.subscriptions.all())this.ensureSocket(t.shardKey),this.sendSubscribeIfOpen(t);this.tabCoordinator?.broadcastConnectionStatus(this.computeStatus(),this.identityFingerprint())},onStopBeingLeader:()=>{for(const[t,s]of this.connections)this.teardownConnection(s),this.connections.delete(t);this.leaderStatus=void 0,this.leaderWasEverConnected=!1},onConnectionStatus:(t,s)=>{if(s!==void 0&&s!==this.identityFingerprint())return;const r=t==="connected"&&this.leaderStatus!=="connected";this.leaderStatus=t,t==="connected"&&(this.leaderWasEverConnected=!0),this.emitConnectionStatus(),r&&this.flushAllOfflineQueues()},onSubscriptionData:(t,s,r,n,i)=>{if(i!==void 0&&i!==this.identityFingerprint())return;const a=this.subscriptions.get(t);a&&(a.serverBase=s,r!==void 0&&(a.serverCursor=r,n!==void 0&&(a.serverEpoch=n),O(a,r)),P(a,R(s,a.optimisticLayers)))},onSubscriptionError:(t,s)=>{const r=this.subscriptions.get(t);r&&A(r.errorCallbacks,s)},onSubscriptionSettled:(t,s,r,n,i,a)=>{if(a!==void 0&&a!==this.identityFingerprint())return;const o=this.subscriptions.get(t);if(o){this.ackAndAdvanceCursor(o,s,r),n!==void 0&&i===this.clientId&&(o.lastMutationId=Math.max(o.lastMutationId??0,n));for(const c of o.checkpointCallbacks)c({checkpoint:o.serverCursor,mutationId:o.lastMutationId})}}})}async enqueueOfflineMutation(e,t,s,r,n,i,a){const o=this.identityFingerprint();if(this.outbox){this.outboxMutationCounter+=1;const c=this.outboxMutationCounter;try{await this.outbox.enqueue({args:t,clientId:this.clientId,functionPath:e.__lunoraRef,idempotencyKey:`${this.clientId}:${String(c)}`,identity:o,mutationId:c,shardKey:s})}catch(d){throw E(n),d instanceof Error?d:new Error(String(d))}for(const d of i)d(void 0);return}return new Promise((c,d)=>{const u={args:t,functionPath:e.__lunoraRef,liveAwaiter:!0,id:r,clientId:this.clientId,identity:o,precondition:a,onCommit:l=>{for(const p of i)p(l)},reject:l=>{this.queuedIdentities.delete(r),E(n),d(l instanceof Error?l:new Error(String(l)))},resolve:c,shardKey:s};this.offlineQueue.enqueue(u),this.queuedOfflineShardKeys.add(s),u.id!==void 0&&this.queuedIdentities.set(u.id,o)})}async hydratePersistedQueue(){try{const e=await this.offlineQueue.hydrate();for(const t of e)this.queuedOfflineShardKeys.add(t),this.ensureSocket(t)}catch{}}hydrateAsOutboxLeader(){const e=()=>{this.hydratePersistedQueue().catch(()=>{})},t=globalThis.navigator?.locks;if(!t){e();return}t.request(`lunora:outbox-leader:${this.url}`,()=>(this.closed||e(),new Promise(s=>{if(this.closed){s();return}this.outboxLeaderRelease=s}))).catch(e)}async hydrateQueryCache(){if(this.queryCache)try{const e=await this.queryCache.load();for(const{key:t,...s}of e){if(re(this.persistenceVersion,s.version)){this.queryCache.remove(t).catch(()=>{});continue}this.hydratedQueryCache.set(t,s)}}catch{}}takeHydratedCache(e,t,s){const r=H(e,t,s),n=this.hydratedQueryCache.get(r);if(n!==void 0)return this.hydratedQueryCache.delete(r),n.identity===this.identityFingerprint()?n:void 0}persistQueryValue(e){const t=e.serverBase;if(!this.queryCache||t===void 0)return;const s=H(e.fn.__lunoraRef,e.argsKey,e.shardKey);this.pendingCacheWrites.set(s,{identity:this.identityFingerprint(),serverCursor:e.serverCursor,ts:Date.now(),value:t,...e.serverEpoch===void 0?{}:{serverEpoch:e.serverEpoch},...this.persistenceVersion===void 0?{}:{version:this.persistenceVersion}}),this.cacheFlushTimer??=setTimeout(()=>{this.flushQueryCacheWrites().catch(()=>{})},ye)}async flushQueryCacheWrites(){this.cacheFlushTimer=void 0;const{queryCache:e}=this;if(!e){this.pendingCacheWrites.clear();return}const t=[...this.pendingCacheWrites.entries()];this.pendingCacheWrites.clear(),await Promise.allSettled(t.map(([s,r])=>e.put(s,r)))}computeStatus(){if(this.tabCoordinator&&!this.tabCoordinator.isLeader())return this.leaderStatus??"idle";const e=[...this.connections.values()];return e.length===0?"idle":e.some(t=>t.wsState==="open")?"connected":e.some(t=>t.wsState==="connecting")?"connecting":"offline"}emitConnectionStatus(){const e=this.computeStatus();e!==this.lastStatus&&(this.lastStatus=e,this.statusListeners.emit(e),this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastConnectionStatus(e,this.identityFingerprint()))}emitItemSettled(e,t,s){this.mutationSettledListeners.emit({args:e.args,code:s===void 0?void 0:s.code,error:s,functionPath:e.functionPath,hadAwaiter:e.liveAwaiter??!1,id:e.id??"",shardKey:e.shardKey,status:t})}applyOptimisticUpdates(e,t,s,r){const n=[],i=[];if(!r)return{confirms:n,rollbacks:i};const a=g.key(e,t,s),o=this.subscriptions.get(a);if(o){const c=ee(o,r);c&&(n.push(c.confirm),i.push(c.rollback))}return{confirms:n,rollbacks:i}}applyOptimisticUpdate(e,t,s,r,n){const{confirms:i,rollbacks:a,store:o}=te(this.subscriptions,s);try{e(o,t)}catch{E(a);return}r.push(...a),n.push(...i)}getConnection(e){return this.connections.get(m(e))}sendOrQueueUnsubscribe(e,t,s){const r=this.getConnection(e);r&&!S(r,{id:t,type:s})&&r.pendingUnsubscribes.push({id:t,type:s})}connectionGateState(e){if(this.tabCoordinator&&!this.tabCoordinator.isLeader()){let s="idle";return this.leaderStatus==="connected"?s="open":this.leaderStatus==="connecting"&&(s="connecting"),{hasSocket:!1,wasEverConnected:this.leaderWasEverConnected,wsState:s}}const t=this.getConnection(e);return{hasSocket:t?.socket!==void 0,wasEverConnected:t?.wasEverConnected??!1,wsState:t?.wsState??"idle"}}getOrCreateConnection(e){const t=m(e);let s=this.connections.get(t);return s||(s={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,pendingUnsubscribes:[],reconnect:K(this.reconnectOptions),reconnectTimer:void 0,shardKey:e,socket:void 0,wasEverConnected:!1,wsState:"idle"},this.connections.set(t,s)),s}wsUrlFor(e,t){const s=[];if(e!==void 0&&s.push(`shard=${encodeURIComponent(e)}`),t!==void 0&&s.push(`token=${encodeURIComponent(t)}`),s.length===0)return this.wsUrl;const r=this.wsUrl.includes("?")?"&":"?";return`${this.wsUrl}${r}${s.join("&")}`}rpcRequestHeaders(e,t){const s={"content-type":"application/json"},r=this.shardCursors.get(this.cursorKeyFor(t));if(r!==void 0&&(s["x-lunora-min-seq"]=r.toString()),this.authToken&&(s.authorization=`Bearer ${this.authToken}`),e.mutationId&&(s["x-lunora-mutation-id"]=e.mutationId),(e.clientId!==void 0||e.mutationId!==void 0)&&(s["x-lunora-client-id"]=e.clientId??this.clientId),e.clientSeq!==void 0&&(s["x-lunora-client-seq"]=e.clientSeq.toString()),e.attachBookmark){const n=this.bookmark.get();n&&(s["x-d1-bookmark"]=n)}return s}async rpc(e,t,s,r={}){if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const n=this.rpcRequestHeaders(r,s),i=await this.fetchImpl(k(this.url,de),{body:JSON.stringify({args:v(t,`args for '${e}'`),functionPath:e,shardKey:s}),headers:n,method:"POST"});if(r.captureBookmark){const o=i.headers.get("x-d1-bookmark");o&&this.bookmark.set(o)}let a;try{a=await i.json()}catch{const o=i.statusText?` ${i.statusText}`:"";throw new f("INTERNAL",`LunoraClient: response was not JSON (status ${i.status.toString()}${o})`)}if("error"in a)throw _(a.error);if(!i.ok){const o=i.statusText?` ${i.statusText}`:"";throw new f("INTERNAL",`LunoraClient: request failed (status ${i.status.toString()}${o})`)}return r.onMutationAck?.(a.lastMutationId),r.onCommitCursor?.(a.commitCursor),this.learnDefaultShardKey(i,s),this.recordShardCursor(s,a.commitCursor),b(a.result)}async adminFetch(e,t,s,r){if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const n={};this.authToken&&(n.authorization=`Bearer ${this.authToken}`);const i=s instanceof ArrayBuffer||s instanceof Blob;let a;s===void 0?a=void 0:i?(a=s,r!==void 0&&(n["content-type"]=r)):(a=JSON.stringify(s),n["content-type"]="application/json");const o=await this.fetchImpl(k(this.url,e),{body:a,headers:n,method:t});let c;try{c=await o.json()}catch{const d=o.statusText?` ${o.statusText}`:"";throw new f("INTERNAL",`LunoraClient: response was not JSON (status ${o.status.toString()}${d})`)}if(typeof c=="object"&&c!==null&&"error"in c){const d=c.error,u=new Error(d.message??"admin request failed");throw u.code=d.code,u}if(!o.ok){const d=o.statusText?` ${o.statusText}`:"";throw new f("INTERNAL",`LunoraClient: admin request failed (status ${o.status.toString()}${d})`)}return c}effectiveConnectionContext(e){const t=this.connectionContextHolders.get(e);return t&&t.length>0?t[t.length-1]?.context:this.connectionContexts.get(e)??this.defaultConnectionContext}refreshConnectionContext(e){const t=this.connections.get(e);t?.wsState==="open"&&this.sendConnectEnvelope(t)}sendConnectEnvelope(e){const t=this.effectiveConnectionContext(m(e.shardKey));S(e,{caps:Ft,clientId:this.clientId,id:"connect",type:"connect",...t===void 0?{}:{context:t}})}resendShapeSubscriptions(e){for(const t of this.shapeSubscriptions.values())m(t.shardKey)===m(e)&&this.sendShapeSubscribeIfOpen(t)}ensureSocket(e){if(this.closed||this.WebSocketImpl===void 0||this.tabCoordinator&&!this.tabCoordinator.isLeader())return;const t=this.getOrCreateConnection(e);if(!(t.wsState==="open"||t.wsState==="connecting")){if(t.wsState="connecting",this.emitConnectionStatus(),typeof this.wsToken=="function"){this.openSocketWithProvidedToken(t,e,this.wsToken).catch(()=>{});return}this.openSocket(t,e,this.wsToken)}}async openSocketWithProvidedToken(e,t,s){let r;try{r=await s()}catch{this.handleDisconnect(e);return}this.closed||this.WebSocketImpl===void 0||e.wsState!=="connecting"||e.socket!==void 0||this.openSocket(e,t,r)}openManagedSocket(e,t,s,r){const{WebSocketImpl:n}=this;if(n===void 0)throw new f("INTERNAL","no WebSocket implementation available");const i=new n(t);e.socket=i;const a=()=>{this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket===i&&(e.socket=void 0)},o=c=>{a(),r.onClose(c)};s>0&&(e.connectTimer=setTimeout(()=>{if(e.connectTimer=void 0,e.socket===i){try{i.close()}catch{}o()}},s)),i.addEventListener("open",()=>{e.socket===i&&(e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.lastFrameAt=Date.now(),r.onOpen(),this.startHeartbeat(e,o))}),i.addEventListener("message",c=>{e.socket===i&&(e.lastFrameAt=Date.now(),r.onMessage(c))}),i.addEventListener("close",c=>{e.socket===i&&o(c)}),i.addEventListener("error",()=>{e.socket===i&&o()})}openSocket(e,t,s){this.WebSocketImpl!==void 0&&this.openManagedSocket(e,this.wsUrlFor(t,s),this.connectTimeoutMs,{onClose:r=>{r?.code===4001&&this.notifyTokenExpired(),this.handleDisconnect(e)},onMessage:r=>{this.handleServerMessage(r.data,t)},onOpen:()=>{e.wsState="open",e.wasEverConnected=!0,e.reconnect.reset(),this.emitConnectionStatus(),this.sendConnectEnvelope(e),this.markShardPendingAck(t);for(const n of this.subscriptions.all())m(n.shardKey)===m(t)&&this.sendSubscribeIfOpen(n);if(this.resendShapeSubscriptions(t),e.pendingUnsubscribes.length>0){const n=e.pendingUnsubscribes;e.pendingUnsubscribes=[];for(const{id:i,type:a}of n)S(e,{id:i,type:a})}if(e.pendingStreams&&e.pendingStreams.length>0){const n=e.pendingStreams;e.pendingStreams=[];for(const i of n)S(e,i)}const r=this.whisperHandlers.get(m(t));if(r)for(const n of r.keys())S(e,{topic:n,type:"whisper_subscribe"});this.flushOfflineQueue(t).catch(()=>{})}})}handleDisconnect(e){if(this.closed||e.wsState==="idle"||e.wsState==="closed")return;this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket=void 0,e.wsState="idle",this.emitConnectionStatus(),this.markShardPendingAck(e.shardKey);const t=new Set((e.pendingStreams??[]).map(r=>r.id));for(const[r,n]of this.streams)if(!(m(n.shardKey)!==m(e.shardKey)||t.has(r))){if(n.durable){const i={...n.message,sinceChunk:n.lastSeq};n.message=i,e.pendingStreams=[...(e.pendingStreams??[]).filter(a=>a.id!==r),i];continue}n.handle.fail(new f("STREAM_DISCONNECTED","stream terminated: WebSocket disconnected")),this.streams.delete(r)}if(this.WebSocketImpl===void 0)return;const s=e.reconnect.next();e.reconnectTimer=setTimeout(()=>{e.reconnectTimer=void 0,this.ensureSocket(e.shardKey)},s)}startHeartbeat(e,t){this.stopHeartbeat(e),!(this.heartbeatIntervalMs<=0)&&(e.heartbeatTimer=setInterval(()=>{if(!e.socket)return;const{socket:s}=e;if(Date.now()-e.lastFrameAt>this.heartbeatIntervalMs*2.5){try{s.close()}catch{}t();return}try{s.send(fe)}catch{}},this.heartbeatIntervalMs))}stopHeartbeat(e){e.heartbeatTimer!==void 0&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=void 0)}markShardPendingAck(e){const t=m(e);for(const s of this.subscriptions.all())m(s.shardKey)===t&&(s.acked=!1)}sendSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);if(t?.wsState!=="open"||e.acked)return;const s=e.fn.__lunoraTable??e.fn.__lunoraRef;S(t,{id:e.id,query:{args:D(e.args),functionPath:e.fn.__lunoraRef,table:s,...e.serverCursor===void 0?{}:{sinceSeq:e.serverCursor},...e.serverEpoch===void 0?{}:{sinceEpoch:e.serverEpoch}},type:"subscribe"})}sendShapeSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);t?.wsState==="open"&&S(t,{id:e.id,shape:{name:e.name,...e.wireArgs===void 0?{}:{args:e.wireArgs}},type:"shape_subscribe",...e.serverCursor===void 0?{}:{sinceCheckpoint:e.serverCursor},...e.serverEpoch===void 0?{}:{sinceEpoch:e.serverEpoch}})}handleServerMessage(e,t){const s=Ut(e);if(s===void 0)return;let r;try{r=JSON.parse(s)}catch{return}switch(r.type){case"ack":{const n=this.subscriptions.getById(r.id);n&&(n.acked=!0);return}case"chunk":{const{data:n,id:i,seq:a}=r,o=this.streams.get(i);o&&typeof a=="number"&&(o.lastSeq=a,o.durable=!0),o?.handle.push(b(n));return}case"complete":{this.handleCompleteMessage(r.id);return}case"data":case"delta":{this.handleDataMessage(r);return}case"error":{this.handleErrorMessage(r);break}case"pokeEnd":{this.handlePokeEnd(r);break}case"pokePart":{this.handlePokePart(r);break}case"pokeStart":{this.handlePokeStart(r);break}case"resume":{this.handleResumeMessage(r);break}case"settled":{this.handleSettledMessage(r);break}case"whisper":{this.dispatchWhisper(r,t);break}}}handleErrorMessage(e){if(e.error?.code==="TOKEN_EXPIRED"){this.notifyTokenExpired();return}const{id:s}=e,r=s===void 0?void 0:this.streams.get(s);if(r&&s!==void 0){r.handle.fail(Lt(e)),this.streams.delete(s);return}const n=s===void 0?void 0:this.subscriptions.getById(s);if(n){A(n.errorCallbacks,q(e));return}const i=s===void 0?void 0:this.shapeSubscriptions.get(s);i&&A(i.errorCallbacks,q(e))}handlePokeStart(e){he(this.pokeBuffers,Q.MAX_POKE_BUFFERS),this.pokeBuffers.set(e.pokeId,{baseCheckpoint:e.baseCheckpoint,epoch:e.epoch,lastMutationId:new Map,parts:new Map})}handlePokePart(e){const t=this.pokeBuffers.get(e.pokeId);if(!t)return;const s=t.parts.get(e.shapeId)??[];for(const r of e.rowsPatch)s.push(r.value===void 0?r:{...r,value:b(r.value)});t.parts.set(e.shapeId,s),e.lastMutationId!==void 0&&t.lastMutationId.set(e.shapeId,e.lastMutationId)}handlePokeEnd(e){const t=this.pokeBuffers.get(e.pokeId);if(t){this.pokeBuffers.delete(e.pokeId);for(const[s,r]of t.parts){const n=this.shapeSubscriptions.get(s);if(!n)continue;const i=t.epoch!==void 0&&n.serverEpoch!==void 0&&t.epoch!==n.serverEpoch,a=t.baseCheckpoint!==void 0&&n.serverCursor!==void 0&&n.serverCursor!==t.baseCheckpoint;if(i||a){n.rows.clear(),n.serverCursor=void 0,n.serverEpoch=void 0,this.emitShapeRows(n),this.sendShapeSubscribeIfOpen(n);continue}le(n.rows,r),e.checkpoint!==void 0&&(n.serverCursor=e.checkpoint),e.epoch!==void 0&&(n.serverEpoch=e.epoch);const o=t.lastMutationId.get(s);o!==void 0&&(n.lastMutationId=o),this.emitShapeRows(n),n.onCheckpoint?.({checkpoint:n.serverCursor,mutationId:n.lastMutationId})}}}emitShapeRows(e){const t=[...e.rows.values()];for(const s of e.callbacks)try{s(t)}catch{}}handleDataMessage(e){const{id:t}=e,s=t?this.subscriptions.getById(t):void 0;if(!s)return;const r=this.resolveDataPayload(e,s);if(s.serverBase=r,e.cursor!==void 0&&(s.serverCursor=e.cursor),e.epoch!==void 0&&(s.serverEpoch=e.epoch),e.lastMutationId!==void 0){s.lastMutationId=Math.max(s.lastMutationId??0,e.lastMutationId);for(const n of s.checkpointCallbacks)n({checkpoint:s.serverCursor,mutationId:s.lastMutationId})}if(this.persistQueryValue(s),O(s,s.serverCursor),P(s,R(r,s.optimisticLayers)),this.tabCoordinator?.isLeader()){const n=g.key(s.fn.__lunoraRef,s.args,s.shardKey);this.tabCoordinator.broadcastSubscriptionData(n,r,s.serverCursor,s.serverEpoch,this.identityFingerprint())}}handleResumeMessage(e){const t=this.subscriptions.getById(e.id);t&&this.ackAndAdvanceCursor(t,e.cursor,e.epoch)}handleSettledMessage(e){const t=this.subscriptions.getById(e.id);if(t){this.ackAndAdvanceCursor(t,e.cursor,e.epoch),e.lastMutationId!==void 0&&(t.lastMutationId=e.lastMutationId);for(const s of t.checkpointCallbacks)s({checkpoint:t.serverCursor,mutationId:t.lastMutationId});if(this.tabCoordinator?.isLeader()){const s=g.key(t.fn.__lunoraRef,t.args,t.shardKey);this.tabCoordinator.broadcastSubscriptionSettled(s,t.serverCursor,t.serverEpoch,t.lastMutationId,this.clientId,this.identityFingerprint())}}}ackAndAdvanceCursor(e,t,s){e.acked=!0,(t!==void 0&&t!==e.serverCursor||s!==void 0&&s!==e.serverEpoch)&&(t!==void 0&&(e.serverCursor=t),s!==void 0&&(e.serverEpoch=s),this.persistQueryValue(e),O(e,e.serverCursor)&&P(e,R(e.serverBase,e.optimisticLayers)))}resolveDataPayload(e,t){if("data"in e&&e.data!==void 0)return b(e.data);const s=b(e.delta);if(z(s)&&t.serverBase!==void 0){const r=V(t.serverBase,s);if(r!==void 0)return r}return s}dispatchWhisper(e,t){const s=this.whisperHandlers.get(m(t))?.get(e.topic);if(!s)return;const r=b(e.data);for(const n of s)try{n(r,e.from)}catch{}}notifyTokenExpired(){this.tokenExpiredListeners.emit()}handleCompleteMessage(e){const t=this.streams.get(e);if(t){t.handle.complete(),this.streams.delete(e);return}const s=this.subscriptions.getById(e);s&&(s.acked=!1,A(s.errorCallbacks,{code:"SUBSCRIPTION_CANCELLED",message:"subscription was cancelled by the server"}))}unpersist(e){e&&this.persistence?.remove(e).catch(t=>{ne(this.onPersistenceError,"remove",t,e)})}identityFingerprint(){if(this.authSubject!==void 0)return this.authSubject===null?null:`subj:${this.authSubject}`;const e=this.authToken;return e===null?null:this.hashToken(e)}hashToken(e){let t=2166136261,s=5381;for(let r=0;r<e.length;r+=1){const n=e.charCodeAt(r);t^=n,t=Math.imul(t,16777619),s=Math.imul(s,33)+n}return`${e.length.toString(36)}:${(t>>>0).toString(36)}:${(s>>>0).toString(36)}`}isSameCredentialUnderTokenHash(e){if(e===null||e.startsWith("subj:"))return!1;const t=this.authToken;return t===null?!1:this.hashToken(t)===e}rejectQueuedForIdentityChange(){const e=this.offlineQueue.drain();for(const t of e){this.queuedIdentities.delete(t.id??""),this.unpersist(t.id);const s=new Error("offline mutation discarded: auth identity changed before replay");s.code="OFFLINE_IDENTITY_CHANGED",t.reject(s),this.emitItemSettled(t,"rejected",s)}this.clearQueryCacheForIdentityChange()}restampQueuedIdentity(e,t){for(const[s,r]of this.queuedIdentities)r===e&&this.queuedIdentities.set(s,t)}restampWatermarks(e,t){const s=e??"",r=this.clientWatermarks.get(s);if(r===void 0)return;this.clientWatermarks.delete(s);const n=t??"",i=this.clientWatermarks.get(n);if(i===void 0)this.clientWatermarks.set(n,r);else for(const[a,o]of r)i.set(a,o)}clearQueryCacheForIdentityChange(){this.cacheFlushTimer!==void 0&&(clearTimeout(this.cacheFlushTimer),this.cacheFlushTimer=void 0),this.pendingCacheWrites.clear(),this.hydratedQueryCache.clear(),this.queryCache?.clear().catch(()=>{})}flushAllOfflineQueues(){for(const e of this.queuedOfflineShardKeys)this.flushOfflineQueue(e).catch(()=>{})}async flushOfflineQueue(e){const t=this.offlineQueue.drainConflict();for(const c of t){this.unpersist(c.id),this.queuedIdentities.delete(c.id??"");const d=new Error("offline mutation skipped: precondition failed before replay");d.code="OFFLINE_PRECONDITION_FAILED",this.emitItemSettled(c,"rejected",d)}const s=m(e),r=this.offlineQueue.drain(c=>m(c.shardKey)===s);if(r.length===0)return;const n=this.identityFingerprint(),i=[];for(const c of r)this.passesReplayIdentityGate(c,n)&&i.push(c);if(i.length===0)return;const a=this.encodableOrSettleTerminal(i);if(a.length===0)return;if(a.length===1){await this.replaySequential(a);return}const o=[];for(let c=0;c<a.length;c+=F){const d=a.slice(c,c+F),u=await this.replayBatched(d);if(o.push(...u.requeue),u.stop){o.push(...a.slice(c+F));break}}o.length>0&&this.offlineQueue.requeue(o)}encodableOrSettleTerminal(e){const t=[];for(const s of e)try{v(s.args,`args for '${s.functionPath}'`),t.push(s)}catch(r){this.settleReplayTerminal(s,r instanceof Error?r:new Error(String(r)))}return t}passesReplayIdentityGate(e,t){const s=e.id===void 0?void 0:this.queuedIdentities.get(e.id),r=s===void 0?e.identity:s;if(r!==void 0&&r!==t&&!this.isSameCredentialUnderTokenHash(r)){this.queuedIdentities.delete(e.id??""),this.unpersist(e.id);const n=new Error("offline mutation skipped: auth identity changed before replay");return n.code="OFFLINE_IDENTITY_CHANGED",e.reject(n),this.emitItemSettled(e,"rejected",n),!1}return this.queuedIdentities.delete(e.id??""),!0}settleReplaySuccess(e,t,s){this.unpersist(e.id),this.recordShardCursor(e.shardKey,s),e.onCommit?.(s),e.resolve(t),this.emitItemSettled(e,"committed")}cursorKeyFor(e){return e??this.defaultShardKey??""}learnDefaultShardKey(e,t){const s=e.headers.get("x-lunora-shard-key");if(s===null||t!==void 0||this.defaultShardKey===s)return;this.defaultShardKey=s;const r=this.shardCursors.get("");r!==void 0&&(this.shardCursors.set(s,Math.max(this.shardCursors.get(s)??0,r)),this.shardCursors.delete(""))}recordShardCursor(e,t){if(typeof t!="number")return;const s=this.cursorKeyFor(e);this.shardCursors.set(s,Math.max(this.shardCursors.get(s)??0,t))}settleReplayTerminal(e,t){this.unpersist(e.id),e.reject(t),this.emitItemSettled(e,"rejected",t)}async replaySequential(e){for(let t=0;t<e.length;t+=1){const s=e[t];if(s)try{let r;const n=await this.rpc(s.functionPath,s.args,s.shardKey,{captureBookmark:!0,clientId:s.clientId??this.clientId,mutationId:s.id,onCommitCursor:i=>{r=i}});this.settleReplaySuccess(s,n,r)}catch(r){if(r.code!==void 0){this.settleReplayTerminal(s,r);continue}this.offlineQueue.requeue(e.slice(t));return}}}async replayBatched(e){if(!this.fetchImpl)return{requeue:e,stop:!0};let t;try{t=await this.fetchImpl(k(this.url,B),{body:JSON.stringify({calls:e.map((n,i)=>({args:v(n.args,`args for '${n.functionPath}'`),functionPath:n.functionPath,id:i,clientId:n.clientId??this.clientId,mutationId:n.id,shardKey:n.shardKey}))}),headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"})}catch{return{requeue:e,stop:!0}}const s=t.headers.get("x-d1-bookmark");s&&this.bookmark.set(s);let r;try{r=await t.json()}catch{return{requeue:e,stop:!0}}if(!r.results){if(r.error){const n=_(r.error);for(const i of e)this.settleReplayTerminal(i,n);return{requeue:[],stop:!1}}return{requeue:e,stop:!0}}return{requeue:this.settleReplayBatchSlots(e,r.results),stop:!1}}settleReplayBatchSlots(e,t){const s=new Map;for(const n of t)typeof n.id=="number"&&n.body!==void 0&&s.set(n.id,n.body);const r=[];for(const[n,i]of e.entries()){const a=s.get(n);a===void 0?r.push(i):"error"in a?Nt.has(a.error.code)?r.push(i):this.settleReplayTerminal(i,_(a.error)):this.settleReplaySuccess(i,b(a.result),a.commitCursor)}return r}}export{Q as LunoraClient};
|
package/dist/packem_shared/{SubscriptionRegistry-D5Xu-a39.mjs → SubscriptionRegistry-BF75d3VP.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{s as i}from"./wire-key-
|
|
1
|
+
import{s as i}from"./wire-key-HxFZXRbI.mjs";class r{static key(e,y,d){return`${e}::${i(y)}::${d??""}`}byKey=new Map;byId=new Map;get(e){return this.byKey.get(e)}getById(e){return this.byId.get(e)}add(e){this.byKey.set(r.key(e.fn.__lunoraRef,e.args,e.shardKey),e),this.byId.set(e.id,e)}remove(e){const y=r.key(e.fn.__lunoraRef,e.args,e.shardKey);this.byKey.get(y)===e&&this.byKey.delete(y),this.byId.delete(e.id)}all(){return[...this.byKey.values()]}}export{r as SubscriptionRegistry};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s=(c,r)=>{let n=0,e=0;return async(i,l)=>{e+=1;const o=e;n+=1,r.setPending(!0);try{const t=await c(i,l);return o===e&&r.setResult(t),t}catch(t){const a=t instanceof Error?t:new Error(String(t));throw o===e&&r.setError(a),a}finally{n-=1,r.setPending(n>0)}}};export{s as createCallRunner};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as t}from"./local-store-Bb62Gev5.mjs";import"./SubscriptionRegistry-BF75d3VP.mjs";export{t as createLocalStore};
|
package/dist/packem_shared/{createServerClient-BxPCzuUt.mjs → createServerClient-CNzt_8I6.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraClient as r}from"./LunoraClient-
|
|
1
|
+
import{LunoraClient as r}from"./LunoraClient-Cgu6xN-X.mjs";const c=e=>{const t=new r({fetch:e.fetch,url:e.url});return e.token!==void 0&&t.setAuthToken(e.token),t};export{c as createServerClient};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as a}from"./wire-key-HxFZXRbI.mjs";const c=(t,r,n,o)=>{const e=t.peekActiveQuerySnapshot(r.__lunoraRef,n,o),p=e.present?a(e.value):void 0;return()=>{const s=t.peekActiveQuerySnapshot(r.__lunoraRef,n,o);return!e.present||!s.present?!0:a(s.value)===p}};export{c as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SubscriptionRegistry as m}from"./SubscriptionRegistry-
|
|
1
|
+
import{SubscriptionRegistry as m}from"./SubscriptionRegistry-BF75d3VP.mjs";const p=(r,o)=>{let e=r;for(const i of o)try{e=i.transform(e)}catch{}return e},u=(r,o)=>{if(o!==r.lastValue){r.lastValue=o;for(const e of r.callbacks)try{e(o)}catch{}}},y=(r,o)=>{let e;try{e=o(r.lastValue)}catch{return}const i={id:Symbol("optimistic"),transform:o};r.optimisticLayers.push(i),u(r,e);const c=()=>{const t=r.optimisticLayers.findIndex(s=>s.id===i.id);return t===-1?!1:(r.optimisticLayers.splice(t,1),!0)},a=()=>{u(r,p(r.serverBase,r.optimisticLayers))};return{confirm:t=>{if(t===void 0){c();return}i.commitCursor=t,r.serverCursor!==void 0&&r.serverCursor>=t&&c()&&a()},rollback:()=>{c()&&a()}}},h=(r,o)=>{if(o===void 0||r.optimisticLayers.length===0)return!1;const e=r.optimisticLayers.length;return r.optimisticLayers=r.optimisticLayers.filter(i=>i.commitCursor===void 0||i.commitCursor>o),r.optimisticLayers.length!==e},L=(r,o)=>{const e=[],i=[],c=(t,s)=>r.get(m.key(t,s,o));return{confirms:e,rollbacks:i,store:{getAllQueries:t=>{const s=[];for(const n of r.all())n.fn.__lunoraRef===t.__lunoraRef&&(n.shardKey??"")===(o??"")&&s.push({args:n.args,value:n.lastValue});return s},getQuery:(t,s)=>c(t.__lunoraRef,s??{})?.lastValue,setQuery:(t,s,n)=>{const f=c(t.__lunoraRef,s??{});if(!f)return;const l=y(f,()=>n);l&&(e.push(l.confirm),i.push(l.rollback))}}}};export{y as a,L as c,h as d,p as f,u as n};
|
|
@@ -387,6 +387,19 @@ interface MutationSettledEvent {
|
|
|
387
387
|
/** Terminal outcome. */
|
|
388
388
|
readonly status: "committed" | "rejected";
|
|
389
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* Per-call options for {@link LunoraClient.action} — just `shardKey`, since an
|
|
392
|
+
* action is not a write and carries none of the optimistic machinery. Exported
|
|
393
|
+
* (at the end of this file) for the same reason {@link MutationCallOptions} is:
|
|
394
|
+
* so the framework adapters (`@lunora/react`, `/solid`, `/svelte`, `/vue`,
|
|
395
|
+
* `/angular`) type their `call(args, options?)` against one canonical
|
|
396
|
+
* definition. Add an option here and every adapter forwards it; re-declare it
|
|
397
|
+
* per adapter and they silently cannot.
|
|
398
|
+
*/
|
|
399
|
+
interface ActionCallOptions {
|
|
400
|
+
/** Route the call to a specific shard. */
|
|
401
|
+
shardKey?: string;
|
|
402
|
+
}
|
|
390
403
|
/**
|
|
391
404
|
* Per-call options for {@link LunoraClient.mutation} — the optimistic-update
|
|
392
405
|
* machinery plus `shardKey`. Exported (at the end of this file) so the framework
|
|
@@ -952,13 +965,9 @@ declare class LunoraClient {
|
|
|
952
965
|
* produce a `() => boolean` precondition that compares it against the
|
|
953
966
|
* value at replay time (on queue drain / reconnect).
|
|
954
967
|
*
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
* mutation is dropped as stale.
|
|
959
|
-
*
|
|
960
|
-
* This is a method wrapper around `createSnapshotPrecondition` that
|
|
961
|
-
* binds the client instance for you — no need to pass `client` explicitly.
|
|
968
|
+
* Delegates to {@link createSnapshotPrecondition} with this client bound —
|
|
969
|
+
* no need to pass `client` explicitly. The comparison semantics (including
|
|
970
|
+
* how an absent subscription is treated) live there, in one place.
|
|
962
971
|
* @example
|
|
963
972
|
* ```ts
|
|
964
973
|
* client.mutation(api.todos.update, { id, text }, {
|
|
@@ -999,18 +1008,26 @@ declare class LunoraClient {
|
|
|
999
1008
|
*/
|
|
1000
1009
|
peekHydratedQuery(functionPath: string, args: Record<string, unknown>, shardKey?: string): unknown;
|
|
1001
1010
|
/**
|
|
1002
|
-
* Peek at the **current live value** of an active subscription,
|
|
1003
|
-
* exists
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1011
|
+
* Peek at the **current live value** of an active subscription, reporting
|
|
1012
|
+
* whether one exists at all rather than just its value. `present` is `false`
|
|
1013
|
+
* when no subscription is open for the given `(functionPath, args, shardKey)`;
|
|
1014
|
+
* `value` is the subscription's `lastValue`, which includes any optimistic
|
|
1015
|
+
* overlay.
|
|
1016
|
+
*
|
|
1017
|
+
* The two are separate because a caller like the snapshot precondition has to
|
|
1018
|
+
* tell "no subscription is active, so this read knows nothing" apart from
|
|
1019
|
+
* "the subscription is active and its value is `undefined`" — collapsing both
|
|
1020
|
+
* into a bare `undefined` return makes an unmounted component look like a
|
|
1021
|
+
* changed value, and drops the queued write.
|
|
1006
1022
|
*
|
|
1007
1023
|
* Unlike {@link peekHydratedQuery} (which reads from the durable read cache
|
|
1008
|
-
* and is independent of active subscriptions), this
|
|
1009
|
-
*
|
|
1010
|
-
* offline mutation preconditions that need to snapshot the value at call time
|
|
1011
|
-
* and compare it at replay time.
|
|
1024
|
+
* and is independent of active subscriptions), this reflects the current
|
|
1025
|
+
* in-memory state of an already-opened subscription.
|
|
1012
1026
|
*/
|
|
1013
|
-
|
|
1027
|
+
peekActiveQuerySnapshot(functionPath: string, args: Record<string, unknown>, shardKey?: string): {
|
|
1028
|
+
present: boolean;
|
|
1029
|
+
value: unknown;
|
|
1030
|
+
};
|
|
1014
1031
|
query<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: {
|
|
1015
1032
|
shardKey?: string;
|
|
1016
1033
|
}): Promise<ReturnOf<F>>;
|
|
@@ -1044,9 +1061,7 @@ declare class LunoraClient {
|
|
|
1044
1061
|
* `OfflineQueueOptions.queueBeforeFirstConnect`.
|
|
1045
1062
|
*/
|
|
1046
1063
|
mutation<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>): Promise<ReturnOf<F>>;
|
|
1047
|
-
action<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?:
|
|
1048
|
-
shardKey?: string;
|
|
1049
|
-
}): Promise<ReturnOf<F>>;
|
|
1064
|
+
action<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: ActionCallOptions): Promise<ReturnOf<F>>;
|
|
1050
1065
|
/**
|
|
1051
1066
|
* Bulk-import `rows` through a mutation that accepts a batch, chunked so a large
|
|
1052
1067
|
* dataset lands in a bounded number of round-trips.
|
|
@@ -2248,4 +2263,4 @@ declare class LunoraClient {
|
|
|
2248
2263
|
*/
|
|
2249
2264
|
private settleReplayBatchSlots;
|
|
2250
2265
|
}
|
|
2251
|
-
export { BatchSlot as B, ConnectionStatus as C, DEFAULT_MAX_BUFFER as D, LunoraClient as L, MutationCallOptions as M, OptimisticLocalStore as O, SubscriptionError as S, SubscriptionErrorCallback as a, StreamIterable as b, CONFLICT_ERROR_CODE as c, ClientDebugShard as d, ClientDebugSnapshot as e, ClientDebugSubscription as f, ClientQueryRef as g, LunoraClientError as h, LunoraErrorCode as i, MutationSettledEvent as j, OptimisticUpdate as k, StreamHandle as l, SubscriptionCallback as m, SubscriptionRegistry as n, SubscriptionState as o, SyncWatermark as p, createClientQuery as q, createLocalStore as r, createStream as s, getErrorCode as t, getRetryAfterMs as u, isConflictError as v, isForbiddenError as w, isRateLimitedError as x, isUnauthorizedError as y };
|
|
2266
|
+
export { ActionCallOptions as A, BatchSlot as B, ConnectionStatus as C, DEFAULT_MAX_BUFFER as D, LunoraClient as L, MutationCallOptions as M, OptimisticLocalStore as O, SubscriptionError as S, SubscriptionErrorCallback as a, StreamIterable as b, CONFLICT_ERROR_CODE as c, ClientDebugShard as d, ClientDebugSnapshot as e, ClientDebugSubscription as f, ClientQueryRef as g, LunoraClientError as h, LunoraErrorCode as i, MutationSettledEvent as j, OptimisticUpdate as k, StreamHandle as l, SubscriptionCallback as m, SubscriptionRegistry as n, SubscriptionState as o, SyncWatermark as p, createClientQuery as q, createLocalStore as r, createStream as s, getErrorCode as t, getRetryAfterMs as u, isConflictError as v, isForbiddenError as w, isRateLimitedError as x, isUnauthorizedError as y };
|
package/dist/packem_shared/{lunora-client.d-BOmxvSrG.d.mts → lunora-client.d-Dkd6-fpN.d.mts}
RENAMED
|
@@ -387,6 +387,19 @@ interface MutationSettledEvent {
|
|
|
387
387
|
/** Terminal outcome. */
|
|
388
388
|
readonly status: "committed" | "rejected";
|
|
389
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* Per-call options for {@link LunoraClient.action} — just `shardKey`, since an
|
|
392
|
+
* action is not a write and carries none of the optimistic machinery. Exported
|
|
393
|
+
* (at the end of this file) for the same reason {@link MutationCallOptions} is:
|
|
394
|
+
* so the framework adapters (`@lunora/react`, `/solid`, `/svelte`, `/vue`,
|
|
395
|
+
* `/angular`) type their `call(args, options?)` against one canonical
|
|
396
|
+
* definition. Add an option here and every adapter forwards it; re-declare it
|
|
397
|
+
* per adapter and they silently cannot.
|
|
398
|
+
*/
|
|
399
|
+
interface ActionCallOptions {
|
|
400
|
+
/** Route the call to a specific shard. */
|
|
401
|
+
shardKey?: string;
|
|
402
|
+
}
|
|
390
403
|
/**
|
|
391
404
|
* Per-call options for {@link LunoraClient.mutation} — the optimistic-update
|
|
392
405
|
* machinery plus `shardKey`. Exported (at the end of this file) so the framework
|
|
@@ -952,13 +965,9 @@ declare class LunoraClient {
|
|
|
952
965
|
* produce a `() => boolean` precondition that compares it against the
|
|
953
966
|
* value at replay time (on queue drain / reconnect).
|
|
954
967
|
*
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
* mutation is dropped as stale.
|
|
959
|
-
*
|
|
960
|
-
* This is a method wrapper around `createSnapshotPrecondition` that
|
|
961
|
-
* binds the client instance for you — no need to pass `client` explicitly.
|
|
968
|
+
* Delegates to {@link createSnapshotPrecondition} with this client bound —
|
|
969
|
+
* no need to pass `client` explicitly. The comparison semantics (including
|
|
970
|
+
* how an absent subscription is treated) live there, in one place.
|
|
962
971
|
* @example
|
|
963
972
|
* ```ts
|
|
964
973
|
* client.mutation(api.todos.update, { id, text }, {
|
|
@@ -999,18 +1008,26 @@ declare class LunoraClient {
|
|
|
999
1008
|
*/
|
|
1000
1009
|
peekHydratedQuery(functionPath: string, args: Record<string, unknown>, shardKey?: string): unknown;
|
|
1001
1010
|
/**
|
|
1002
|
-
* Peek at the **current live value** of an active subscription,
|
|
1003
|
-
* exists
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1011
|
+
* Peek at the **current live value** of an active subscription, reporting
|
|
1012
|
+
* whether one exists at all rather than just its value. `present` is `false`
|
|
1013
|
+
* when no subscription is open for the given `(functionPath, args, shardKey)`;
|
|
1014
|
+
* `value` is the subscription's `lastValue`, which includes any optimistic
|
|
1015
|
+
* overlay.
|
|
1016
|
+
*
|
|
1017
|
+
* The two are separate because a caller like the snapshot precondition has to
|
|
1018
|
+
* tell "no subscription is active, so this read knows nothing" apart from
|
|
1019
|
+
* "the subscription is active and its value is `undefined`" — collapsing both
|
|
1020
|
+
* into a bare `undefined` return makes an unmounted component look like a
|
|
1021
|
+
* changed value, and drops the queued write.
|
|
1006
1022
|
*
|
|
1007
1023
|
* Unlike {@link peekHydratedQuery} (which reads from the durable read cache
|
|
1008
|
-
* and is independent of active subscriptions), this
|
|
1009
|
-
*
|
|
1010
|
-
* offline mutation preconditions that need to snapshot the value at call time
|
|
1011
|
-
* and compare it at replay time.
|
|
1024
|
+
* and is independent of active subscriptions), this reflects the current
|
|
1025
|
+
* in-memory state of an already-opened subscription.
|
|
1012
1026
|
*/
|
|
1013
|
-
|
|
1027
|
+
peekActiveQuerySnapshot(functionPath: string, args: Record<string, unknown>, shardKey?: string): {
|
|
1028
|
+
present: boolean;
|
|
1029
|
+
value: unknown;
|
|
1030
|
+
};
|
|
1014
1031
|
query<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: {
|
|
1015
1032
|
shardKey?: string;
|
|
1016
1033
|
}): Promise<ReturnOf<F>>;
|
|
@@ -1044,9 +1061,7 @@ declare class LunoraClient {
|
|
|
1044
1061
|
* `OfflineQueueOptions.queueBeforeFirstConnect`.
|
|
1045
1062
|
*/
|
|
1046
1063
|
mutation<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>): Promise<ReturnOf<F>>;
|
|
1047
|
-
action<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?:
|
|
1048
|
-
shardKey?: string;
|
|
1049
|
-
}): Promise<ReturnOf<F>>;
|
|
1064
|
+
action<F extends FunctionReference>(function_: F, args: ArgsOf<F>, options?: ActionCallOptions): Promise<ReturnOf<F>>;
|
|
1050
1065
|
/**
|
|
1051
1066
|
* Bulk-import `rows` through a mutation that accepts a batch, chunked so a large
|
|
1052
1067
|
* dataset lands in a bounded number of round-trips.
|
|
@@ -2248,4 +2263,4 @@ declare class LunoraClient {
|
|
|
2248
2263
|
*/
|
|
2249
2264
|
private settleReplayBatchSlots;
|
|
2250
2265
|
}
|
|
2251
|
-
export { BatchSlot as B, ConnectionStatus as C, DEFAULT_MAX_BUFFER as D, LunoraClient as L, MutationCallOptions as M, OptimisticLocalStore as O, SubscriptionError as S, SubscriptionErrorCallback as a, StreamIterable as b, CONFLICT_ERROR_CODE as c, ClientDebugShard as d, ClientDebugSnapshot as e, ClientDebugSubscription as f, ClientQueryRef as g, LunoraClientError as h, LunoraErrorCode as i, MutationSettledEvent as j, OptimisticUpdate as k, StreamHandle as l, SubscriptionCallback as m, SubscriptionRegistry as n, SubscriptionState as o, SyncWatermark as p, createClientQuery as q, createLocalStore as r, createStream as s, getErrorCode as t, getRetryAfterMs as u, isConflictError as v, isForbiddenError as w, isRateLimitedError as x, isUnauthorizedError as y };
|
|
2266
|
+
export { ActionCallOptions as A, BatchSlot as B, ConnectionStatus as C, DEFAULT_MAX_BUFFER as D, LunoraClient as L, MutationCallOptions as M, OptimisticLocalStore as O, SubscriptionError as S, SubscriptionErrorCallback as a, StreamIterable as b, CONFLICT_ERROR_CODE as c, ClientDebugShard as d, ClientDebugSnapshot as e, ClientDebugSubscription as f, ClientQueryRef as g, LunoraClientError as h, LunoraErrorCode as i, MutationSettledEvent as j, OptimisticUpdate as k, StreamHandle as l, SubscriptionCallback as m, SubscriptionRegistry as n, SubscriptionState as o, SyncWatermark as p, createClientQuery as q, createLocalStore as r, createStream as s, getErrorCode as t, getRetryAfterMs as u, isConflictError as v, isForbiddenError as w, isRateLimitedError as x, isUnauthorizedError as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LunoraClient } from "./lunora-client.d-
|
|
1
|
+
import { L as LunoraClient } from "./lunora-client.d-DT9XhMHZ.js";
|
|
2
2
|
import { F as FunctionReference, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./types.d-CsuRAQvb.js";
|
|
3
3
|
/**
|
|
4
4
|
* Run a query once on the server (during SSR) and capture its result in a
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L as LunoraClient } from "./lunora-client.d-
|
|
1
|
+
import { L as LunoraClient } from "./lunora-client.d-Dkd6-fpN.mjs";
|
|
2
2
|
import { F as FunctionReference, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./types.d-CsuRAQvb.mjs";
|
|
3
3
|
/**
|
|
4
4
|
* Run a query once on the server (during SSR) and capture its result in a
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{e as c}from"./wire-codec-D4iww4NV.mjs";const f=(t,n)=>t<n?-1:t>n?1:0,e=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(typeof t=="number"){if(Number.isNaN(t))return"nan";if(t===1/0)return"inf";if(t===-1/0)return"-inf";if(Object.is(t,-0))return"-0"}if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(r=>e(r)).join(",")}]`;const n=Object.getPrototypeOf(t);if(n!==null&&n!==Object.prototype){const r=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const i=t,y=Object.keys(i).toSorted(f),o=[];for(const r of y){const s=i[r];s!==void 0&&o.push(`${JSON.stringify(r)}:${e(s)}`)}return`{${o.join(",")}}`},p=t=>e(c(t));export{p as s};
|
package/dist/query/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SubscriptionError, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { S as SubscriptionError, L as LunoraClient } from "../packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
2
2
|
export type {
|
|
3
3
|
/**
|
|
4
4
|
* `@lunora/client/query` — the framework-neutral live-query state machine shared
|
|
@@ -10,7 +10,7 @@ export type {
|
|
|
10
10
|
* framework — each adapter supplies thin sinks that write into its own ref /
|
|
11
11
|
* store / signal / cache.
|
|
12
12
|
*/
|
|
13
|
-
a as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-
|
|
13
|
+
a as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
14
14
|
import { F as FunctionReference, A as ArgsOf, R as ReturnOf, a as Unsubscribe } from "../packem_shared/types.d-CsuRAQvb.mjs";
|
|
15
15
|
import '@lunora/runtime';
|
|
16
16
|
/**
|
package/dist/query/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SubscriptionError, L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
1
|
+
import { S as SubscriptionError, L as LunoraClient } from "../packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
2
2
|
export type {
|
|
3
3
|
/**
|
|
4
4
|
* `@lunora/client/query` — the framework-neutral live-query state machine shared
|
|
@@ -10,7 +10,7 @@ export type {
|
|
|
10
10
|
* framework — each adapter supplies thin sinks that write into its own ref /
|
|
11
11
|
* store / signal / cache.
|
|
12
12
|
*/
|
|
13
|
-
a as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-
|
|
13
|
+
a as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
14
14
|
import { F as FunctionReference, A as ArgsOf, R as ReturnOf, a as Unsubscribe } from "../packem_shared/types.d-CsuRAQvb.js";
|
|
15
15
|
import '@lunora/runtime';
|
|
16
16
|
/**
|
package/dist/ssr/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { P as Preloaded } from "../packem_shared/types.d-CsuRAQvb.mjs";
|
|
2
2
|
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/types.d-CsuRAQvb.mjs";
|
|
3
|
-
import { L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
3
|
+
import { L as LunoraClient } from "../packem_shared/lunora-client.d-Dkd6-fpN.mjs";
|
|
4
4
|
export {
|
|
5
5
|
/**
|
|
6
6
|
* `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
|
|
@@ -21,7 +21,7 @@ p as preloadQuery,
|
|
|
21
21
|
* WebSocket or touches a UI framework, so it is safe to import from any SSR
|
|
22
22
|
* loader.
|
|
23
23
|
*/
|
|
24
|
-
a as preloadedQueryResult } from "../packem_shared/preload.d-
|
|
24
|
+
a as preloadedQueryResult } from "../packem_shared/preload.d-CxLsgsd8.mjs";
|
|
25
25
|
import '@lunora/runtime';
|
|
26
26
|
/**
|
|
27
27
|
* Structural shape of a better-auth `getSession` call's resolved value.
|
package/dist/ssr/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { P as Preloaded } from "../packem_shared/types.d-CsuRAQvb.js";
|
|
2
2
|
export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/types.d-CsuRAQvb.js";
|
|
3
|
-
import { L as LunoraClient } from "../packem_shared/lunora-client.d-
|
|
3
|
+
import { L as LunoraClient } from "../packem_shared/lunora-client.d-DT9XhMHZ.js";
|
|
4
4
|
export {
|
|
5
5
|
/**
|
|
6
6
|
* `@lunora/client/ssr` — the framework-neutral server contract that every Lunora
|
|
@@ -21,7 +21,7 @@ p as preloadQuery,
|
|
|
21
21
|
* WebSocket or touches a UI framework, so it is safe to import from any SSR
|
|
22
22
|
* loader.
|
|
23
23
|
*/
|
|
24
|
-
a as preloadedQueryResult } from "../packem_shared/preload.d-
|
|
24
|
+
a as preloadedQueryResult } from "../packem_shared/preload.d-Ch-D-Pfo.js";
|
|
25
25
|
import '@lunora/runtime';
|
|
26
26
|
/**
|
|
27
27
|
* Structural shape of a better-auth `getSession` call's resolved value.
|
package/dist/ssr/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getServerSession as o}from"../packem_shared/getServerSession-BaOoo1p6.mjs";import{deserializePreloaded as l,serializePreloaded as t}from"../packem_shared/deserializePreloaded-CHfOFpka.mjs";import{createServerClient as i}from"../packem_shared/createServerClient-
|
|
1
|
+
import{getServerSession as o}from"../packem_shared/getServerSession-BaOoo1p6.mjs";import{deserializePreloaded as l,serializePreloaded as t}from"../packem_shared/deserializePreloaded-CHfOFpka.mjs";import{createServerClient as i}from"../packem_shared/createServerClient-CNzt_8I6.mjs";import{preloadQuery as s,preloadedQueryResult as f}from"../packem_shared/preloadQuery-uFy24PCR.mjs";export{i as createServerClient,l as deserializePreloaded,o as getServerSession,s as preloadQuery,f as preloadedQueryResult,t as serializePreloaded};
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as f}from"@lunora/errors";import{i as z,a as V,P as j}from"./delta-merge-BoVuM-rE.mjs";import{d as b,e as D}from"./wire-codec-D4iww4NV.mjs";import{s as E}from"./wire-key-BEmRM5ls.mjs";import J from"./createInMemoryBookmarkStorage-BooZhW0n.mjs";import{ClientQueryStore as Y}from"./createClientQuery-TKD_52cT.mjs";import{TabCoordinator as X}from"./TabCoordinator-DVKG2RlZ.mjs";import{httpStream as Z}from"./httpStream-x6q-x4yK.mjs";import{d as P,n as R,f as H,a as ee,c as te}from"./local-store-BD0RFD7A.mjs";import{O as se,n as N,i as re,r as ne}from"./offline-queue-BdQFXDz_.mjs";import{resolvePersistenceAdapter as ie}from"./createInMemoryPersistence-BPdQiujT.mjs";import{resolveQueryCacheAdapter as ae,queryCacheKey as F}from"./createInMemoryQueryCache-HMIq2XtS.mjs";import{createReconnect as K}from"./createReconnect-CjTmjJDH.mjs";import{createStream as oe}from"./DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as g}from"./SubscriptionRegistry-D5Xu-a39.mjs";const L=500,ce=(h,e)=>{if(h.size<e)return;const t=h.keys().next().value;t!==void 0&&h.delete(t)};class C{listeners=new Set;add(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}emit(...e){const[t]=e;for(const s of this.listeners)try{s(t)}catch{}}clear(){this.listeners.clear()}}const he="/_lunora/rpc",B="/_lunora/rpc-batch",de="/_lunora/ws",M=h=>h===void 0||h===""?"":`&bucket=${encodeURIComponent(h)}`,A=h=>{for(let e=h.length-1;e>=0;e-=1)h[e]?.()},ue=(h,e)=>{for(const t of e)t.op==="delete"?h.delete(t.key):t.value!==void 0&&h.set(t.key,t.value)},le="lunora-ping",fe=3e4,me=1e4,pe=250,ye=64,Se="/_lunora/admin/shard-traffic",be="/_lunora/admin/scheduled",Te="/_lunora/admin/scheduled/status",ke="/_lunora/admin/scheduled/ws",ve="/_lunora/admin/scheduled/cancel",ge="/_lunora/admin/scheduled/dead",Ce="/_lunora/admin/scheduled/dead/retry",_e="/_lunora/admin/scheduled/dead/cancel",we="/_lunora/admin/workflows/instances",Ee="/_lunora/admin/workflows/instance",Ae="/_lunora/admin/workflows/status",U="/_lunora/admin/storage",Ie="/_lunora/admin/storage/url",Oe="/_lunora/admin/storage/buckets",Pe="/_lunora/admin/functions",Re="/_lunora/admin/cron-jobs",He="/_lunora/admin/cron-jobs/run",Fe="/_lunora/admin/openapi",Le="/_lunora/admin/openrpc",Me="/_lunora/admin/global/tables",Ue="/_lunora/admin/global/table",xe="/_lunora/admin/global/facet",Ne="/_lunora/admin/vector/indexes",Ke="/_lunora/admin/vector/query",Be="/_lunora/admin/logs/archive",We="/_lunora/admin/kv/namespaces",qe="/_lunora/admin/kv/keys",x="/_lunora/admin/kv/value",De="/_lunora/admin/auth/users",$e="/_lunora/admin/auth/sessions",Qe="/_lunora/admin/auth/users/create",Ge="/_lunora/admin/auth/users/role",ze="/_lunora/admin/auth/users/ban",Ve="/_lunora/admin/auth/users/unban",je="/_lunora/admin/auth/users/password",Je="/_lunora/admin/auth/users/remove",Ye="/_lunora/admin/auth/users/impersonate",Xe="/_lunora/admin/auth/sessions/revoke",Ze="/_lunora/admin/auth/sessions/revoke-all",et="/_lunora/admin/auth/capabilities",tt="/_lunora/admin/auth/users/update",st="/_lunora/admin/auth/accounts",rt="/_lunora/admin/auth/accounts/unlink",nt="/_lunora/admin/auth/passkeys",it="/_lunora/admin/auth/passkeys/delete",at="/_lunora/admin/auth/two-factor/disable",ot="/_lunora/admin/auth/organizations",ct="/_lunora/admin/auth/organizations/members",ht="/_lunora/admin/auth/organizations/invitations",dt="/_lunora/admin/auth/organizations/members/remove",ut="/_lunora/admin/auth/organizations/invitations/cancel",lt="/_lunora/admin/auth/config",ft="/_lunora/admin/auth/organizations/create",mt="/_lunora/admin/auth/organizations/update",pt="/_lunora/admin/auth/organizations/remove",yt="/_lunora/admin/auth/organizations/members/add",St="/_lunora/admin/auth/organizations/members/invite",bt="/_lunora/admin/auth/organizations/members/role",Tt="/_lunora/admin/auth/organizations/teams",kt="/_lunora/admin/auth/organizations/teams/create",vt="/_lunora/admin/auth/organizations/teams/update",gt="/_lunora/admin/auth/organizations/teams/remove",Ct="/_lunora/admin/auth/organizations/teams/members",_t="/_lunora/admin/auth/organizations/teams/members/add",wt="/_lunora/admin/auth/organizations/teams/members/remove",Et="/_lunora/admin/auth/organizations/roles",At="/_lunora/admin/auth/organizations/roles/create",It="/_lunora/admin/auth/organizations/roles/update",Ot="/_lunora/admin/auth/organizations/roles/remove",Pt="/api/auth",Rt="/get-session",W=h=>h.startsWith("https://")?`wss://${h.slice(8)}`:h.startsWith("http://")?`ws://${h.slice(7)}`:h,k=(h,e)=>`${h.endsWith("/")?h.slice(0,-1):h}${e}`,y=(h,e)=>{const t=new URLSearchParams;for(const[r,n]of Object.entries(e))n!==void 0&&n!==""&&t.set(r,String(n));const s=t.toString();return s===""?h:`${h}?${s}`},Ht=[j],m=h=>h??"",$=(h,e)=>{const t=h.error,s=typeof t?.code=="string"?t.code:void 0,r=typeof t?.message=="string"?t.message:void 0;return{code:s,messageText:(typeof h.message=="string"?h.message:void 0)??r??e}},Ft=h=>{const{code:e,messageText:t}=$(h,"stream error");return e===void 0?new Error(t):new f(e,t)},q=h=>{const{code:e,messageText:t}=$(h,"subscription error");return{message:t,...e===void 0?{}:{code:e}}},I=(h,e)=>{for(const t of h)try{t(e)}catch{}},Lt=new TextDecoder,Mt=h=>{if(typeof h=="string")return h;if(h instanceof ArrayBuffer)return Lt.decode(h)},S=(h,e)=>{if(!h.socket||h.wsState!=="open")return!1;try{return h.socket.send(JSON.stringify(e)),!0}catch{return!1}},_=h=>{const e=new Error(h.message??"request failed");return e.code=h.code,h.data!==void 0&&(e.data=b(h.data)),h.hint!==void 0&&(e.hint=h.hint),h.docsUrl!==void 0&&(e.docsUrl=h.docsUrl),e},v=(h,e)=>{try{return D(h)}catch(t){const s=t instanceof Error?t.message:String(t);throw new TypeError(`LunoraClient: cannot encode ${e} — ${s}`,t instanceof Error?{cause:t}:void 0)}},Ut=(h,e)=>{const t=Array.from({length:e});for(const s of h){if(typeof s.id!="number"||s.id<0||s.id>=e)continue;const r=s.body;t[s.id]=r&&"error"in r&&r.error?{error:_(r.error),ok:!1}:{ok:!0,value:b(r?.result)}}return t.map(s=>s??{error:new Error("batch call returned no result"),ok:!1})},xt=new Set(["SHARD_ERROR","SHARD_UNAVAILABLE"]),Nt=Promise.resolve();class Q{static MAX_POKE_BUFFERS=256;static createClientQuery(e,t){return{defaultValue:t,key:e}}url;wsUrl;clientQueryStore;wsToken;authBasePath;fetchImpl;WebSocketImpl;bookmark;reconnectOptions;connectTimeoutMs;heartbeatIntervalMs;offlineQueue;outbox;clientId;shardCursors=new Map;defaultShardKey;readyResolved=!1;readyResolve;readyPromise;clientWatermarks=new Map;outboxMutationCounter=0;onPersistenceError;persistence;persistenceVersion;outboxLeaderRelease;queryCache;hydratedQueryCache=new Map;pendingCacheWrites=new Map;cacheFlushTimer;subscriptions=new g;tabCoordinator;leaderStatus;leaderWasEverConnected=!1;connections=new Map;defaultConnectionContext;connectionContexts=new Map;connectionContextHolders=new Map;authToken=null;authSubject=void 0;queuedIdentities=new Map;queuedOfflineShardKeys=new Set;closed=!1;authTokenListeners=new C;statusListeners=new C;tokenExpiredListeners=new C;mutationSettledListeners=new C;pendingChangeListeners=new C;whisperHandlers=new Map;lastStatus="idle";nextSubId=0;nextStreamId=0;streams=new Map;shapeSubscriptions=new Map;pokeBuffers=new Map;nextShapeId=0;constructor(e){this.url=e.url,this.wsUrl=e.wsUrl??k(W(e.url),de),this.wsToken=e.wsToken;const t=e.authBasePath??Pt;this.authBasePath=t.endsWith("/")?t.slice(0,-1):t,this.fetchImpl=e.fetch??(typeof fetch=="function"?fetch.bind(globalThis):void 0),this.WebSocketImpl=e.WebSocket??(typeof WebSocket=="function"?WebSocket:void 0),this.bookmark=e.bookmarkStorage??J(),this.reconnectOptions=e.reconnect,this.heartbeatIntervalMs=e.heartbeatIntervalMs??fe,this.connectTimeoutMs=e.connectTimeoutMs??me,this.defaultConnectionContext=e.connectionContext,this.persistence=ie(e.persistence,e.outbox===void 0),this.persistenceVersion=e.persistenceVersion,this.queryCache=ae(e.queryCache),this.onPersistenceError=e.offlineQueue?.onPersistenceError,this.clientQueryStore=new Y,e.crossTabSync?(this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start()):this.tabCoordinator=void 0,e.hydrateOnStart&&this.queryCache?this.readyPromise=new Promise(s=>{this.readyResolve=s}):(this.readyResolved=!0,this.readyPromise=Nt),this.offlineQueue=new se(e.offlineQueue,{onEvict:(s,r)=>{this.emitItemSettled(s,"rejected",r)},onSizeChange:s=>{this.pendingChangeListeners.emit(s)},persistence:this.persistence,version:e.persistenceVersion}),this.outbox=e.outbox,this.clientId=e.clientId??`client-${N()}`,this.persistence&&queueMicrotask(()=>{this.hydrateAsOutboxLeader()}),this.queryCache&&queueMicrotask(()=>{(async()=>{try{await this.hydrateQueryCache()}catch{}finally{this.readyResolved=!0,this.readyResolve?.()}})().catch(()=>{})})}setAuthToken(e,t){const s=this.authToken!==e,r=this.identityFingerprint();this.authToken=e,t!==void 0&&(this.authSubject=t);const n=this.identityFingerprint();if(n!==r&&(s?this.rejectQueuedForIdentityChange():(this.restampQueuedIdentity(r,n),this.restampWatermarks(r,n)),this.tabCoordinator)){const i=this.tabCoordinator.isLeader();this.tabCoordinator.stop(),this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start(),i&&this.tabCoordinator.promoteImmediately()}s&&this.authTokenListeners.emit(e)}getAuthToken(){return this.authToken}currentIdentity(){return this.identityFingerprint()}clientIdentifier(){return this.clientId}confirmedMutationWatermark(e){return this.clientWatermarks.get(this.identityFingerprint()??"")?.get(e??"")??0}async callMutator(e,t,s){const r=s?.clientSeq;if(r!==void 0&&(!Number.isInteger(r)||r<=0))throw new f("INTERNAL",`callMutator: clientSeq must be a positive integer, got ${String(r)}`);const n=s?.shardKey??"",i=this.identityFingerprint();let a;const o=await this.rpc(e,t,s?.shardKey,{captureBookmark:!0,clientId:this.clientId,clientSeq:r,onMutationAck:d=>{a=d}});if(a!==void 0&&a>(this.clientWatermarks.get(i??"")?.get(n)??0)){let d=this.clientWatermarks.get(i??"");d===void 0&&(d=new Map,this.clientWatermarks.set(i??"",d)),d.set(n,a)}return{applied:a===void 0||a===r,result:o}}onAuthTokenChange(e){return this.authTokenListeners.add(e)}async getCurrentUser(){if(this.closed||!this.fetchImpl)return null;const e={};this.authToken&&(e.authorization=`Bearer ${this.authToken}`);try{const t=await this.fetchImpl(k(this.url,`${this.authBasePath}${Rt}`),{credentials:"include",headers:e,method:"GET"});return t.ok?(await t.json())?.user??null:null}catch{return null}}setWsToken(e){if(this.wsToken!==e){this.wsToken=e;for(const t of this.connections.values())if(t.socket)try{t.socket.close()}catch{}}}setConnectionContext(e,t={}){const s=m(t.shardKey);e===void 0?this.connectionContexts.delete(s):this.connectionContexts.set(s,e),this.refreshConnectionContext(s)}acquireConnectionContext(e,t={}){const s=m(t.shardKey),r={context:e},n=this.connectionContextHolders.get(s);n?n.push(r):this.connectionContextHolders.set(s,[r]),this.refreshConnectionContext(s);let i=!1;return()=>{if(i)return;i=!0;const a=this.connectionContextHolders.get(s);if(!a)return;const o=a.indexOf(r);o!==-1&&a.splice(o,1),a.length===0&&this.connectionContextHolders.delete(s),this.refreshConnectionContext(s)}}whisperSubscribe(e,t,s={}){const r=m(s.shardKey);let n=this.whisperHandlers.get(r);n||(n=new Map,this.whisperHandlers.set(r,n));let i=n.get(e);const a=i===void 0;if(i||(i=new Set,n.set(e,i)),i.add(t),this.ensureSocket(s.shardKey),a){const o=this.getConnection(s.shardKey);o&&S(o,{topic:e,type:"whisper_subscribe"})}return()=>{const o=this.whisperHandlers.get(r),c=o?.get(e);if(!c?.delete(t)||c.size>0)return;o?.delete(e),o?.size===0&&this.whisperHandlers.delete(r);const d=this.getConnection(s.shardKey);d&&S(d,{topic:e,type:"whisper_unsubscribe"})}}whisper(e,t,s={}){this.ensureSocket(s.shardKey);const r=this.getConnection(s.shardKey);r&&S(r,{data:v(t??null,`whisper data for topic '${e}'`),topic:e,type:"whisper"})}onTokenExpired(e){return this.tokenExpiredListeners.add(e)}connectionStatus(){return this.computeStatus()}onConnectionStatus(e){const t=this.statusListeners.add(e);return e(this.computeStatus()),t}pendingCount(){return this.offlineQueue.size}debug(){const e=[],t=this.clientWatermarks.get(this.identityFingerprint()??""),s=new Set([...this.connections.keys(),...t?.keys()??[]]);for(const n of s){const i=this.connections.get(n);e.push({confirmedMutationWatermark:t?.get(n)??0,hasSocket:i?.socket!==void 0,shardKey:n===""?void 0:n,wasEverConnected:i?.wasEverConnected??!1,wsState:i?.wsState??"idle"})}const r=this.subscriptions.all().map(n=>({acked:n.acked,functionPath:n.fn.__lunoraRef,id:n.id,kind:"query",lastMutationId:n.lastMutationId,pendingOptimisticLayers:n.optimisticLayers.length,serverCursor:n.serverCursor,shardKey:n.shardKey,subscriberCount:n.callbacks.size}));for(const n of this.shapeSubscriptions.values())r.push({acked:n.serverCursor!==void 0,functionPath:`shape:${n.name}`,id:n.id,kind:"shape",lastMutationId:n.lastMutationId,pendingOptimisticLayers:0,rowCount:n.rows.size,serverCursor:n.serverCursor,shardKey:n.shardKey,subscriberCount:n.callbacks.size});return{clientId:this.clientId,closed:this.closed,connectionStatus:this.computeStatus(),pendingWrites:this.offlineQueue.size,shards:e.toSorted((n,i)=>(n.shardKey??"").localeCompare(i.shardKey??"")),subscriptions:r.toSorted((n,i)=>n.functionPath.localeCompare(i.functionPath))}}onPendingChange(e){const t=this.pendingChangeListeners.add(e);return e(this.offlineQueue.size),t}onMutationSettled(e){return this.mutationSettledListeners.add(e)}getWebSocketImpl(){return this.WebSocketImpl}getClientQuery(e){return this.clientQueryStore.get(e)}setClientQuery(e,t){this.clientQueryStore.set(e,t)}subscribeClientQuery(e,t){return this.clientQueryStore.subscribe(e,t)}resetClientQuery(e){this.clientQueryStore.reset(e)}snapshotPrecondition(e,t,s){const r=this.peekActiveQueryValue(e.__lunoraRef,t,s),n=r===void 0?void 0:E(r);return()=>{const i=this.peekActiveQueryValue(e.__lunoraRef,t,s);return n===void 0&&i===void 0?!0:n===void 0||i===void 0?!1:E(i)===n}}whenReady(){return this.readyPromise}get isReady(){return this.readyResolved}peekHydratedQuery(e,t,s){if(!this.readyResolved)return;const r=E(t),n=F(e,r,s),i=this.hydratedQueryCache.get(n);if(i!==void 0)return i.identity===this.identityFingerprint()?i.value:void 0}peekActiveQueryValue(e,t,s){const r=g.key(e,t,s);return this.subscriptions.get(r)?.lastValue}async query(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey,{attachBookmark:!0})}async batch(e){if(this.assertOpen(),!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");if(e.length===0)return[];const t=await this.fetchImpl(k(this.url,B),{body:JSON.stringify({calls:e.map((n,i)=>({args:v(n.args??{},`args for batch call '${n.fn.__lunoraRef}'`),functionPath:n.fn.__lunoraRef,id:i,shardKey:n.shardKey}))}),headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"}),s=t.headers.get("x-d1-bookmark");s&&this.bookmark.set(s);let r;try{r=await t.json()}catch{throw new f("INTERNAL",`LunoraClient: batch response was not JSON (status ${t.status.toString()})`)}if(!t.ok||r.error&&!r.results)throw r.error?_(r.error):new f("INTERNAL",`LunoraClient: batch request failed (status ${t.status.toString()})`);for(const n of r.results??[]){const i=n.body?.commitCursor;typeof n.id=="number"&&typeof i=="number"&&this.recordShardCursor(e[n.id]?.shardKey,i)}return Ut(r.results??[],e.length)}async mutation(e,t,s={}){this.assertOpen();const r=t,n=s.mutationId??N(),{confirms:i,rollbacks:a}=this.applyOptimisticUpdates(e.__lunoraRef,r,s.shardKey,s.optimistic);s.optimisticUpdate&&this.applyOptimisticUpdate(s.optimisticUpdate,t,s.shardKey,a,i);const{hasSocket:o,wasEverConnected:c,wsState:d}=this.connectionGateState(s.shardKey),{queueBeforeFirstConnect:u}=this.offlineQueue,l=c||u,p=this.WebSocketImpl!==void 0&&l;if(d!=="open"&&!o&&p||d==="connecting"&&l)return this.enqueueOfflineMutation(e,r,s.shardKey,n,a,i,s.precondition);try{let w;const G=await this.rpc(e.__lunoraRef,r,s.shardKey,{captureBookmark:!0,mutationId:n,onCommitCursor:O=>{w=O}});for(const O of i)O(w);return G}catch(w){throw A(a),w}}async action(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey)}async importRows(e,t,s={}){this.assertOpen();const r=Math.max(1,Math.trunc(s.chunkSize??500)),n=s.toArgs??(c=>({rows:c})),i=t.length;let a=0,o=0;for(let c=0;c<i;c+=r){const d=t.slice(c,c+r),u=o;await this.mutation(e,n(d),{...s.importId===void 0?{}:{mutationId:`${s.importId}:${String(u)}`},shardKey:s.shardKey}),o+=1,a+=d.length,s.onProgress?.({done:a,total:i})}return{chunks:o,imported:a}}async shardTraffic(e){this.assertOpen();const t=await this.adminFetch(Se,"POST",{table:e});return{failed:t.failed??0,ok:t.ok??0,shards:t.shards??[]}}async listScheduledJobs(){return this.assertOpen(),(await this.adminFetch(be,"GET")).records??[]}async schedulerStatus(){this.assertOpen();const e=await this.adminFetch(Te,"GET");return{backlog:e.backlog??0,inFlight:e.inFlight??0,pools:e.pools??[]}}async cancelScheduledJob(e){return this.assertOpen(),{cancelled:(await this.adminFetch(ve,"POST",{id:e})).cancelled===!0}}async listDeadJobs(){return this.assertOpen(),(await this.adminFetch(ge,"GET")).records??[]}async retryDeadJob(e){return this.assertOpen(),{retried:(await this.adminFetch(Ce,"POST",{id:e})).retried===!0}}async removeDeadJob(e){return this.assertOpen(),{removed:(await this.adminFetch(_e,"POST",{id:e})).removed===!0}}async listWorkflowInstances(e){this.assertOpen();const t=new URLSearchParams({name:e.name});e.status!==void 0&&t.set("status",e.status),e.page!==void 0&&t.set("page",String(e.page)),e.perPage!==void 0&&t.set("perPage",String(e.perPage));const s=await this.adminFetch(`${we}?${t.toString()}`,"GET");return{configured:s.configured,instances:s.instances??[],page:s.page??1,perPage:s.perPage??e.perPage??0,totalCount:s.totalCount}}async getWorkflowInstance(e){this.assertOpen();const t=new URLSearchParams({id:e.id,name:e.name}),s=await this.adminFetch(`${Ee}?${t.toString()}`,"GET");return{createdOn:s.createdOn,endedOn:s.endedOn,error:s.error,id:s.id??e.id,output:s.output,params:s.params,startedOn:s.startedOn,status:s.status??"unknown",steps:s.steps??[]}}async setWorkflowInstanceStatus(e){return this.assertOpen(),{status:(await this.adminFetch(Ae,"POST",{action:e.action,id:e.id,name:e.name})).status??"unknown"}}subscribeScheduledJobs(e){if(this.assertOpen(),this.WebSocketImpl===void 0)return()=>{};const t=k(W(this.url),ke),s=K(this.reconnectOptions),r={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,socket:void 0};let n,i=!1;const a=()=>{i||(n=setTimeout(d,s.next()))},o=u=>{if(i||this.WebSocketImpl===void 0)return;const l=u===void 0?t:`${t}?token=${encodeURIComponent(u)}`;this.openManagedSocket(r,l,this.connectTimeoutMs,{onClose:()=>{a()},onMessage:p=>{try{const T=JSON.parse(typeof p.data=="string"?p.data:"");T.type==="jobs"&&Array.isArray(T.records)&&e(T.records)}catch{}},onOpen:()=>{s.reset()}})},c=async u=>{let l;try{l=await u()}catch{a();return}o(l)},d=()=>{if(i||this.WebSocketImpl===void 0)return;const{wsToken:u}=this;if(typeof u=="function"){c(u).catch(()=>{});return}o(u)};return d(),()=>{i=!0,n!==void 0&&clearTimeout(n),r.connectTimer!==void 0&&(clearTimeout(r.connectTimer),r.connectTimer=void 0),this.stopHeartbeat(r),r.socket?.close()}}async listFunctions(){return this.assertOpen(),(await this.adminFetch(Pe,"GET")).functions??[]}async getCronJobs(){return this.assertOpen(),(await this.adminFetch(Re,"GET")).jobs??[]}async runCronJob(e){this.assertOpen();const t=await this.adminFetch(He,"POST",{name:e});return{name:t.name??e,ran:t.ran===!0}}async fetchOpenApi(){return this.assertOpen(),await this.adminFetch(Fe,"GET")}async fetchOpenRpc(){return this.assertOpen(),await this.adminFetch(Le,"GET")}async listStorageObjects(e={}){this.assertOpen();const t=y(U,{bucket:e.bucket,cursor:e.cursor,limit:e.limit,prefix:e.prefix}),s=await this.adminFetch(t,"GET");return{cursor:s.cursor,objects:s.objects??[]}}async deleteStorageObject(e,t){this.assertOpen();const s=`${U}?key=${encodeURIComponent(e)}${M(t?.bucket)}`,r=await this.adminFetch(s,"DELETE");return{deleted:r.deleted??!0,key:r.key??e}}async listStorageBuckets(){return this.assertOpen(),(await this.adminFetch(Oe,"GET")).buckets??[]}async uploadStorageObject(e){this.assertOpen();const t=`${U}?key=${encodeURIComponent(e.key)}${M(e.bucket)}`,s=await this.adminFetch(t,"PUT",e.body,e.contentType);return{etag:s.etag,key:s.key??e.key}}async signedStorageUrl(e,t){this.assertOpen();const s=t?.expiresInSeconds,r=s===void 0?"":`&expiresIn=${encodeURIComponent(s.toString())}`,n=`${Ie}?key=${encodeURIComponent(e)}${r}${M(t?.bucket)}`,i=await this.adminFetch(n,"GET");if(typeof i.url!="string")throw new TypeError("LunoraClient: storage URL endpoint returned no `url`");return i.url}async listGlobalTables(){return this.assertOpen(),await this.adminFetch(Me,"GET")}async readGlobalTablePage(e){this.assertOpen();const t=new URLSearchParams({table:e.table});return e.limit!==void 0&&t.set("limit",String(e.limit)),e.offset!==void 0&&t.set("offset",String(e.offset)),e.filters!==void 0&&e.filters.length>0&&t.set("filters",JSON.stringify(e.filters)),await this.adminFetch(`${Ue}?${t.toString()}`,"GET")}async facetGlobalColumn(e){this.assertOpen();const t=new URLSearchParams({column:e.column,table:e.table});return e.limit!==void 0&&t.set("limit",String(e.limit)),e.filters!==void 0&&e.filters.length>0&&t.set("filters",JSON.stringify(e.filters)),await this.adminFetch(`${xe}?${t.toString()}`,"GET")}async listVectorIndexes(){return this.assertOpen(),(await this.adminFetch(Ne,"GET")).indexes??[]}async queryVectorIndex(e){return this.assertOpen(),(await this.adminFetch(Ke,"POST",e)).matches??[]}async queryLogArchive(e={}){this.assertOpen();const t=await this.adminFetch(Be,"POST",e);return{nextCursor:t.nextCursor,rows:t.rows??[]}}async listKvNamespaces(){return this.assertOpen(),(await this.adminFetch(We,"GET")).namespaces??[]}async listKvKeys(e){this.assertOpen();const t=y(qe,{cursor:e.cursor,limit:e.limit,namespace:e.namespace,prefix:e.prefix});return await this.adminFetch(t,"GET")}async getKvValue(e){this.assertOpen();const t=y(x,{key:e.key,namespace:e.namespace});return await this.adminFetch(t,"GET")}async putKvValue(e){this.assertOpen(),await this.adminFetch(x,"PUT",e)}async deleteKvKey(e){this.assertOpen();const t=y(x,{key:e.key,namespace:e.namespace});await this.adminFetch(t,"DELETE")}async listAuthUsers(e={}){this.assertOpen();const t=y(De,{filterField:e.filterField,filterValue:e.filterValue,limit:e.limit,offset:e.offset,search:e.search,searchField:e.searchField,sortBy:e.sortBy,sortDirection:e.sortDirection});return await this.adminFetch(t,"GET")}async createAuthUser(e){return await this.adminFetch(Qe,"POST",e)}async setAuthUserRole(e){return await this.adminFetch(Ge,"POST",e)}async banAuthUser(e){return await this.adminFetch(ze,"POST",e)}async unbanAuthUser(e){return await this.adminFetch(Ve,"POST",e)}async setAuthUserPassword(e){await this.adminFetch(je,"POST",e)}async removeAuthUser(e){await this.adminFetch(Je,"POST",e)}async impersonateAuthUser(e){return await this.adminFetch(Ye,"POST",e)}async revokeAuthSession(e){await this.adminFetch(Xe,"POST",e)}async revokeAuthUserSessions(e){await this.adminFetch(Ze,"POST",e)}async getAuthCapabilities(){return await this.adminFetch(et,"GET")}async updateAuthUser(e){return await this.adminFetch(tt,"POST",e)}async listAuthAccounts(e){return await this.adminFetch(y(st,{userId:e.userId}),"GET")}async unlinkAuthAccount(e){await this.adminFetch(rt,"POST",e)}async listAuthPasskeys(e){return await this.adminFetch(y(nt,{userId:e.userId}),"GET")}async deleteAuthPasskey(e){await this.adminFetch(it,"POST",e)}async disableAuthTwoFactor(e){await this.adminFetch(at,"POST",e)}async listAuthOrganizations(e={}){return await this.adminFetch(y(ot,{limit:e.limit,offset:e.offset}),"GET")}async listAuthOrgMembers(e){const t=y(ct,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async listAuthOrgInvitations(e){const t=y(ht,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async removeAuthOrgMember(e){await this.adminFetch(dt,"POST",e)}async cancelAuthOrgInvitation(e){await this.adminFetch(ut,"POST",e)}async getAuthConfig(){return await this.adminFetch(lt,"GET")}async createAuthOrganization(e){return await this.adminFetch(ft,"POST",e)}async updateAuthOrganization(e){return await this.adminFetch(mt,"POST",e)}async deleteAuthOrganization(e){await this.adminFetch(pt,"POST",e)}async addAuthOrgMember(e){return await this.adminFetch(yt,"POST",e)}async inviteAuthOrgMember(e){return await this.adminFetch(St,"POST",e)}async setAuthOrgMemberRole(e){return await this.adminFetch(bt,"POST",e)}async listAuthOrgTeams(e){const t=y(Tt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgTeam(e){return await this.adminFetch(kt,"POST",e)}async updateAuthOrgTeam(e){return await this.adminFetch(vt,"POST",e)}async removeAuthOrgTeam(e){await this.adminFetch(gt,"POST",e)}async listAuthOrgTeamMembers(e){const t=y(Ct,{limit:e.limit,offset:e.offset,teamId:e.teamId});return await this.adminFetch(t,"GET")}async addAuthOrgTeamMember(e){return await this.adminFetch(_t,"POST",e)}async removeAuthOrgTeamMember(e){await this.adminFetch(wt,"POST",e)}async listAuthOrgRoles(e){const t=y(Et,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgRole(e){return await this.adminFetch(At,"POST",e)}async updateAuthOrgRole(e){return await this.adminFetch(It,"POST",e)}async deleteAuthOrgRole(e){await this.adminFetch(Ot,"POST",e)}async listAuthSessions(e={}){this.assertOpen();const t=y($e,{limit:e.limit,offset:e.offset,userId:e.userId});return await this.adminFetch(t,"GET")}subscribe(e,t,s,r={}){this.assertOpen();const n=t??{},i=g.key(e.__lunoraRef,n,r.shardKey);let a=this.subscriptions.get(i);const o=s,c=r.onError;if(!a){this.nextSubId+=1;const u=`sub_${this.nextSubId.toString()}`,l=E(n),p=this.takeHydratedCache(e.__lunoraRef,l,r.shardKey);a={acked:!1,args:n,argsKey:l,callbacks:new Set,checkpointCallbacks:new Set,errorCallbacks:new Set,fn:e,id:u,lastValue:p?.value,optimisticLayers:[],serverBase:p?.value,serverCursor:p?.serverCursor,shardKey:r.shardKey,...p?.serverEpoch===void 0?{}:{serverEpoch:p.serverEpoch}},this.subscriptions.add(a)}if(a.callbacks.add(o),c&&a.errorCallbacks.add(c),r.onCheckpoint&&a.checkpointCallbacks.add(r.onCheckpoint),a.lastValue!==void 0)try{o(a.lastValue)}catch{}this.ensureSocket(r.shardKey),this.sendSubscribeIfOpen(a);const d=a;return()=>{d.callbacks.delete(o),c&&d.errorCallbacks.delete(c),r.onCheckpoint&&d.checkpointCallbacks.delete(r.onCheckpoint),d.callbacks.size===0&&(this.sendOrQueueUnsubscribe(d.shardKey,d.id,"unsubscribe"),this.subscriptions.remove(d))}}subscribeShape(e,t,s={}){this.assertOpen(),this.nextShapeId+=1;const r=`shape_${this.nextShapeId.toString()}`,n={args:e.args,callbacks:new Set([t]),errorCallbacks:s.onError?new Set([s.onError]):new Set,id:r,name:e.name,onCheckpoint:s.onCheckpoint,rows:new Map,shardKey:s.shardKey,wireArgs:e.args===void 0?void 0:v(e.args,`shape args for '${e.name}'`)};return this.shapeSubscriptions.set(r,n),this.ensureSocket(s.shardKey),this.sendShapeSubscribeIfOpen(n),()=>{this.shapeSubscriptions.delete(r),this.sendOrQueueUnsubscribe(n.shardKey,r,"shape_unsubscribe")}}stream(e,t,s={}){if(this.assertOpen(),this.WebSocketImpl===void 0)throw new f("INTERNAL","LunoraClient: streams require a WebSocket implementation");this.nextStreamId+=1;const r=`stream_${this.nextStreamId.toString()}`,{shardKey:n}=s,i=t??{},{handle:a,iterable:o}=oe({maxBuffer:s.maxBuffer,onCancel:()=>{const l=this.getConnection(n);l&&S(l,{id:r,type:"unsubscribe"}),this.streams.delete(r)}});this.ensureSocket(n);const c=this.getConnection(n),d={id:r,query:{args:v(i,`stream args for '${e.__lunoraRef}'`),functionPath:e.__lunoraRef,shardKey:n},type:"stream"};if(this.streams.set(r,{durable:s.durable===!0,handle:a,lastSeq:0,message:d,shardKey:n}),!(c?.wsState==="open"&&S(c,d))&&c){for(c.pendingStreams=c.pendingStreams??[];c.pendingStreams.length>=ye;){const p=c.pendingStreams.shift()?.id,T=p?this.streams.get(p):void 0;T&&(T.handle.fail(new f("STREAM_QUEUE_OVERFLOW","stream-start frame evicted while socket was unreachable")),this.streams.delete(p))}c.pendingStreams.push(d)}return o}httpStream(e,t,s={}){if(this.closed)throw new f("CLIENT_CLOSED","LunoraClient is closed");if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const r={...this.authToken?{authorization:`Bearer ${this.authToken}`}:{},...s.headers};return Z(e,t,{baseUrl:this.url,fetch:this.fetchImpl,headers:r,maxBuffer:s.maxBuffer,signal:s.signal})}close(){this.closed=!0,this.outboxLeaderRelease?.(),this.outboxLeaderRelease=void 0;for(const e of this.streams.values())e.handle.fail(new f("CLIENT_CLOSED","LunoraClient closed"));this.streams.clear();for(const e of this.connections.values())this.teardownConnection(e);this.offlineQueue.clear(),this.queuedIdentities.clear(),this.cacheFlushTimer!==void 0&&(clearTimeout(this.cacheFlushTimer),this.cacheFlushTimer=void 0),this.pendingCacheWrites.size>0&&this.flushQueryCacheWrites().catch(()=>{}),this.authTokenListeners.clear(),this.statusListeners.clear(),this.tokenExpiredListeners.clear(),this.mutationSettledListeners.clear(),this.pendingChangeListeners.clear(),this.whisperHandlers.clear(),this.shapeSubscriptions.clear(),this.pokeBuffers.clear(),this.tabCoordinator?.stop(),this.tabCoordinator=void 0}assertOpen(){if(this.closed)throw new f("INTERNAL","LunoraClient is closed")}teardownConnection(e){if(e.reconnectTimer!==void 0&&(clearTimeout(e.reconnectTimer),e.reconnectTimer=void 0),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),this.stopHeartbeat(e),e.socket){try{e.socket.close()}catch{}e.socket=void 0}e.wsState="closed"}createTabCoordinator(){const e=`lunora-bridge::${this.url}::${this.identityFingerprint()??"anon"}`;return new X({channelName:e,onBecomeLeader:()=>{for(const t of this.subscriptions.all())this.ensureSocket(t.shardKey),this.sendSubscribeIfOpen(t);this.tabCoordinator?.broadcastConnectionStatus(this.computeStatus(),this.identityFingerprint())},onStopBeingLeader:()=>{for(const[t,s]of this.connections)this.teardownConnection(s),this.connections.delete(t);this.leaderStatus=void 0,this.leaderWasEverConnected=!1},onConnectionStatus:(t,s)=>{if(s!==void 0&&s!==this.identityFingerprint())return;const r=t==="connected"&&this.leaderStatus!=="connected";this.leaderStatus=t,t==="connected"&&(this.leaderWasEverConnected=!0),this.emitConnectionStatus(),r&&this.flushAllOfflineQueues()},onSubscriptionData:(t,s,r,n,i)=>{if(i!==void 0&&i!==this.identityFingerprint())return;const a=this.subscriptions.get(t);a&&(a.serverBase=s,r!==void 0&&(a.serverCursor=r,n!==void 0&&(a.serverEpoch=n),P(a,r)),R(a,H(s,a.optimisticLayers)))},onSubscriptionError:(t,s)=>{const r=this.subscriptions.get(t);r&&I(r.errorCallbacks,s)},onSubscriptionSettled:(t,s,r,n,i,a)=>{if(a!==void 0&&a!==this.identityFingerprint())return;const o=this.subscriptions.get(t);if(o){this.ackAndAdvanceCursor(o,s,r),n!==void 0&&i===this.clientId&&(o.lastMutationId=Math.max(o.lastMutationId??0,n));for(const c of o.checkpointCallbacks)c({checkpoint:o.serverCursor,mutationId:o.lastMutationId})}}})}async enqueueOfflineMutation(e,t,s,r,n,i,a){const o=this.identityFingerprint();if(this.outbox){this.outboxMutationCounter+=1;const c=this.outboxMutationCounter;try{await this.outbox.enqueue({args:t,clientId:this.clientId,functionPath:e.__lunoraRef,idempotencyKey:`${this.clientId}:${String(c)}`,identity:o,mutationId:c,shardKey:s})}catch(d){throw A(n),d instanceof Error?d:new Error(String(d))}for(const d of i)d(void 0);return}return new Promise((c,d)=>{const u={args:t,functionPath:e.__lunoraRef,liveAwaiter:!0,id:r,clientId:this.clientId,identity:o,precondition:a,onCommit:l=>{for(const p of i)p(l)},reject:l=>{this.queuedIdentities.delete(r),A(n),d(l instanceof Error?l:new Error(String(l)))},resolve:c,shardKey:s};this.offlineQueue.enqueue(u),this.queuedOfflineShardKeys.add(s),u.id!==void 0&&this.queuedIdentities.set(u.id,o)})}async hydratePersistedQueue(){try{const e=await this.offlineQueue.hydrate();for(const t of e)this.queuedOfflineShardKeys.add(t),this.ensureSocket(t)}catch{}}hydrateAsOutboxLeader(){const e=()=>{this.hydratePersistedQueue().catch(()=>{})},t=globalThis.navigator?.locks;if(!t){e();return}t.request(`lunora:outbox-leader:${this.url}`,()=>(this.closed||e(),new Promise(s=>{if(this.closed){s();return}this.outboxLeaderRelease=s}))).catch(e)}async hydrateQueryCache(){if(this.queryCache)try{const e=await this.queryCache.load();for(const{key:t,...s}of e){if(re(this.persistenceVersion,s.version)){this.queryCache.remove(t).catch(()=>{});continue}this.hydratedQueryCache.set(t,s)}}catch{}}takeHydratedCache(e,t,s){const r=F(e,t,s),n=this.hydratedQueryCache.get(r);if(n!==void 0)return this.hydratedQueryCache.delete(r),n.identity===this.identityFingerprint()?n:void 0}persistQueryValue(e){const t=e.serverBase;if(!this.queryCache||t===void 0)return;const s=F(e.fn.__lunoraRef,e.argsKey,e.shardKey);this.pendingCacheWrites.set(s,{identity:this.identityFingerprint(),serverCursor:e.serverCursor,ts:Date.now(),value:t,...e.serverEpoch===void 0?{}:{serverEpoch:e.serverEpoch},...this.persistenceVersion===void 0?{}:{version:this.persistenceVersion}}),this.cacheFlushTimer??=setTimeout(()=>{this.flushQueryCacheWrites().catch(()=>{})},pe)}async flushQueryCacheWrites(){this.cacheFlushTimer=void 0;const{queryCache:e}=this;if(!e){this.pendingCacheWrites.clear();return}const t=[...this.pendingCacheWrites.entries()];this.pendingCacheWrites.clear(),await Promise.allSettled(t.map(([s,r])=>e.put(s,r)))}computeStatus(){if(this.tabCoordinator&&!this.tabCoordinator.isLeader())return this.leaderStatus??"idle";const e=[...this.connections.values()];return e.length===0?"idle":e.some(t=>t.wsState==="open")?"connected":e.some(t=>t.wsState==="connecting")?"connecting":"offline"}emitConnectionStatus(){const e=this.computeStatus();e!==this.lastStatus&&(this.lastStatus=e,this.statusListeners.emit(e),this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastConnectionStatus(e,this.identityFingerprint()))}emitItemSettled(e,t,s){this.mutationSettledListeners.emit({args:e.args,code:s===void 0?void 0:s.code,error:s,functionPath:e.functionPath,hadAwaiter:e.liveAwaiter??!1,id:e.id??"",shardKey:e.shardKey,status:t})}applyOptimisticUpdates(e,t,s,r){const n=[],i=[];if(!r)return{confirms:n,rollbacks:i};const a=g.key(e,t,s),o=this.subscriptions.get(a);if(o){const c=ee(o,r);c&&(n.push(c.confirm),i.push(c.rollback))}return{confirms:n,rollbacks:i}}applyOptimisticUpdate(e,t,s,r,n){const{confirms:i,rollbacks:a,store:o}=te(this.subscriptions,s);try{e(o,t)}catch{A(a);return}r.push(...a),n.push(...i)}getConnection(e){return this.connections.get(m(e))}sendOrQueueUnsubscribe(e,t,s){const r=this.getConnection(e);r&&!S(r,{id:t,type:s})&&r.pendingUnsubscribes.push({id:t,type:s})}connectionGateState(e){if(this.tabCoordinator&&!this.tabCoordinator.isLeader()){let s="idle";return this.leaderStatus==="connected"?s="open":this.leaderStatus==="connecting"&&(s="connecting"),{hasSocket:!1,wasEverConnected:this.leaderWasEverConnected,wsState:s}}const t=this.getConnection(e);return{hasSocket:t?.socket!==void 0,wasEverConnected:t?.wasEverConnected??!1,wsState:t?.wsState??"idle"}}getOrCreateConnection(e){const t=m(e);let s=this.connections.get(t);return s||(s={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,pendingUnsubscribes:[],reconnect:K(this.reconnectOptions),reconnectTimer:void 0,shardKey:e,socket:void 0,wasEverConnected:!1,wsState:"idle"},this.connections.set(t,s)),s}wsUrlFor(e,t){const s=[];if(e!==void 0&&s.push(`shard=${encodeURIComponent(e)}`),t!==void 0&&s.push(`token=${encodeURIComponent(t)}`),s.length===0)return this.wsUrl;const r=this.wsUrl.includes("?")?"&":"?";return`${this.wsUrl}${r}${s.join("&")}`}rpcRequestHeaders(e,t){const s={"content-type":"application/json"},r=this.shardCursors.get(this.cursorKeyFor(t));if(r!==void 0&&(s["x-lunora-min-seq"]=r.toString()),this.authToken&&(s.authorization=`Bearer ${this.authToken}`),e.mutationId&&(s["x-lunora-mutation-id"]=e.mutationId),(e.clientId!==void 0||e.mutationId!==void 0)&&(s["x-lunora-client-id"]=e.clientId??this.clientId),e.clientSeq!==void 0&&(s["x-lunora-client-seq"]=e.clientSeq.toString()),e.attachBookmark){const n=this.bookmark.get();n&&(s["x-d1-bookmark"]=n)}return s}async rpc(e,t,s,r={}){if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const n=this.rpcRequestHeaders(r,s),i=await this.fetchImpl(k(this.url,he),{body:JSON.stringify({args:v(t,`args for '${e}'`),functionPath:e,shardKey:s}),headers:n,method:"POST"});if(r.captureBookmark){const o=i.headers.get("x-d1-bookmark");o&&this.bookmark.set(o)}let a;try{a=await i.json()}catch{const o=i.statusText?` ${i.statusText}`:"";throw new f("INTERNAL",`LunoraClient: response was not JSON (status ${i.status.toString()}${o})`)}if("error"in a)throw _(a.error);if(!i.ok){const o=i.statusText?` ${i.statusText}`:"";throw new f("INTERNAL",`LunoraClient: request failed (status ${i.status.toString()}${o})`)}return r.onMutationAck?.(a.lastMutationId),r.onCommitCursor?.(a.commitCursor),this.learnDefaultShardKey(i,s),this.recordShardCursor(s,a.commitCursor),b(a.result)}async adminFetch(e,t,s,r){if(!this.fetchImpl)throw new f("INTERNAL","LunoraClient: no `fetch` implementation available");const n={};this.authToken&&(n.authorization=`Bearer ${this.authToken}`);const i=s instanceof ArrayBuffer||s instanceof Blob;let a;s===void 0?a=void 0:i?(a=s,r!==void 0&&(n["content-type"]=r)):(a=JSON.stringify(s),n["content-type"]="application/json");const o=await this.fetchImpl(k(this.url,e),{body:a,headers:n,method:t});let c;try{c=await o.json()}catch{const d=o.statusText?` ${o.statusText}`:"";throw new f("INTERNAL",`LunoraClient: response was not JSON (status ${o.status.toString()}${d})`)}if(typeof c=="object"&&c!==null&&"error"in c){const d=c.error,u=new Error(d.message??"admin request failed");throw u.code=d.code,u}if(!o.ok){const d=o.statusText?` ${o.statusText}`:"";throw new f("INTERNAL",`LunoraClient: admin request failed (status ${o.status.toString()}${d})`)}return c}effectiveConnectionContext(e){const t=this.connectionContextHolders.get(e);return t&&t.length>0?t[t.length-1]?.context:this.connectionContexts.get(e)??this.defaultConnectionContext}refreshConnectionContext(e){const t=this.connections.get(e);t?.wsState==="open"&&this.sendConnectEnvelope(t)}sendConnectEnvelope(e){const t=this.effectiveConnectionContext(m(e.shardKey));S(e,{caps:Ht,clientId:this.clientId,id:"connect",type:"connect",...t===void 0?{}:{context:t}})}resendShapeSubscriptions(e){for(const t of this.shapeSubscriptions.values())m(t.shardKey)===m(e)&&this.sendShapeSubscribeIfOpen(t)}ensureSocket(e){if(this.closed||this.WebSocketImpl===void 0||this.tabCoordinator&&!this.tabCoordinator.isLeader())return;const t=this.getOrCreateConnection(e);if(!(t.wsState==="open"||t.wsState==="connecting")){if(t.wsState="connecting",this.emitConnectionStatus(),typeof this.wsToken=="function"){this.openSocketWithProvidedToken(t,e,this.wsToken).catch(()=>{});return}this.openSocket(t,e,this.wsToken)}}async openSocketWithProvidedToken(e,t,s){let r;try{r=await s()}catch{this.handleDisconnect(e);return}this.closed||this.WebSocketImpl===void 0||e.wsState!=="connecting"||e.socket!==void 0||this.openSocket(e,t,r)}openManagedSocket(e,t,s,r){const{WebSocketImpl:n}=this;if(n===void 0)throw new f("INTERNAL","no WebSocket implementation available");const i=new n(t);e.socket=i;const a=()=>{this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket===i&&(e.socket=void 0)},o=c=>{a(),r.onClose(c)};s>0&&(e.connectTimer=setTimeout(()=>{if(e.connectTimer=void 0,e.socket===i){try{i.close()}catch{}o()}},s)),i.addEventListener("open",()=>{e.socket===i&&(e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.lastFrameAt=Date.now(),r.onOpen(),this.startHeartbeat(e,o))}),i.addEventListener("message",c=>{e.socket===i&&(e.lastFrameAt=Date.now(),r.onMessage(c))}),i.addEventListener("close",c=>{e.socket===i&&o(c)}),i.addEventListener("error",()=>{e.socket===i&&o()})}openSocket(e,t,s){this.WebSocketImpl!==void 0&&this.openManagedSocket(e,this.wsUrlFor(t,s),this.connectTimeoutMs,{onClose:r=>{r?.code===4001&&this.notifyTokenExpired(),this.handleDisconnect(e)},onMessage:r=>{this.handleServerMessage(r.data,t)},onOpen:()=>{e.wsState="open",e.wasEverConnected=!0,e.reconnect.reset(),this.emitConnectionStatus(),this.sendConnectEnvelope(e),this.markShardPendingAck(t);for(const n of this.subscriptions.all())m(n.shardKey)===m(t)&&this.sendSubscribeIfOpen(n);if(this.resendShapeSubscriptions(t),e.pendingUnsubscribes.length>0){const n=e.pendingUnsubscribes;e.pendingUnsubscribes=[];for(const{id:i,type:a}of n)S(e,{id:i,type:a})}if(e.pendingStreams&&e.pendingStreams.length>0){const n=e.pendingStreams;e.pendingStreams=[];for(const i of n)S(e,i)}const r=this.whisperHandlers.get(m(t));if(r)for(const n of r.keys())S(e,{topic:n,type:"whisper_subscribe"});this.flushOfflineQueue(t).catch(()=>{})}})}handleDisconnect(e){if(this.closed||e.wsState==="idle"||e.wsState==="closed")return;this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket=void 0,e.wsState="idle",this.emitConnectionStatus(),this.markShardPendingAck(e.shardKey);const t=new Set((e.pendingStreams??[]).map(r=>r.id));for(const[r,n]of this.streams)if(!(m(n.shardKey)!==m(e.shardKey)||t.has(r))){if(n.durable){const i={...n.message,sinceChunk:n.lastSeq};n.message=i,e.pendingStreams=[...(e.pendingStreams??[]).filter(a=>a.id!==r),i];continue}n.handle.fail(new f("STREAM_DISCONNECTED","stream terminated: WebSocket disconnected")),this.streams.delete(r)}if(this.WebSocketImpl===void 0)return;const s=e.reconnect.next();e.reconnectTimer=setTimeout(()=>{e.reconnectTimer=void 0,this.ensureSocket(e.shardKey)},s)}startHeartbeat(e,t){this.stopHeartbeat(e),!(this.heartbeatIntervalMs<=0)&&(e.heartbeatTimer=setInterval(()=>{if(!e.socket)return;const{socket:s}=e;if(Date.now()-e.lastFrameAt>this.heartbeatIntervalMs*2.5){try{s.close()}catch{}t();return}try{s.send(le)}catch{}},this.heartbeatIntervalMs))}stopHeartbeat(e){e.heartbeatTimer!==void 0&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=void 0)}markShardPendingAck(e){const t=m(e);for(const s of this.subscriptions.all())m(s.shardKey)===t&&(s.acked=!1)}sendSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);if(t?.wsState!=="open"||e.acked)return;const s=e.fn.__lunoraTable??e.fn.__lunoraRef;S(t,{id:e.id,query:{args:D(e.args),functionPath:e.fn.__lunoraRef,table:s,...e.serverCursor===void 0?{}:{sinceSeq:e.serverCursor},...e.serverEpoch===void 0?{}:{sinceEpoch:e.serverEpoch}},type:"subscribe"})}sendShapeSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);t?.wsState==="open"&&S(t,{id:e.id,shape:{name:e.name,...e.wireArgs===void 0?{}:{args:e.wireArgs}},type:"shape_subscribe",...e.serverCursor===void 0?{}:{sinceCheckpoint:e.serverCursor},...e.serverEpoch===void 0?{}:{sinceEpoch:e.serverEpoch}})}handleServerMessage(e,t){const s=Mt(e);if(s===void 0)return;let r;try{r=JSON.parse(s)}catch{return}switch(r.type){case"ack":{const n=this.subscriptions.getById(r.id);n&&(n.acked=!0);return}case"chunk":{const{data:n,id:i,seq:a}=r,o=this.streams.get(i);o&&typeof a=="number"&&(o.lastSeq=a,o.durable=!0),o?.handle.push(b(n));return}case"complete":{this.handleCompleteMessage(r.id);return}case"data":case"delta":{this.handleDataMessage(r);return}case"error":{this.handleErrorMessage(r);break}case"pokeEnd":{this.handlePokeEnd(r);break}case"pokePart":{this.handlePokePart(r);break}case"pokeStart":{this.handlePokeStart(r);break}case"resume":{this.handleResumeMessage(r);break}case"settled":{this.handleSettledMessage(r);break}case"whisper":{this.dispatchWhisper(r,t);break}}}handleErrorMessage(e){if(e.error?.code==="TOKEN_EXPIRED"){this.notifyTokenExpired();return}const{id:s}=e,r=s===void 0?void 0:this.streams.get(s);if(r&&s!==void 0){r.handle.fail(Ft(e)),this.streams.delete(s);return}const n=s===void 0?void 0:this.subscriptions.getById(s);if(n){I(n.errorCallbacks,q(e));return}const i=s===void 0?void 0:this.shapeSubscriptions.get(s);i&&I(i.errorCallbacks,q(e))}handlePokeStart(e){ce(this.pokeBuffers,Q.MAX_POKE_BUFFERS),this.pokeBuffers.set(e.pokeId,{baseCheckpoint:e.baseCheckpoint,epoch:e.epoch,lastMutationId:new Map,parts:new Map})}handlePokePart(e){const t=this.pokeBuffers.get(e.pokeId);if(!t)return;const s=t.parts.get(e.shapeId)??[];for(const r of e.rowsPatch)s.push(r.value===void 0?r:{...r,value:b(r.value)});t.parts.set(e.shapeId,s),e.lastMutationId!==void 0&&t.lastMutationId.set(e.shapeId,e.lastMutationId)}handlePokeEnd(e){const t=this.pokeBuffers.get(e.pokeId);if(t){this.pokeBuffers.delete(e.pokeId);for(const[s,r]of t.parts){const n=this.shapeSubscriptions.get(s);if(!n)continue;const i=t.epoch!==void 0&&n.serverEpoch!==void 0&&t.epoch!==n.serverEpoch,a=t.baseCheckpoint!==void 0&&n.serverCursor!==void 0&&n.serverCursor!==t.baseCheckpoint;if(i||a){n.rows.clear(),n.serverCursor=void 0,n.serverEpoch=void 0,this.emitShapeRows(n),this.sendShapeSubscribeIfOpen(n);continue}ue(n.rows,r),e.checkpoint!==void 0&&(n.serverCursor=e.checkpoint),e.epoch!==void 0&&(n.serverEpoch=e.epoch);const o=t.lastMutationId.get(s);o!==void 0&&(n.lastMutationId=o),this.emitShapeRows(n),n.onCheckpoint?.({checkpoint:n.serverCursor,mutationId:n.lastMutationId})}}}emitShapeRows(e){const t=[...e.rows.values()];for(const s of e.callbacks)try{s(t)}catch{}}handleDataMessage(e){const{id:t}=e,s=t?this.subscriptions.getById(t):void 0;if(!s)return;const r=this.resolveDataPayload(e,s);if(s.serverBase=r,e.cursor!==void 0&&(s.serverCursor=e.cursor),e.epoch!==void 0&&(s.serverEpoch=e.epoch),e.lastMutationId!==void 0){s.lastMutationId=Math.max(s.lastMutationId??0,e.lastMutationId);for(const n of s.checkpointCallbacks)n({checkpoint:s.serverCursor,mutationId:s.lastMutationId})}if(this.persistQueryValue(s),P(s,s.serverCursor),R(s,H(r,s.optimisticLayers)),this.tabCoordinator?.isLeader()){const n=g.key(s.fn.__lunoraRef,s.args,s.shardKey);this.tabCoordinator.broadcastSubscriptionData(n,r,s.serverCursor,s.serverEpoch,this.identityFingerprint())}}handleResumeMessage(e){const t=this.subscriptions.getById(e.id);t&&this.ackAndAdvanceCursor(t,e.cursor,e.epoch)}handleSettledMessage(e){const t=this.subscriptions.getById(e.id);if(t){this.ackAndAdvanceCursor(t,e.cursor,e.epoch),e.lastMutationId!==void 0&&(t.lastMutationId=e.lastMutationId);for(const s of t.checkpointCallbacks)s({checkpoint:t.serverCursor,mutationId:t.lastMutationId});if(this.tabCoordinator?.isLeader()){const s=g.key(t.fn.__lunoraRef,t.args,t.shardKey);this.tabCoordinator.broadcastSubscriptionSettled(s,t.serverCursor,t.serverEpoch,t.lastMutationId,this.clientId,this.identityFingerprint())}}}ackAndAdvanceCursor(e,t,s){e.acked=!0,(t!==void 0&&t!==e.serverCursor||s!==void 0&&s!==e.serverEpoch)&&(t!==void 0&&(e.serverCursor=t),s!==void 0&&(e.serverEpoch=s),this.persistQueryValue(e),P(e,e.serverCursor)&&R(e,H(e.serverBase,e.optimisticLayers)))}resolveDataPayload(e,t){if("data"in e&&e.data!==void 0)return b(e.data);const s=b(e.delta);if(z(s)&&t.serverBase!==void 0){const r=V(t.serverBase,s);if(r!==void 0)return r}return s}dispatchWhisper(e,t){const s=this.whisperHandlers.get(m(t))?.get(e.topic);if(!s)return;const r=b(e.data);for(const n of s)try{n(r,e.from)}catch{}}notifyTokenExpired(){this.tokenExpiredListeners.emit()}handleCompleteMessage(e){const t=this.streams.get(e);if(t){t.handle.complete(),this.streams.delete(e);return}const s=this.subscriptions.getById(e);s&&(s.acked=!1,I(s.errorCallbacks,{code:"SUBSCRIPTION_CANCELLED",message:"subscription was cancelled by the server"}))}unpersist(e){e&&this.persistence?.remove(e).catch(t=>{ne(this.onPersistenceError,"remove",t,e)})}identityFingerprint(){if(this.authSubject!==void 0)return this.authSubject===null?null:`subj:${this.authSubject}`;const e=this.authToken;return e===null?null:this.hashToken(e)}hashToken(e){let t=2166136261,s=5381;for(let r=0;r<e.length;r+=1){const n=e.charCodeAt(r);t^=n,t=Math.imul(t,16777619),s=Math.imul(s,33)+n}return`${e.length.toString(36)}:${(t>>>0).toString(36)}:${(s>>>0).toString(36)}`}isSameCredentialUnderTokenHash(e){if(e===null||e.startsWith("subj:"))return!1;const t=this.authToken;return t===null?!1:this.hashToken(t)===e}rejectQueuedForIdentityChange(){const e=this.offlineQueue.drain();for(const t of e){this.queuedIdentities.delete(t.id??""),this.unpersist(t.id);const s=new Error("offline mutation discarded: auth identity changed before replay");s.code="OFFLINE_IDENTITY_CHANGED",t.reject(s),this.emitItemSettled(t,"rejected",s)}this.clearQueryCacheForIdentityChange()}restampQueuedIdentity(e,t){for(const[s,r]of this.queuedIdentities)r===e&&this.queuedIdentities.set(s,t)}restampWatermarks(e,t){const s=e??"",r=this.clientWatermarks.get(s);if(r===void 0)return;this.clientWatermarks.delete(s);const n=t??"",i=this.clientWatermarks.get(n);if(i===void 0)this.clientWatermarks.set(n,r);else for(const[a,o]of r)i.set(a,o)}clearQueryCacheForIdentityChange(){this.cacheFlushTimer!==void 0&&(clearTimeout(this.cacheFlushTimer),this.cacheFlushTimer=void 0),this.pendingCacheWrites.clear(),this.hydratedQueryCache.clear(),this.queryCache?.clear().catch(()=>{})}flushAllOfflineQueues(){for(const e of this.queuedOfflineShardKeys)this.flushOfflineQueue(e).catch(()=>{})}async flushOfflineQueue(e){const t=this.offlineQueue.drainConflict();for(const c of t){this.unpersist(c.id),this.queuedIdentities.delete(c.id??"");const d=new Error("offline mutation skipped: precondition failed before replay");d.code="OFFLINE_PRECONDITION_FAILED",this.emitItemSettled(c,"rejected",d)}const s=m(e),r=this.offlineQueue.drain(c=>m(c.shardKey)===s);if(r.length===0)return;const n=this.identityFingerprint(),i=[];for(const c of r)this.passesReplayIdentityGate(c,n)&&i.push(c);if(i.length===0)return;const a=this.encodableOrSettleTerminal(i);if(a.length===0)return;if(a.length===1){await this.replaySequential(a);return}const o=[];for(let c=0;c<a.length;c+=L){const d=a.slice(c,c+L),u=await this.replayBatched(d);if(o.push(...u.requeue),u.stop){o.push(...a.slice(c+L));break}}o.length>0&&this.offlineQueue.requeue(o)}encodableOrSettleTerminal(e){const t=[];for(const s of e)try{v(s.args,`args for '${s.functionPath}'`),t.push(s)}catch(r){this.settleReplayTerminal(s,r instanceof Error?r:new Error(String(r)))}return t}passesReplayIdentityGate(e,t){const s=e.id===void 0?void 0:this.queuedIdentities.get(e.id),r=s===void 0?e.identity:s;if(r!==void 0&&r!==t&&!this.isSameCredentialUnderTokenHash(r)){this.queuedIdentities.delete(e.id??""),this.unpersist(e.id);const n=new Error("offline mutation skipped: auth identity changed before replay");return n.code="OFFLINE_IDENTITY_CHANGED",e.reject(n),this.emitItemSettled(e,"rejected",n),!1}return this.queuedIdentities.delete(e.id??""),!0}settleReplaySuccess(e,t,s){this.unpersist(e.id),this.recordShardCursor(e.shardKey,s),e.onCommit?.(s),e.resolve(t),this.emitItemSettled(e,"committed")}cursorKeyFor(e){return e??this.defaultShardKey??""}learnDefaultShardKey(e,t){const s=e.headers.get("x-lunora-shard-key");if(s===null||t!==void 0||this.defaultShardKey===s)return;this.defaultShardKey=s;const r=this.shardCursors.get("");r!==void 0&&(this.shardCursors.set(s,Math.max(this.shardCursors.get(s)??0,r)),this.shardCursors.delete(""))}recordShardCursor(e,t){if(typeof t!="number")return;const s=this.cursorKeyFor(e);this.shardCursors.set(s,Math.max(this.shardCursors.get(s)??0,t))}settleReplayTerminal(e,t){this.unpersist(e.id),e.reject(t),this.emitItemSettled(e,"rejected",t)}async replaySequential(e){for(let t=0;t<e.length;t+=1){const s=e[t];if(s)try{let r;const n=await this.rpc(s.functionPath,s.args,s.shardKey,{captureBookmark:!0,clientId:s.clientId??this.clientId,mutationId:s.id,onCommitCursor:i=>{r=i}});this.settleReplaySuccess(s,n,r)}catch(r){if(r.code!==void 0){this.settleReplayTerminal(s,r);continue}this.offlineQueue.requeue(e.slice(t));return}}}async replayBatched(e){if(!this.fetchImpl)return{requeue:e,stop:!0};let t;try{t=await this.fetchImpl(k(this.url,B),{body:JSON.stringify({calls:e.map((n,i)=>({args:v(n.args,`args for '${n.functionPath}'`),functionPath:n.functionPath,id:i,clientId:n.clientId??this.clientId,mutationId:n.id,shardKey:n.shardKey}))}),headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"})}catch{return{requeue:e,stop:!0}}const s=t.headers.get("x-d1-bookmark");s&&this.bookmark.set(s);let r;try{r=await t.json()}catch{return{requeue:e,stop:!0}}if(!r.results){if(r.error){const n=_(r.error);for(const i of e)this.settleReplayTerminal(i,n);return{requeue:[],stop:!1}}return{requeue:e,stop:!0}}return{requeue:this.settleReplayBatchSlots(e,r.results),stop:!1}}settleReplayBatchSlots(e,t){const s=new Map;for(const n of t)typeof n.id=="number"&&n.body!==void 0&&s.set(n.id,n.body);const r=[];for(const[n,i]of e.entries()){const a=s.get(n);a===void 0?r.push(i):"error"in a?xt.has(a.error.code)?r.push(i):this.settleReplayTerminal(i,_(a.error)):this.settleReplaySuccess(i,b(a.result),a.commitCursor)}return r}}export{Q as LunoraClient};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as t}from"./local-store-BD0RFD7A.mjs";import"./SubscriptionRegistry-D5Xu-a39.mjs";export{t as createLocalStore};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const u=(o,a,r)=>{let e=0;return async(c,i)=>{e+=1,r.setPending(!0);try{const t=await o.mutation(a,c,i);return r.setResult(t),t}catch(t){const n=t instanceof Error?t:new Error(String(t));throw r.setError(n),n}finally{e-=1,r.setPending(e>0)}}};export{u as createMutationRunner};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as u}from"./wire-key-BEmRM5ls.mjs";const v=(r,t,n,i)=>{const s=r.peekActiveQueryValue(t.__lunoraRef,n,i),e=s===void 0?void 0:u(s);return()=>{const o=r.peekActiveQueryValue(t.__lunoraRef,n,i);return e===void 0&&o===void 0?!0:e===void 0||o===void 0?!1:u(o)===e}};export{v as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{e as c}from"./wire-codec-D4iww4NV.mjs";const y=(t,e)=>t<e?-1:t>e?1:0,n=t=>{if(t===void 0)return"null";if(typeof t=="bigint")throw new TypeError("stableStringify: cannot use a bigint in a stable JSON cache key — pass it as a string, or use stableWireKey");if(t===null||typeof t!="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(r=>n(r)).join(",")}]`;const e=Object.getPrototypeOf(t);if(e!==null&&e!==Object.prototype){const r=t.constructor?.name??"value";throw new TypeError(`stableStringify: cannot use a ${r} in a stable JSON cache key — only plain objects, arrays, and JSON primitives are supported (wire-typed values key via stableWireKey)`)}const o=t,a=Object.keys(o).toSorted(y),i=[];for(const r of a){const s=o[r];s!==void 0&&i.push(`${JSON.stringify(r)}:${n(s)}`)}return`{${i.join(",")}}`},f=t=>n(c(t));export{f as s};
|