@lunora/client 1.0.0-alpha.74 → 1.0.0-alpha.75

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.
@@ -1,4 +1,4 @@
1
- import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-Cb_0IT8r.mjs";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-DIphNr-G.mjs";
2
2
  import '@lunora/errors';
3
3
  import "../packem_shared/function-reference.d-Br_hsKje.mjs";
4
4
  import '@lunora/runtime';
@@ -1,4 +1,4 @@
1
- import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-CyDr665D.js";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-ljp6sQC5.js";
2
2
  import '@lunora/errors';
3
3
  import "../packem_shared/function-reference.d-Br_hsKje.js";
4
4
  import '@lunora/runtime';
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { c as PersistenceAdapter, Q as QueryCacheAdapter, B as BookmarkStorage, C as ConnectionStatus, S as SubscriptionError, H as HttpStreamRef, d as HttpStreamArgsOf, e as HttpStreamChunkOf, f as StreamIterable, O as OfflineQueueOptions, R as ReconnectOptions, L as LunoraClient } from "./packem_shared/lunora-client.d-Cb_0IT8r.mjs";
2
- export { type A as ActionCallOptions, type g as BatchSlot, type h as CachedQuery, type i as ClientDebugShard, type j as ClientDebugSnapshot, type k as ClientDebugSubscription, type l as ClientMessage, type m as ClientQueryRef, type n as ClientShapeSubscribeMessage, type o as ClientShapeUnsubscribeMessage, D as DEFAULT_MAX_BUFFER, type F as FunctionArgumentDescriptor, type p as FunctionDescriptor, type G as GlobalFacetResult, type q as GlobalFacetValue, type r as GlobalFilterClause, type s as GlobalTableInfo, type t as GlobalTablePage, type u as HttpStreamCallArgs, type v as LunoraClientError, type w as LunoraClientOptions, type M as MutationCallOptions, type x as MutationSettledEvent, type y as OptimisticLocalStore, type z as OptimisticUpdate, type E as OutboxMutation, type I as OutboxSink, type J as PersistedMutation, type P as Preloaded, type K as RowOp, type N as RpcEnvelope, type T as RpcResponseBody, type V as ScheduleRecord, type W as ScheduleRetryPolicy, type X as SchedulerPoolStatus, type Y as SchedulerStatus, type Z as ServerMessage, type _ as ServerPokeEndMessage, type $ as ServerPokePartMessage, type a0 as ServerPokeStartMessage, type a1 as ShardTrafficEntry, type a2 as ShardTrafficResult, type a3 as StorageListPage, type a4 as StorageObject, type a5 as StoredQuery, type a6 as StreamHandle, type a7 as SubscriptionCallback, type b as SubscriptionErrorCallback, a8 as SubscriptionRegistry, type a9 as SubscriptionState, type aa as SyncWatermark, type a as Unsubscribe, type U as User, type ab as WorkflowInstanceAction, type ac as WorkflowInstanceDetail, type ad as WorkflowInstancePage, type ae as WorkflowInstanceStatus, type af as WorkflowInstanceSummary, type ag as WorkflowStepDetail, type ah as WsTokenProvider, ai as createClientQuery, aj as createLocalStore, ak as createStream } from "./packem_shared/lunora-client.d-Cb_0IT8r.mjs";
1
+ import { c as PersistenceAdapter, Q as QueryCacheAdapter, B as BookmarkStorage, C as ConnectionStatus, S as SubscriptionError, H as HttpStreamRef, d as HttpStreamArgsOf, e as HttpStreamChunkOf, f as StreamIterable, O as OfflineQueueOptions, R as ReconnectOptions, L as LunoraClient } from "./packem_shared/lunora-client.d-DIphNr-G.mjs";
2
+ export { type A as ActionCallOptions, type g as BatchSlot, type h as CachedQuery, type i as ClientDebugShard, type j as ClientDebugSnapshot, type k as ClientDebugSubscription, type l as ClientMessage, type m as ClientQueryRef, type n as ClientShapeSubscribeMessage, type o as ClientShapeUnsubscribeMessage, D as DEFAULT_MAX_BUFFER, type F as FunctionArgumentDescriptor, type p as FunctionDescriptor, type G as GlobalFacetResult, type q as GlobalFacetValue, type r as GlobalFilterClause, type s as GlobalTableInfo, type t as GlobalTablePage, type u as HttpStreamCallArgs, type v as LunoraClientError, type w as LunoraClientOptions, type M as MutationCallOptions, type x as MutationSettledEvent, type y as OptimisticLocalStore, type z as OptimisticUpdate, type E as OutboxMutation, type I as OutboxSink, type J as PersistedMutation, type P as Preloaded, type K as RowOp, type N as RpcEnvelope, type T as RpcResponseBody, type V as ScheduleRecord, type W as ScheduleRetryPolicy, type X as SchedulerPoolStatus, type Y as SchedulerStatus, type Z as ServerMessage, type _ as ServerPokeEndMessage, type $ as ServerPokePartMessage, type a0 as ServerPokeStartMessage, type a1 as ShardTrafficEntry, type a2 as ShardTrafficResult, type a3 as StorageListPage, type a4 as StorageObject, type a5 as StoredQuery, type a6 as StreamHandle, type a7 as SubscriptionCallback, type b as SubscriptionErrorCallback, a8 as SubscriptionRegistry, type a9 as SubscriptionState, type aa as SyncWatermark, type a as Unsubscribe, type U as User, type ab as WorkflowInstanceAction, type ac as WorkflowInstanceDetail, type ad as WorkflowInstancePage, type ae as WorkflowInstanceStatus, type af as WorkflowInstanceSummary, type ag as WorkflowStepDetail, type ah as WsTokenProvider, ai as createClientQuery, aj as createLocalStore, ak as createStream } from "./packem_shared/lunora-client.d-DIphNr-G.mjs";
3
3
  import { LunoraError, LunoraErrorCode } from '@lunora/errors';
4
4
  export type { LunoraErrorCode } from '@lunora/errors';
5
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-BrV8gNAa.mjs";
5
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-DxVLGSy_.mjs";
6
6
  import { F as FunctionReference } from "./packem_shared/function-reference.d-Br_hsKje.mjs";
7
7
  export type { A as ArgsOf, R as ReturnOf } from "./packem_shared/function-reference.d-Br_hsKje.mjs";
8
8
  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';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { c as PersistenceAdapter, Q as QueryCacheAdapter, B as BookmarkStorage, C as ConnectionStatus, S as SubscriptionError, H as HttpStreamRef, d as HttpStreamArgsOf, e as HttpStreamChunkOf, f as StreamIterable, O as OfflineQueueOptions, R as ReconnectOptions, L as LunoraClient } from "./packem_shared/lunora-client.d-CyDr665D.js";
2
- export { type A as ActionCallOptions, type g as BatchSlot, type h as CachedQuery, type i as ClientDebugShard, type j as ClientDebugSnapshot, type k as ClientDebugSubscription, type l as ClientMessage, type m as ClientQueryRef, type n as ClientShapeSubscribeMessage, type o as ClientShapeUnsubscribeMessage, D as DEFAULT_MAX_BUFFER, type F as FunctionArgumentDescriptor, type p as FunctionDescriptor, type G as GlobalFacetResult, type q as GlobalFacetValue, type r as GlobalFilterClause, type s as GlobalTableInfo, type t as GlobalTablePage, type u as HttpStreamCallArgs, type v as LunoraClientError, type w as LunoraClientOptions, type M as MutationCallOptions, type x as MutationSettledEvent, type y as OptimisticLocalStore, type z as OptimisticUpdate, type E as OutboxMutation, type I as OutboxSink, type J as PersistedMutation, type P as Preloaded, type K as RowOp, type N as RpcEnvelope, type T as RpcResponseBody, type V as ScheduleRecord, type W as ScheduleRetryPolicy, type X as SchedulerPoolStatus, type Y as SchedulerStatus, type Z as ServerMessage, type _ as ServerPokeEndMessage, type $ as ServerPokePartMessage, type a0 as ServerPokeStartMessage, type a1 as ShardTrafficEntry, type a2 as ShardTrafficResult, type a3 as StorageListPage, type a4 as StorageObject, type a5 as StoredQuery, type a6 as StreamHandle, type a7 as SubscriptionCallback, type b as SubscriptionErrorCallback, a8 as SubscriptionRegistry, type a9 as SubscriptionState, type aa as SyncWatermark, type a as Unsubscribe, type U as User, type ab as WorkflowInstanceAction, type ac as WorkflowInstanceDetail, type ad as WorkflowInstancePage, type ae as WorkflowInstanceStatus, type af as WorkflowInstanceSummary, type ag as WorkflowStepDetail, type ah as WsTokenProvider, ai as createClientQuery, aj as createLocalStore, ak as createStream } from "./packem_shared/lunora-client.d-CyDr665D.js";
1
+ import { c as PersistenceAdapter, Q as QueryCacheAdapter, B as BookmarkStorage, C as ConnectionStatus, S as SubscriptionError, H as HttpStreamRef, d as HttpStreamArgsOf, e as HttpStreamChunkOf, f as StreamIterable, O as OfflineQueueOptions, R as ReconnectOptions, L as LunoraClient } from "./packem_shared/lunora-client.d-ljp6sQC5.js";
2
+ export { type A as ActionCallOptions, type g as BatchSlot, type h as CachedQuery, type i as ClientDebugShard, type j as ClientDebugSnapshot, type k as ClientDebugSubscription, type l as ClientMessage, type m as ClientQueryRef, type n as ClientShapeSubscribeMessage, type o as ClientShapeUnsubscribeMessage, D as DEFAULT_MAX_BUFFER, type F as FunctionArgumentDescriptor, type p as FunctionDescriptor, type G as GlobalFacetResult, type q as GlobalFacetValue, type r as GlobalFilterClause, type s as GlobalTableInfo, type t as GlobalTablePage, type u as HttpStreamCallArgs, type v as LunoraClientError, type w as LunoraClientOptions, type M as MutationCallOptions, type x as MutationSettledEvent, type y as OptimisticLocalStore, type z as OptimisticUpdate, type E as OutboxMutation, type I as OutboxSink, type J as PersistedMutation, type P as Preloaded, type K as RowOp, type N as RpcEnvelope, type T as RpcResponseBody, type V as ScheduleRecord, type W as ScheduleRetryPolicy, type X as SchedulerPoolStatus, type Y as SchedulerStatus, type Z as ServerMessage, type _ as ServerPokeEndMessage, type $ as ServerPokePartMessage, type a0 as ServerPokeStartMessage, type a1 as ShardTrafficEntry, type a2 as ShardTrafficResult, type a3 as StorageListPage, type a4 as StorageObject, type a5 as StoredQuery, type a6 as StreamHandle, type a7 as SubscriptionCallback, type b as SubscriptionErrorCallback, a8 as SubscriptionRegistry, type a9 as SubscriptionState, type aa as SyncWatermark, type a as Unsubscribe, type U as User, type ab as WorkflowInstanceAction, type ac as WorkflowInstanceDetail, type ad as WorkflowInstancePage, type ae as WorkflowInstanceStatus, type af as WorkflowInstanceSummary, type ag as WorkflowStepDetail, type ah as WsTokenProvider, ai as createClientQuery, aj as createLocalStore, ak as createStream } from "./packem_shared/lunora-client.d-ljp6sQC5.js";
3
3
  import { LunoraError, LunoraErrorCode } from '@lunora/errors';
4
4
  export type { LunoraErrorCode } from '@lunora/errors';
5
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-8LuiLYlj.js";
5
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-6JPSWNGq.js";
6
6
  import { F as FunctionReference } from "./packem_shared/function-reference.d-Br_hsKje.js";
7
7
  export type { A as ArgsOf, R as ReturnOf } from "./packem_shared/function-reference.d-Br_hsKje.js";
8
8
  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';
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 c,reconcileOptimistic as p}from"./packem_shared/RETIRE_AFTER_DURABLE_SEQ_ADVANCE-DoEHtuR8.mjs";import{createAsyncStoragePersistence as m}from"./packem_shared/createAsyncStoragePersistence-CeUW9NTj.mjs";import{createAsyncStorageQueryCache as f}from"./packem_shared/createAsyncStorageQueryCache-VgJNCeEn.mjs";import{default as x}from"./packem_shared/createInMemoryBookmarkStorage-BooZhW0n.mjs";import{createCallRunner as l}from"./packem_shared/createCallRunner-Bwcrfh76.mjs";import{createClientQuery as d}from"./packem_shared/createClientQuery-B8Nfj-7o.mjs";import{TabCoordinator as R}from"./packem_shared/TabCoordinator-CXD7vulJ.mjs";import{a as S,i as A}from"./packem_shared/delta-merge-Ds6tHkFX.mjs";import{CONFLICT_ERROR_CODE as Q,TransportError as _,getErrorCode as h,getRetryAfterMs as I,isConflictError as M,isForbiddenError as T,isRateLimitedError as g,isUnauthorizedError as F}from"./packem_shared/CONFLICT_ERROR_CODE-BOeeP_Wl.mjs";import{httpStream as O}from"./packem_shared/httpStream-x6q-x4yK.mjs";import{c as P}from"./packem_shared/local-store-irMi9H2G.mjs";import{LunoraClient as k}from"./packem_shared/LunoraClient-BoqhqR-g.mjs";import{createMutatorRunner as q}from"./packem_shared/createMutatorRunner-CuMRJpUx.mjs";import{O as v}from"./packem_shared/offline-queue-xntsWiKt.mjs";import{createInMemoryPersistence as z,createIndexedDbPersistence as K}from"./packem_shared/createInMemoryPersistence-Cz2W6XVj.mjs";import{preloadQuery as W,preloadedQueryResult as X}from"./packem_shared/preloadQuery-uFy24PCR.mjs";import{createInMemoryQueryCache as G,createIndexedDbQueryCache as H,queryCacheKey as J}from"./packem_shared/createInMemoryQueryCache-D2uNHLfM.mjs";import{createReconnect as Z}from"./packem_shared/createReconnect-CjTmjJDH.mjs";import{default as ee}from"./packem_shared/createSnapshotPrecondition-B7kQcZUF.mjs";import{DEFAULT_MAX_BUFFER as oe,createStream as te}from"./packem_shared/DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as ce}from"./packem_shared/SubscriptionRegistry-BQTQZYoI.mjs";import{ClientServiceWorker as ne}from"./packem_shared/ClientServiceWorker-DXnBXeWK.mjs";import{createReply as ie,sendToSw as fe}from"./packem_shared/createReply-CwFABEJs.mjs";export{Q as CONFLICT_ERROR_CODE,ne as ClientServiceWorker,oe as DEFAULT_MAX_BUFFER,k as LunoraClient,v as OfflineQueue,a as RETIRE_AFTER_DURABLE_SEQ_ADVANCE,ce as SubscriptionRegistry,R as TabCoordinator,_ as TransportError,o as anyApi,S as applyDelta,m as createAsyncStoragePersistence,f as createAsyncStorageQueryCache,l as createCallRunner,d as createClientQuery,x as createInMemoryBookmarkStorage,z as createInMemoryPersistence,G as createInMemoryQueryCache,K as createIndexedDbPersistence,H as createIndexedDbQueryCache,P as createLocalStore,q as createMutatorRunner,Z as createReconnect,ie as createReply,ee as createSnapshotPrecondition,te as createStream,h as getErrorCode,I as getRetryAfterMs,O as httpStream,M as isConflictError,T as isForbiddenError,A as isMutationDelta,g as isRateLimitedError,F as isUnauthorizedError,c as maxSeq,W as preloadQuery,X as preloadedQueryResult,J as queryCacheKey,p as reconcileOptimistic,fe as sendToSw};
1
+ import{anyApi as o}from"./packem_shared/anyApi-CBOws2ZA.mjs";import{RETIRE_AFTER_DURABLE_SEQ_ADVANCE as a,maxSeq as c,reconcileOptimistic as p}from"./packem_shared/RETIRE_AFTER_DURABLE_SEQ_ADVANCE-DoEHtuR8.mjs";import{createAsyncStoragePersistence as m}from"./packem_shared/createAsyncStoragePersistence-CeUW9NTj.mjs";import{createAsyncStorageQueryCache as f}from"./packem_shared/createAsyncStorageQueryCache-VgJNCeEn.mjs";import{default as x}from"./packem_shared/createInMemoryBookmarkStorage-BooZhW0n.mjs";import{createCallRunner as l}from"./packem_shared/createCallRunner-Bwcrfh76.mjs";import{createClientQuery as d}from"./packem_shared/createClientQuery-B8Nfj-7o.mjs";import{TabCoordinator as R}from"./packem_shared/TabCoordinator-CXD7vulJ.mjs";import{a as S,i as A}from"./packem_shared/delta-merge-Ds6tHkFX.mjs";import{CONFLICT_ERROR_CODE as Q,TransportError as _,getErrorCode as h,getRetryAfterMs as I,isConflictError as M,isForbiddenError as T,isRateLimitedError as g,isUnauthorizedError as F}from"./packem_shared/CONFLICT_ERROR_CODE-BOeeP_Wl.mjs";import{httpStream as O}from"./packem_shared/httpStream-x6q-x4yK.mjs";import{c as P}from"./packem_shared/local-store-irMi9H2G.mjs";import{LunoraClient as k}from"./packem_shared/LunoraClient-CXm7h69q.mjs";import{createMutatorRunner as q}from"./packem_shared/createMutatorRunner-CuMRJpUx.mjs";import{O as v}from"./packem_shared/offline-queue-xntsWiKt.mjs";import{createInMemoryPersistence as z,createIndexedDbPersistence as K}from"./packem_shared/createInMemoryPersistence-Cz2W6XVj.mjs";import{preloadQuery as W,preloadedQueryResult as X}from"./packem_shared/preloadQuery-uFy24PCR.mjs";import{createInMemoryQueryCache as G,createIndexedDbQueryCache as H,queryCacheKey as J}from"./packem_shared/createInMemoryQueryCache-D2uNHLfM.mjs";import{createReconnect as Z}from"./packem_shared/createReconnect-CjTmjJDH.mjs";import{default as ee}from"./packem_shared/createSnapshotPrecondition-B7kQcZUF.mjs";import{DEFAULT_MAX_BUFFER as oe,createStream as te}from"./packem_shared/DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as ce}from"./packem_shared/SubscriptionRegistry-BQTQZYoI.mjs";import{ClientServiceWorker as ne}from"./packem_shared/ClientServiceWorker-DXnBXeWK.mjs";import{createReply as ie,sendToSw as fe}from"./packem_shared/createReply-CwFABEJs.mjs";export{Q as CONFLICT_ERROR_CODE,ne as ClientServiceWorker,oe as DEFAULT_MAX_BUFFER,k as LunoraClient,v as OfflineQueue,a as RETIRE_AFTER_DURABLE_SEQ_ADVANCE,ce as SubscriptionRegistry,R as TabCoordinator,_ as TransportError,o as anyApi,S as applyDelta,m as createAsyncStoragePersistence,f as createAsyncStorageQueryCache,l as createCallRunner,d as createClientQuery,x as createInMemoryBookmarkStorage,z as createInMemoryPersistence,G as createInMemoryQueryCache,K as createIndexedDbPersistence,H as createIndexedDbQueryCache,P as createLocalStore,q as createMutatorRunner,Z as createReconnect,ie as createReply,ee as createSnapshotPrecondition,te as createStream,h as getErrorCode,I as getRetryAfterMs,O as httpStream,M as isConflictError,T as isForbiddenError,A as isMutationDelta,g as isRateLimitedError,F as isUnauthorizedError,c as maxSeq,W as preloadQuery,X as preloadedQueryResult,J as queryCacheKey,p as reconcileOptimistic,fe as sendToSw};
@@ -0,0 +1 @@
1
+ import{LunoraError as m}from"@lunora/errors";import{i as ne,a as ae,P as oe}from"./delta-merge-Ds6tHkFX.mjs";import{e as W,d as T}from"./wire-codec-BOMWQpoF.mjs";import{s as q}from"./wire-key-CmT1XyQI.mjs";import ce from"./createInMemoryBookmarkStorage-BooZhW0n.mjs";import{ClientQueryStore as he}from"./createClientQuery-B8Nfj-7o.mjs";import{TabCoordinator as de}from"./TabCoordinator-CXD7vulJ.mjs";import{TransportError as A,getRetryAfterMs as Z}from"./CONFLICT_ERROR_CODE-BOeeP_Wl.mjs";import{httpStream as ue}from"./httpStream-x6q-x4yK.mjs";import{d as U,n as O,f as R,a as le,c as fe}from"./local-store-irMi9H2G.mjs";import{O as me,n as Q,i as pe,r as ye}from"./offline-queue-xntsWiKt.mjs";import{resolvePersistenceAdapter as Se}from"./createInMemoryPersistence-Cz2W6XVj.mjs";import{resolveQueryCacheAdapter as be,queryCacheKey as P}from"./createInMemoryQueryCache-D2uNHLfM.mjs";import{createReconnect as $}from"./createReconnect-CjTmjJDH.mjs";import Te from"./createSnapshotPrecondition-B7kQcZUF.mjs";import{createStream as ve}from"./DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as k}from"./SubscriptionRegistry-BQTQZYoI.mjs";const x=500,ge=async o=>{const e=[];let t;for(;;){const s=await o(t);if(e.push(...Array.isArray(s.records)?s.records:[]),s.truncated!==!0||typeof s.cursor!="string"||s.cursor.length===0)return e;if(s.cursor===t)throw new Error("collectPages: the list did not advance its cursor — refusing to page forever");t=s.cursor}},G=(o,e)=>{if(o.size<e)return;const t=o.keys().next().value;t!==void 0&&o.delete(t)};class w{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 L=new Set(["RATE_LIMITED","SHARD_ERROR","SHARD_UNAVAILABLE","TOO_MANY_REQUESTS"]),ke=o=>{if(o instanceof A)return!0;const e=o?.code;return e===void 0||L.has(e)},ee=6e4,Ce=1e3,te=o=>{if(o===null)return;const e=Number(o);if(Number.isFinite(e))return e>0?e*1e3:void 0;const t=Date.parse(o);if(Number.isNaN(t))return;const s=t-Date.now();return s>0?s:void 0},we={401:"UNAUTHORIZED",403:"FORBIDDEN",404:"NOT_FOUND",413:"PAYLOAD_TOO_LARGE",429:"TOO_MANY_REQUESTS"},M=(o,e,t)=>{const s=te(t),r=s===void 0?void 0:{retryAfterMs:s},i=`LunoraClient: response carried no error envelope (status ${o.toString()}${e?` ${e}`:""})`;return o<400||o>=500||o===408?new A(i,r):new m(we[o]??"BAD_REQUEST",i,{data:r})},Ee=(o,e)=>{const t=te(e);if(!(t===void 0||Z(o)!==void 0))return o.data===void 0?{retryAfterMs:t}:typeof o.data=="object"&&o.data!==null&&!Array.isArray(o.data)?{...o.data,retryAfterMs:t}:void 0},_e=(o,e=Math.random)=>{const t=Math.min(Ce*2**Math.max(o-1,0),ee);return Math.round(t*(.5+e()*.5))},Ae=o=>o instanceof A||L.has(o?.code??""),Ie=(o,e,t)=>{const s=Z(o);return s!==void 0&&s>0?Math.min(s,ee):Ae(o)?_e(e,t):void 0},Oe=983040,Re=o=>typeof TextEncoder>"u"?o.length:new TextEncoder().encode(o).length,Pe="/_lunora/rpc",j="/_lunora/rpc-batch",Me="/_lunora/ws",N=o=>o===void 0||o===""?"":`&bucket=${encodeURIComponent(o)}`,H=o=>{for(let e=o.length-1;e>=0;e-=1)o[e]?.()},z=Symbol("lunora.unmergeableDelta"),He=(o,e)=>{for(const t of e)t.op==="delete"?o.delete(t.key):t.value!==void 0&&o.set(t.key,t.value)},Le="lunora-ping",Fe=3e4,Ue=1e4,xe=250,Ne=5e3,De=64,Be=8,Ke="/_lunora/admin/shard-traffic",We="/_lunora/admin/scheduled",qe="/_lunora/admin/scheduled/status",Qe="/_lunora/admin/scheduled/ws",$e="/_lunora/admin/scheduled/cancel",V="/_lunora/admin/scheduled/dead",Ge="/_lunora/admin/scheduled/dead/retry",je="/_lunora/admin/scheduled/dead/cancel",ze="/_lunora/admin/workflows/instances",Ve="/_lunora/admin/workflows/instance",Je="/_lunora/admin/workflows/status",D="/_lunora/admin/storage",Ye="/_lunora/admin/storage/url",Xe="/_lunora/admin/storage/buckets",Ze="/_lunora/admin/functions",et="/_lunora/admin/cron-jobs",tt="/_lunora/admin/cron-jobs/run",st="/_lunora/admin/openapi",rt="/_lunora/admin/openrpc",it="/_lunora/admin/global/tables",nt="/_lunora/admin/global/table",at="/_lunora/admin/global/facet",ot="/_lunora/admin/vector/indexes",ct="/_lunora/admin/vector/query",ht="/_lunora/admin/logs/archive",dt="/_lunora/admin/kv/namespaces",ut="/_lunora/admin/kv/keys",B="/_lunora/admin/kv/value",lt="/_lunora/admin/auth/users",ft="/_lunora/admin/auth/sessions",mt="/_lunora/admin/auth/users/create",pt="/_lunora/admin/auth/users/role",yt="/_lunora/admin/auth/users/ban",St="/_lunora/admin/auth/users/unban",bt="/_lunora/admin/auth/users/password",Tt="/_lunora/admin/auth/users/remove",vt="/_lunora/admin/auth/users/impersonate",gt="/_lunora/admin/auth/sessions/revoke",kt="/_lunora/admin/auth/sessions/revoke-all",Ct="/_lunora/admin/auth/capabilities",wt="/_lunora/admin/auth/users/update",Et="/_lunora/admin/auth/accounts",_t="/_lunora/admin/auth/accounts/unlink",At="/_lunora/admin/auth/passkeys",It="/_lunora/admin/auth/passkeys/delete",Ot="/_lunora/admin/auth/two-factor/disable",Rt="/_lunora/admin/auth/organizations",Pt="/_lunora/admin/auth/organizations/members",Mt="/_lunora/admin/auth/organizations/invitations",Ht="/_lunora/admin/auth/organizations/members/remove",Lt="/_lunora/admin/auth/organizations/invitations/cancel",Ft="/_lunora/admin/auth/config",Ut="/_lunora/admin/auth/organizations/create",xt="/_lunora/admin/auth/organizations/update",Nt="/_lunora/admin/auth/organizations/remove",Dt="/_lunora/admin/auth/organizations/members/add",Bt="/_lunora/admin/auth/organizations/members/invite",Kt="/_lunora/admin/auth/organizations/members/role",Wt="/_lunora/admin/auth/organizations/teams",qt="/_lunora/admin/auth/organizations/teams/create",Qt="/_lunora/admin/auth/organizations/teams/update",$t="/_lunora/admin/auth/organizations/teams/remove",Gt="/_lunora/admin/auth/organizations/teams/members",jt="/_lunora/admin/auth/organizations/teams/members/add",zt="/_lunora/admin/auth/organizations/teams/members/remove",Vt="/_lunora/admin/auth/organizations/roles",Jt="/_lunora/admin/auth/organizations/roles/create",Yt="/_lunora/admin/auth/organizations/roles/update",Xt="/_lunora/admin/auth/organizations/roles/remove",Zt="/api/auth",es="/get-session",J=o=>o.startsWith("https://")?`wss://${o.slice(8)}`:o.startsWith("http://")?`ws://${o.slice(7)}`:o,C=(o,e)=>`${o.endsWith("/")?o.slice(0,-1):o}${e}`,y=(o,e)=>{const t=new URLSearchParams;for(const[r,i]of Object.entries(e))i!==void 0&&i!==""&&t.set(r,String(i));const s=t.toString();return s===""?o:`${o}?${s}`},ts=[oe],l=o=>o??"",se=(o,e)=>{const t=o.error,s=typeof t?.code=="string"?t.code:void 0,r=typeof t?.message=="string"?t.message:void 0;return{code:s,messageText:(typeof o.message=="string"?o.message:void 0)??r??e}},ss=o=>{const{code:e,messageText:t}=se(o,"stream error");return e===void 0?new Error(t):new m(e,t)},Y=o=>{const{code:e,messageText:t}=se(o,"subscription error");return{message:t,...e===void 0?{}:{code:e}}};function K(o){if(o!==void 0)return e=>{o(e)}}const E=(o,e)=>{for(const t of o)try{t(e)}catch{}},rs=new TextDecoder,is=o=>{if(typeof o=="string")return o;if(o instanceof ArrayBuffer)return rs.decode(o)},b=(o,e)=>{if(!o.socket||o.wsState!=="open")return!1;try{return o.socket.send(JSON.stringify(e)),!0}catch{return!1}},_=o=>{const e=new Error(o.message??"request failed");return e.code=o.code,o.data!==void 0&&(e.data=T(o.data)),o.hint!==void 0&&(e.hint=o.hint),o.docsUrl!==void 0&&(e.docsUrl=o.docsUrl),e},X=(o,e)=>{const t=_(o),s=Ee(t,e);return s!==void 0&&(t.data=s),t},v=(o,e)=>{try{return W(o)}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)}},ns=(o,e)=>{const t=Array.from({length:e});for(const s of o){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:T(r?.result)}}return t.map(s=>s??{error:new Error("batch call returned no result"),ok:!1})},as=Promise.resolve();class re{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 k;tabCoordinator;leaderStatus;leaderWasEverConnected=!1;connections=new Map;defaultConnectionContext;connectionContexts=new Map;connectionContextHolders=new Map;authToken=null;authSubject=void 0;subjectToken=null;queuedIdentities=new Map;queuedOfflineShardKeys=new Set;closed=!1;authTokenListeners=new w;statusListeners=new w;tokenExpiredListeners=new w;mutationSettledListeners=new w;pendingChangeListeners=new w;whisperHandlers=new Map;lastStatus="idle";nextSubId=0;nextStreamId=0;streams=new Map;adminSocketTeardowns=new Set;offlineFlushes=new Map;replayRetryState=new Map;replayRetryTimers=new Map;shapeSubscriptions=new Map;pokeBuffers=new Map;nextShapeId=0;constructor(e){this.url=e.url,this.wsUrl=e.wsUrl??C(J(e.url),Me),this.wsToken=e.wsToken;const t=e.authBasePath??Zt;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??ce(),this.reconnectOptions=e.reconnect,this.heartbeatIntervalMs=e.heartbeatIntervalMs??Fe,this.connectTimeoutMs=e.connectTimeoutMs??Ue,this.defaultConnectionContext=e.connectionContext,this.persistence=Se(e.persistence,e.outbox===void 0),this.persistenceVersion=e.persistenceVersion,this.queryCache=be(e.queryCache),this.onPersistenceError=e.offlineQueue?.onPersistenceError,this.clientQueryStore=new he,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=as),this.offlineQueue=new me(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-${Q()}`,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(),i=this.authSubject===void 0||this.subjectToken===this.authToken;this.authToken=e,t!==void 0?(this.authSubject=t,this.subjectToken=e):e===null&&(this.authSubject=void 0,this.subjectToken=null);const n=this.identityFingerprint();if(n!==r&&(!s&&i?(this.restampQueuedIdentity(r,n),this.restampWatermarks(r,n),this.restampConnectionIdentity(r,n)):this.rejectQueuedForIdentityChange(r),this.tabCoordinator)){const a=this.tabCoordinator.isLeader();this.tabCoordinator.stop(),this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start(),a&&this.tabCoordinator.promoteImmediately()}s&&this.authTokenListeners.emit(e),this.offlineQueue.size>0&&this.computeStatus()==="connected"&&this.flushAllOfflineQueues()}getAuthToken(){return this.authToken}currentIdentity(){return this.identityFingerprint()}replayIdentityVerdict(e){if(this.subjectAwaitingReconfirm())return"unknown";const t=this.identityFingerprint();return e===t||e!==void 0&&this.isSameCredentialUnderTokenHash(e)?"match":t===null?"unknown":"mismatch"}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 m("INTERNAL",`callMutator: clientSeq must be a positive integer, got ${String(r)}`);const i=s?.shardKey??"",n=this.identityFingerprint();let a;const c=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(n??"")?.get(i)??0)){let d=this.clientWatermarks.get(n??"");d===void 0&&(G(this.clientWatermarks,Be),d=new Map,this.clientWatermarks.set(n??"",d)),d.set(i,a)}return{applied:a===void 0||a===r,result:c}}onAuthTokenChange(e){return this.authTokenListeners.add(e)}async getCurrentUser(){if(this.closed||!this.fetchImpl)return null;const e={},t=this.authToken;this.authToken&&(e.authorization=`Bearer ${this.authToken}`);try{const s=await this.fetchImpl(C(this.url,`${this.authBasePath}${es}`),{credentials:"include",headers:e,method:"GET"});if(!s.ok)return null;const i=(await s.json())?.user??null;return this.adoptResolvedSubject(t,i),i}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={}){this.assertLeaderOwnedSurface("setConnectionContext");const s=l(t.shardKey);e===void 0?this.connectionContexts.delete(s):this.connectionContexts.set(s,e),this.refreshConnectionContext(s)}acquireConnectionContext(e,t={}){if(this.followsAnotherTab())return()=>{};const s=l(t.shardKey),r={context:e},i=this.connectionContextHolders.get(s);i?i.push(r):this.connectionContextHolders.set(s,[r]),this.refreshConnectionContext(s);let n=!1;return()=>{if(n)return;n=!0;const a=this.connectionContextHolders.get(s);if(!a)return;const c=a.indexOf(r);c!==-1&&a.splice(c,1),a.length===0&&this.connectionContextHolders.delete(s),this.refreshConnectionContext(s)}}whisperSubscribe(e,t,s={}){this.assertLeaderOwnedSurface("whisperSubscribe");const r=l(s.shardKey);let i=this.whisperHandlers.get(r);i||(i=new Map,this.whisperHandlers.set(r,i));let n=i.get(e);const a=n===void 0;if(n||(n=new Set,i.set(e,n)),n.add(t),this.ensureSocket(s.shardKey),a){const c=this.getConnection(s.shardKey);c&&b(c,{topic:e,type:"whisper_subscribe"})}return()=>{const c=this.whisperHandlers.get(r),h=c?.get(e);if(!h?.delete(t)||h.size>0)return;c?.delete(e),c?.size===0&&this.whisperHandlers.delete(r);const d=this.getConnection(s.shardKey);d&&b(d,{topic:e,type:"whisper_unsubscribe"})}}whisper(e,t,s={}){this.assertLeaderOwnedSurface("whisper"),this.ensureSocket(s.shardKey);const r=this.getConnection(s.shardKey);r&&b(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 i of s){const n=this.connections.get(i);e.push({confirmedMutationWatermark:t?.get(i)??0,hasSocket:n?.socket!==void 0,shardKey:i===""?void 0:i,wasEverConnected:n?.wasEverConnected??!1,wsState:n?.wsState??"idle"})}const r=this.subscriptions.all().map(i=>({acked:i.acked,functionPath:i.fn.__lunoraRef,id:i.id,kind:"query",lastMutationId:i.lastMutationId,pendingOptimisticLayers:i.optimisticLayers.length,serverCursor:i.serverCursor,shardKey:i.shardKey,subscriberCount:i.callbacks.size}));for(const i of this.shapeSubscriptions.values())r.push({acked:i.serverCursor!==void 0,functionPath:`shape:${i.name}`,id:i.id,kind:"shape",lastMutationId:i.lastMutationId,pendingOptimisticLayers:0,rowCount:i.rows.size,serverCursor:i.serverCursor,shardKey:i.shardKey,subscriberCount:i.callbacks.size});return{clientId:this.clientId,closed:this.closed,connectionStatus:this.computeStatus(),pendingWrites:this.offlineQueue.size,shards:e.toSorted((i,n)=>(i.shardKey??"").localeCompare(n.shardKey??"")),subscriptions:r.toSorted((i,n)=>i.functionPath.localeCompare(n.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 Te(this,e,t,s)}whenReady(){return this.readyPromise}get isReady(){return this.readyResolved}peekHydratedQuery(e,t,s){if(!this.readyResolved)return;const r=q(t),i=P(e,r,s),n=this.hydratedQueryCache.get(i);if(n!==void 0)return n.identity===this.identityFingerprint()?n.value:void 0}peekActiveQuerySnapshot(e,t,s){const r=k.key(e,t,s),i=this.subscriptions.get(r);return{present:i!==void 0,value:i?.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 m("INTERNAL","LunoraClient: no `fetch` implementation available");if(e.length===0)return[];const t=await this.fetchImpl(C(this.url,j),{body:JSON.stringify({calls:e.map((i,n)=>({args:v(i.args??{},`args for batch call '${i.fn.__lunoraRef}'`),functionPath:i.fn.__lunoraRef,id:n,shardKey:i.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 m("INTERNAL",`LunoraClient: batch response was not JSON (status ${t.status.toString()})`)}if(!t.ok||r.error&&!r.results)throw r.error?_(r.error):new m("INTERNAL",`LunoraClient: batch request failed (status ${t.status.toString()})`);for(const i of r.results??[]){const n=i.body?.commitCursor;typeof i.id=="number"&&typeof n=="number"&&this.recordShardCursor(e[i.id]?.shardKey,n)}return ns(r.results??[],e.length)}async mutation(e,t,s={}){this.assertOpen();const r=t,i=s.mutationId??Q(),{confirms:n,rollbacks:a}=this.applyOptimisticUpdates(e.__lunoraRef,r,s.shardKey,s.optimistic);s.optimisticUpdate&&this.applyOptimisticUpdate(s.optimisticUpdate,t,s.shardKey,a,n);const c=this.offlineFlushes.get(l(s.shardKey));c!==void 0&&await c;const{hasSocket:h,wasEverConnected:d,wsState:u}=this.connectionGateState(s.shardKey),{queueBeforeFirstConnect:f}=this.offlineQueue,S=d||f,p=this.WebSocketImpl!==void 0&&S;if(u!=="open"&&!h&&p||u==="connecting"&&S)return this.enqueueOfflineMutation(e,r,s.shardKey,i,a,n,s.precondition);try{let I;const ie=await this.rpc(e.__lunoraRef,r,s.shardKey,{captureBookmark:!0,mutationId:i,onCommitCursor:F=>{I=F}});for(const F of n)F(I);return ie}catch(I){throw H(a),I}}async action(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey,{attachBookmark:!0,captureBookmark:!0})}async importRows(e,t,s={}){this.assertOpen();const r=Math.max(1,Math.trunc(s.chunkSize??500)),i=s.toArgs??(h=>({rows:h})),n=t.length;let a=0,c=0;for(let h=0;h<n;h+=r){const d=t.slice(h,h+r),u=c;await this.mutation(e,i(d),{...s.importId===void 0?{}:{mutationId:`${s.importId}:${String(u)}`},shardKey:s.shardKey}),c+=1,a+=d.length,s.onProgress?.({done:a,total:n})}return{chunks:c,imported:a}}async shardTraffic(e){this.assertOpen();const t=await this.adminFetch(Ke,"POST",{table:e});return{failed:t.failed??0,ok:t.ok??0,shards:t.shards??[]}}async listScheduledJobs(){return this.assertOpen(),(await this.adminFetch(We,"GET")).records??[]}async schedulerStatus(){this.assertOpen();const e=await this.adminFetch(qe,"GET");return{backlog:e.backlog??0,inFlight:e.inFlight??0,pools:e.pools??[]}}async cancelScheduledJob(e){return this.assertOpen(),{cancelled:(await this.adminFetch($e,"POST",{id:e})).cancelled===!0}}async listDeadJobs(){return this.assertOpen(),await ge(async e=>await this.adminFetch(e===void 0?V:`${V}?cursor=${encodeURIComponent(e)}`,"GET"))}async retryDeadJob(e){return this.assertOpen(),{retried:(await this.adminFetch(Ge,"POST",{id:e})).retried===!0}}async removeDeadJob(e){return this.assertOpen(),{removed:(await this.adminFetch(je,"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(`${ze}?${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(`${Ve}?${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(Je,"POST",{action:e.action,id:e.id,name:e.name})).status??"unknown"}}subscribeScheduledJobs(e){if(this.assertOpen(),this.WebSocketImpl===void 0)return()=>{};const t=C(J(this.url),Qe),s=$(this.reconnectOptions),r={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,socket:void 0};let i,n=!1;const a=()=>{n||this.closed||(i=setTimeout(d,s.next()))},c=f=>{if(n||this.WebSocketImpl===void 0)return;const S=f===void 0?t:`${t}?token=${encodeURIComponent(f)}`;this.openManagedSocket(r,S,this.connectTimeoutMs,{onClose:()=>{a()},onMessage:p=>{try{const g=JSON.parse(typeof p.data=="string"?p.data:"");g.type==="jobs"&&Array.isArray(g.records)&&(s.reset(),e(g.records))}catch{}}})},h=async f=>{let S;try{S=await f()}catch{a();return}c(S)},d=()=>{if(n||this.WebSocketImpl===void 0)return;const{wsToken:f}=this;if(typeof f=="function"){h(f).catch(()=>{});return}c(f)};d();const u=()=>{n=!0,i!==void 0&&(clearTimeout(i),i=void 0),r.connectTimer!==void 0&&(clearTimeout(r.connectTimer),r.connectTimer=void 0),this.stopHeartbeat(r),r.socket?.close(),r.socket=void 0};return this.adminSocketTeardowns.add(u),()=>{this.adminSocketTeardowns.delete(u),u()}}async listFunctions(){return this.assertOpen(),(await this.adminFetch(Ze,"GET")).functions??[]}async getCronJobs(){return this.assertOpen(),(await this.adminFetch(et,"GET")).jobs??[]}async runCronJob(e){this.assertOpen();const t=await this.adminFetch(tt,"POST",{name:e});return{name:t.name??e,ran:t.ran===!0}}async fetchOpenApi(){return this.assertOpen(),await this.adminFetch(st,"GET")}async fetchOpenRpc(){return this.assertOpen(),await this.adminFetch(rt,"GET")}async listStorageObjects(e={}){this.assertOpen();const t=y(D,{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=`${D}?key=${encodeURIComponent(e)}${N(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(Xe,"GET")).buckets??[]}async uploadStorageObject(e){this.assertOpen();const t=`${D}?key=${encodeURIComponent(e.key)}${N(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())}`,i=`${Ye}?key=${encodeURIComponent(e)}${r}${N(t?.bucket)}`,n=await this.adminFetch(i,"GET");if(typeof n.url!="string")throw new TypeError("LunoraClient: storage URL endpoint returned no `url`");return n.url}async listGlobalTables(){return this.assertOpen(),await this.adminFetch(it,"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(W(e.filters))),T(await this.adminFetch(`${nt}?${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(W(e.filters))),T(await this.adminFetch(`${at}?${t.toString()}`,"GET"))}async listVectorIndexes(){return this.assertOpen(),(await this.adminFetch(ot,"GET")).indexes??[]}async queryVectorIndex(e){return this.assertOpen(),(await this.adminFetch(ct,"POST",e)).matches??[]}async queryLogArchive(e={}){this.assertOpen();const t=await this.adminFetch(ht,"POST",e);return{nextCursor:t.nextCursor,rows:t.rows??[]}}async listKvNamespaces(){return this.assertOpen(),(await this.adminFetch(dt,"GET")).namespaces??[]}async listKvKeys(e){this.assertOpen();const t=y(ut,{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(B,{key:e.key,namespace:e.namespace});return await this.adminFetch(t,"GET")}async putKvValue(e){this.assertOpen(),await this.adminFetch(B,"PUT",e)}async deleteKvKey(e){this.assertOpen();const t=y(B,{key:e.key,namespace:e.namespace});await this.adminFetch(t,"DELETE")}async listAuthUsers(e={}){this.assertOpen();const t=y(lt,{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(mt,"POST",e)}async setAuthUserRole(e){return await this.adminFetch(pt,"POST",e)}async banAuthUser(e){return await this.adminFetch(yt,"POST",e)}async unbanAuthUser(e){return await this.adminFetch(St,"POST",e)}async setAuthUserPassword(e){await this.adminFetch(bt,"POST",e)}async removeAuthUser(e){await this.adminFetch(Tt,"POST",e)}async impersonateAuthUser(e){return await this.adminFetch(vt,"POST",e)}async revokeAuthSession(e){await this.adminFetch(gt,"POST",e)}async revokeAuthUserSessions(e){await this.adminFetch(kt,"POST",e)}async getAuthCapabilities(){return await this.adminFetch(Ct,"GET")}async updateAuthUser(e){return await this.adminFetch(wt,"POST",e)}async listAuthAccounts(e){return await this.adminFetch(y(Et,{userId:e.userId}),"GET")}async unlinkAuthAccount(e){await this.adminFetch(_t,"POST",e)}async listAuthPasskeys(e){return await this.adminFetch(y(At,{userId:e.userId}),"GET")}async deleteAuthPasskey(e){await this.adminFetch(It,"POST",e)}async disableAuthTwoFactor(e){await this.adminFetch(Ot,"POST",e)}async listAuthOrganizations(e={}){return await this.adminFetch(y(Rt,{limit:e.limit,offset:e.offset}),"GET")}async listAuthOrgMembers(e){const t=y(Pt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async listAuthOrgInvitations(e){const t=y(Mt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async removeAuthOrgMember(e){await this.adminFetch(Ht,"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(Ut,"POST",e)}async updateAuthOrganization(e){return await this.adminFetch(xt,"POST",e)}async deleteAuthOrganization(e){await this.adminFetch(Nt,"POST",e)}async addAuthOrgMember(e){return await this.adminFetch(Dt,"POST",e)}async inviteAuthOrgMember(e){return await this.adminFetch(Bt,"POST",e)}async setAuthOrgMemberRole(e){return await this.adminFetch(Kt,"POST",e)}async listAuthOrgTeams(e){const t=y(Wt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgTeam(e){return await this.adminFetch(qt,"POST",e)}async updateAuthOrgTeam(e){return await this.adminFetch(Qt,"POST",e)}async removeAuthOrgTeam(e){await this.adminFetch($t,"POST",e)}async listAuthOrgTeamMembers(e){const t=y(Gt,{limit:e.limit,offset:e.offset,teamId:e.teamId});return await this.adminFetch(t,"GET")}async addAuthOrgTeamMember(e){return await this.adminFetch(jt,"POST",e)}async removeAuthOrgTeamMember(e){await this.adminFetch(zt,"POST",e)}async listAuthOrgRoles(e){const t=y(Vt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgRole(e){return await this.adminFetch(Jt,"POST",e)}async updateAuthOrgRole(e){return await this.adminFetch(Yt,"POST",e)}async deleteAuthOrgRole(e){await this.adminFetch(Xt,"POST",e)}async listAuthSessions(e={}){this.assertOpen();const t=y(ft,{limit:e.limit,offset:e.offset,userId:e.userId});return await this.adminFetch(t,"GET")}subscribe(e,t,s,r={}){this.assertOpen();const i=t??{},n=k.key(e.__lunoraRef,i,r.shardKey);let a=this.subscriptions.get(n);const c=K(s),h=K(r.onError),d=K(r.onCheckpoint);if(!a){this.nextSubId+=1;const f=`sub_${this.nextSubId.toString()}`,S=q(i),p=this.takeHydratedCache(e.__lunoraRef,S,r.shardKey);a={acked:!1,args:i,argsKey:S,callbacks:new Set,checkpointCallbacks:new Set,errorCallbacks:new Set,fn:e,id:f,lastValue:p?.value,optimisticLayers:[],serverBase:p?.value,serverCursor:p?.serverCursor,shardKey:r.shardKey,wireArgs:v(i,`args for '${e.__lunoraRef}'`),...p?.serverEpoch===void 0?{}:{serverEpoch:p.serverEpoch}},this.subscriptions.add(a)}if(a.callbacks.add(c),h&&a.errorCallbacks.add(h),d&&a.checkpointCallbacks.add(d),a.lastValue!==void 0)try{c(a.lastValue)}catch{}this.ensureSocket(r.shardKey),this.sendSubscribeIfOpen(a);const u=a;return()=>{u.callbacks.delete(c),h&&u.errorCallbacks.delete(h),d&&u.checkpointCallbacks.delete(d),u.callbacks.size===0&&(this.sendOrQueueUnsubscribe(u.shardKey,u.id,"unsubscribe"),this.subscriptions.remove(u))}}subscribeShape(e,t,s={}){if(this.assertOpen(),this.followsAnotherTab())return()=>{};this.nextShapeId+=1;const r=`shape_${this.nextShapeId.toString()}`,i={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,i),this.ensureSocket(s.shardKey),this.sendShapeSubscribeIfOpen(i),()=>{this.shapeSubscriptions.delete(r),this.sendOrQueueUnsubscribe(i.shardKey,r,"shape_unsubscribe")}}stream(e,t,s={}){if(this.assertOpen(),this.WebSocketImpl===void 0)throw new m("INTERNAL","LunoraClient: streams require a WebSocket implementation");this.nextStreamId+=1;const r=`stream_${this.nextStreamId.toString()}`,{shardKey:i}=s,n=t??{},{handle:a,iterable:c}=ve({maxBuffer:s.maxBuffer,onCancel:()=>{this.cancelStream(r,i)}});this.ensureSocket(i);const h=this.getConnection(i),d={id:r,query:{args:v(n,`stream args for '${e.__lunoraRef}'`),functionPath:e.__lunoraRef,shardKey:i},type:"stream"},u={durable:s.durable===!0,generation:void 0,handle:a,lastSeq:0,message:d,shardKey:i,started:!1};this.streams.set(r,u);const f=h?.wsState==="open"&&b(h,d);if(u.started=f,!f&&h===void 0)return this.streams.delete(r),a.fail(new m("STREAM_DISCONNECTED","stream unavailable: this tab is not the cross-tab WebSocket leader, so it holds no socket to stream over")),c;if(!f){for(h.pendingStreams=h.pendingStreams??[];h.pendingStreams.length>=De;){const p=h.pendingStreams.shift()?.id,g=p?this.streams.get(p):void 0;g&&(g.handle.fail(new m("STREAM_QUEUE_OVERFLOW","stream-start frame evicted while socket was unreachable")),this.streams.delete(p))}h.pendingStreams.push(d)}return c}httpStream(e,t,s={}){if(this.closed)throw new m("CLIENT_CLOSED","LunoraClient is closed");if(!this.fetchImpl)throw new m("INTERNAL","LunoraClient: no `fetch` implementation available");const r={...this.authToken?{authorization:`Bearer ${this.authToken}`}:{},...s.headers};return ue(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 m("CLIENT_CLOSED","LunoraClient closed"));this.streams.clear();for(const e of this.connections.values())this.teardownConnection(e);for(const e of this.adminSocketTeardowns)e();this.adminSocketTeardowns.clear();for(const e of this.replayRetryTimers.values())clearTimeout(e);this.replayRetryTimers.clear(),this.replayRetryState.clear(),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.subscriptions.clear(),this.clientQueryStore.clear(),this.hydratedQueryCache.clear(),this.tabCoordinator?.stop(),this.tabCoordinator=void 0}assertOpen(){if(this.closed)throw new m("INTERNAL","LunoraClient is closed")}followsAnotherTab(){const e=this.tabCoordinator;if(e===void 0||e.isLeader())return!1;const t=e.leaderTabId;return t!==void 0&&t!==e.id}assertLeaderOwnedSurface(e){if(this.followsAnotherTab())throw new m("NOT_IMPLEMENTED",`LunoraClient: \`${e}\` is unavailable on a cross-tab follower tab. The \`crossTabSync\` channel only carries data from the leader tab outward, so this call could never reach the server. Turn off \`crossTabSync\`, or keep \`${e}\` on the leader tab.`)}clearConnectionTimers(e){clearTimeout(e.reconnectTimer),clearTimeout(e.connectTimer),clearTimeout(e.stableTimer),e.reconnectTimer=void 0,e.connectTimer=void 0,e.stableTimer=void 0}teardownConnection(e){const t=l(e.shardKey);for(const[s,r]of this.streams)l(r.shardKey)===t&&(r.handle.fail(new m("STREAM_DISCONNECTED","stream terminated: the connection carrying it was torn down")),this.streams.delete(s));if(e.pendingStreams=void 0,e.pendingUnsubscribes=[],this.clearConnectionTimers(e),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 de({channelName:e,onBecomeLeader:()=>{for(const t of this.subscriptions.all())this.ensureSocket(t.shardKey),this.sendSubscribeIfOpen(t);for(const t of this.queuedOfflineShardKeys)this.ensureSocket(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,i,n)=>{if(n!==void 0&&n!==this.identityFingerprint())return;const a=this.subscriptions.get(t);a&&(a.serverBase=s,r!==void 0&&(a.serverCursor=r,i!==void 0&&(a.serverEpoch=i),U(a,r)),O(a,R(s,a.optimisticLayers)))},onLeaderClaimAnswered:()=>{this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastConnectionStatus(this.computeStatus(),this.identityFingerprint())},onSubscriptionError:(t,s,r)=>{if(r!==void 0&&r!==this.identityFingerprint())return;const i=this.subscriptions.get(t);i&&E(i.errorCallbacks,s)},onSubscriptionSettled:(t,s,r,i,n,a)=>{if(a!==void 0&&a!==this.identityFingerprint())return;const c=this.subscriptions.get(t);if(c){this.ackAndAdvanceCursor(c,s,r),i!==void 0&&n===this.clientId&&(c.lastMutationId=Math.max(c.lastMutationId??0,i));for(const h of c.checkpointCallbacks)h({checkpoint:c.serverCursor,mutationId:c.lastMutationId})}}})}async enqueueOfflineMutation(e,t,s,r,i,n,a){const c=this.identityFingerprint();if(this.outbox){this.outboxMutationCounter+=1;const h=this.outboxMutationCounter;try{await this.outbox.enqueue({args:t,clientId:this.clientId,functionPath:e.__lunoraRef,idempotencyKey:`${this.clientId}:${String(h)}`,identity:c,mutationId:h,shardKey:s})}catch(d){throw H(i),d instanceof Error?d:new Error(String(d))}for(const d of n)d(void 0);return}return new Promise((h,d)=>{const u={args:t,functionPath:e.__lunoraRef,liveAwaiter:!0,id:r,clientId:this.clientId,identity:c,precondition:a,onCommit:f=>{for(const S of n)S(f)},reject:f=>{this.queuedIdentities.delete(r),H(i),d(f instanceof Error?f:new Error(String(f)))},resolve:h,shardKey:s};this.offlineQueue.enqueue(u),this.queuedOfflineShardKeys.add(s),u.id!==void 0&&this.queuedIdentities.set(u.id,c)})}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(),t=new Map;for(const s of this.subscriptions.all())t.set(P(s.fn.__lunoraRef,s.argsKey,s.shardKey),s);for(const{key:s,...r}of e){if(pe(this.persistenceVersion,r.version)){this.queryCache.remove(s).catch(()=>{});continue}const i=t.get(s);if(i){this.seedSubscriptionFromCache(i,r);continue}this.hydratedQueryCache.set(s,r)}}catch{}}seedSubscriptionFromCache(e,t){e.serverBase!==void 0||e.lastValue!==void 0||t.identity!==this.identityFingerprint()||(e.serverBase=t.value,e.serverCursor=t.serverCursor,t.serverEpoch!==void 0&&(e.serverEpoch=t.serverEpoch),O(e,R(t.value,e.optimisticLayers)))}takeHydratedCache(e,t,s){const r=P(e,t,s),i=this.hydratedQueryCache.get(r);if(i!==void 0)return this.hydratedQueryCache.delete(r),i.identity===this.identityFingerprint()?i:void 0}persistQueryValue(e){const t=e.serverBase;if(!this.queryCache||t===void 0)return;const s=P(e.fn.__lunoraRef,e.argsKey,e.shardKey),r=this.getConnection(e.shardKey)?.identity;this.pendingCacheWrites.set(s,{identity:r===void 0?this.identityFingerprint():r,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(()=>{})},xe)}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(async([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 i=[],n=[];if(!r)return{confirms:i,rollbacks:n};const a=k.key(e,t,s),c=this.subscriptions.get(a);if(c){const h=le(c,r);h&&(i.push(h.confirm),n.push(h.rollback))}return{confirms:i,rollbacks:n}}applyOptimisticUpdate(e,t,s,r,i){const{confirms:n,rollbacks:a,store:c}=fe(this.subscriptions,s);try{e(c,t)}catch{H(a);return}r.push(...a),i.push(...n)}getConnection(e){return this.connections.get(l(e))}sendOrQueueUnsubscribe(e,t,s){const r=this.getConnection(e);r&&!b(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=l(e);let s=this.connections.get(t);return s||(s={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,pendingUnsubscribes:[],reconnect:$(this.reconnectOptions),reconnectTimer:void 0,shardKey:e,socket:void 0,stableTimer: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 i=this.bookmark.get();i&&(s["x-d1-bookmark"]=i)}return s}async rpc(e,t,s,r={}){if(!this.fetchImpl)throw new A("LunoraClient: no `fetch` implementation available");const i=this.rpcRequestHeaders(r,s),n=await this.fetchImpl(C(this.url,Pe),{body:JSON.stringify({args:v(t,`args for '${e}'`),functionPath:e,shardKey:s}),headers:i,method:"POST"});if(r.captureBookmark){const c=n.headers.get("x-d1-bookmark");c&&this.bookmark.set(c)}let a;try{a=await n.json()}catch{throw M(n.status,n.statusText,n.headers.get("retry-after"))}if("error"in a)throw X(a.error,n.headers.get("retry-after"));if(!n.ok)throw M(n.status,n.statusText,n.headers.get("retry-after"));return r.onMutationAck?.(a.lastMutationId),r.onCommitCursor?.(a.commitCursor),this.learnDefaultShardKey(n,s),this.recordShardCursor(s,a.commitCursor),T(a.result)}async adminFetch(e,t,s,r){if(!this.fetchImpl)throw new m("INTERNAL","LunoraClient: no `fetch` implementation available");const i={};this.authToken&&(i.authorization=`Bearer ${this.authToken}`);const n=s instanceof ArrayBuffer||s instanceof Blob;let a;s===void 0?a=void 0:n?(a=s,r!==void 0&&(i["content-type"]=r)):(a=JSON.stringify(s),i["content-type"]="application/json");const c=await this.fetchImpl(C(this.url,e),{body:a,headers:i,method:t});let h;try{h=await c.json()}catch{const d=c.statusText?` ${c.statusText}`:"";throw new m("INTERNAL",`LunoraClient: response was not JSON (status ${c.status.toString()}${d})`)}if(typeof h=="object"&&h!==null&&"error"in h){const d=h.error,u=new Error(d.message??"admin request failed");throw u.code=d.code,u}if(!c.ok){const d=c.statusText?` ${c.statusText}`:"";throw new m("INTERNAL",`LunoraClient: admin request failed (status ${c.status.toString()}${d})`)}return h}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(l(e.shardKey));b(e,{caps:ts,clientId:this.clientId,id:"connect",type:"connect",...t===void 0?{}:{context:t}})}resendShapeSubscriptions(e){for(const t of this.shapeSubscriptions.values())l(t.shardKey)===l(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:i}=this;if(i===void 0)throw new m("INTERNAL","no WebSocket implementation available");const n=new i(t);e.socket=n;const a=()=>{this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket===n&&(e.socket=void 0)},c=h=>{a(),r.onClose(h)};s>0&&(e.connectTimer=setTimeout(()=>{if(e.connectTimer=void 0,e.socket===n){try{n.close()}catch{}c()}},s)),n.addEventListener("open",()=>{if(e.socket===n){e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.lastFrameAt=Date.now();try{r.onOpen?.()}catch(h){console.error("[lunora] connection open handler threw",h)}this.startHeartbeat(e,c)}}),n.addEventListener("message",h=>{if(e.socket===n){e.lastFrameAt=Date.now();try{r.onMessage(h)}catch(d){console.error("[lunora] server frame handler threw",d)}}}),n.addEventListener("close",h=>{e.socket===n&&c(h)}),n.addEventListener("error",()=>{e.socket===n&&c()})}openSocket(e,t,s){this.WebSocketImpl!==void 0&&(e.identity=this.identityFingerprint(),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,clearTimeout(e.stableTimer),e.stableTimer=setTimeout(()=>{e.wsState==="open"&&e.reconnect.reset()},Ne),this.emitConnectionStatus(),this.sendConnectEnvelope(e),this.markShardPendingAck(t);for(const i of this.subscriptions.all())l(i.shardKey)===l(t)&&this.sendSubscribeIfOpen(i);if(this.resendShapeSubscriptions(t),e.pendingUnsubscribes.length>0){const i=e.pendingUnsubscribes;e.pendingUnsubscribes=[];for(const{id:n,type:a}of i)b(e,{id:n,type:a})}this.flushPendingStreams(e);const r=this.whisperHandlers.get(l(t));if(r)for(const i of r.keys())b(e,{topic:i,type:"whisper_subscribe"});this.flushOfflineQueue(t).catch(()=>{})}}))}flushPendingStreams(e){if(!e.pendingStreams||e.pendingStreams.length===0)return;const t=e.pendingStreams;e.pendingStreams=[];for(const s of t){const r=b(e,s)?this.streams.get(String(s.id)):void 0;r&&(r.started=!0)}}cancelStream(e,t){const s=this.getConnection(t),r=this.streams.get(e);s&&(s.pendingStreams=s.pendingStreams?.filter(i=>i.id!==e),!b(s,{id:e,type:"unsubscribe"})&&r?.durable===!0&&r.started&&s.pendingUnsubscribes.push({id:e,type:"unsubscribe"})),this.streams.delete(e)}handleDisconnect(e){if(this.closed||e.wsState==="idle"||e.wsState==="closed")return;this.stopHeartbeat(e),this.clearConnectionTimers(e),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,i]of this.streams)if(!(l(i.shardKey)!==l(e.shardKey)||t.has(r))){if(i.durable){const n={...i.message,...i.generation===void 0?{}:{generation:i.generation},sinceChunk:i.lastSeq};i.message=n,e.pendingStreams=[...(e.pendingStreams??[]).filter(a=>a.id!==r),n];continue}i.handle.fail(new m("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=l(e);for(const s of this.subscriptions.all())l(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,r=e.serverCursor!==void 0&&e.serverBase!==void 0;b(t,{id:e.id,query:{args:e.wireArgs,functionPath:e.fn.__lunoraRef,table:s,...r?{sinceSeq:e.serverCursor}:{},...r&&e.serverEpoch!==void 0?{sinceEpoch:e.serverEpoch}:{}},type:"subscribe"})}sendShapeSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);t?.wsState==="open"&&b(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=is(e);if(s===void 0)return;let r;try{r=JSON.parse(s)}catch{return}switch(r.type!=="error"&&this.getConnection(t)?.reconnect.reset(),r.type){case"ack":{const i=this.subscriptions.getById(r.id);i&&(i.acked=!0);return}case"chunk":{const{data:i,generation:n,id:a,seq:c}=r,h=this.streams.get(a);h&&typeof c=="number"&&(h.lastSeq=c,typeof n=="number"&&(h.generation=n),h.durable=!0),h?.handle.push(T(i));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,t);break}case"pokePart":{this.handlePokePart(r,t);break}case"pokeStart":{this.handlePokeStart(r,t);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(ss(e)),this.streams.delete(s);return}const i=s===void 0?void 0:this.subscriptions.getById(s);if(i){const a=Y(e),c=this.identityFingerprint(),h=k.keyOf(i);E(i.errorCallbacks,a),this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastSubscriptionError(h,a,c);return}const n=s===void 0?void 0:this.shapeSubscriptions.get(s);n&&E(n.errorCallbacks,Y(e))}pokeBufferKey(e,t){return`${l(e)}\0${t}`}handlePokeStart(e,t){G(this.pokeBuffers,re.MAX_POKE_BUFFERS),this.pokeBuffers.set(this.pokeBufferKey(t,e.pokeId),{baseCheckpoint:e.baseCheckpoint,bases:new Map,epoch:e.epoch,lastMutationId:new Map,parts:new Map,resets:new Set})}handlePokePart(e,t){const s=this.pokeBuffers.get(this.pokeBufferKey(t,e.pokeId));if(!s)return;const r=s.parts.get(e.shapeId)??[];for(const n of e.rowsPatch)r.push(n.value===void 0?n:{...n,value:T(n.value)});s.parts.set(e.shapeId,r),e.lastMutationId!==void 0&&s.lastMutationId.set(e.shapeId,e.lastMutationId);const i=e.baseCheckpoint??s.baseCheckpoint;i!==void 0&&s.bases.set(e.shapeId,i),e.reset===!0&&s.resets.add(e.shapeId)}handlePokeEnd(e,t){const s=this.pokeBufferKey(t,e.pokeId),r=this.pokeBuffers.get(s);if(r){this.pokeBuffers.delete(s);for(const i of r.parts.keys()){const n=this.shapeSubscriptions.get(i);n&&this.applyPokePart(n,r,e)}}}applyPokePart(e,t,s){const r=t.parts.get(e.id)??[],i=t.resets.has(e.id),n=t.bases.get(e.id),a=t.epoch!==void 0&&e.serverEpoch!==void 0&&t.epoch!==e.serverEpoch,c=n!==void 0&&e.serverCursor!==void 0&&e.serverCursor!==n;if(!i&&(a||c)){e.rows.clear(),e.serverCursor=void 0,e.serverEpoch=void 0,this.emitShapeRows(e),this.sendShapeSubscribeIfOpen(e);return}i&&e.rows.clear(),He(e.rows,r),s.checkpoint!==void 0&&(e.serverCursor=s.checkpoint),s.epoch!==void 0&&(e.serverEpoch=s.epoch);const h=t.lastMutationId.get(e.id);h!==void 0&&(e.lastMutationId=h),this.emitShapeRows(e),e.onCheckpoint?.({checkpoint:e.serverCursor,mutationId:e.lastMutationId})}resnapshotSubscription(e){e.acked=!1,e.serverCursor=void 0,e.serverEpoch=void 0,console.warn("[lunora] could not merge a row delta into the cached result; re-subscribing for a full snapshot"),this.sendSubscribeIfOpen(e)}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;let r;try{r=this.resolveDataPayload(e,s)}catch(i){E(s.errorCallbacks,{code:"WIRE_DECODE_FAILED",message:`could not decode a server frame for this subscription — ${i instanceof Error?i.message:String(i)}`});return}if(r===z){this.resnapshotSubscription(s);return}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 i of s.checkpointCallbacks)i({checkpoint:s.serverCursor,mutationId:s.lastMutationId})}if(this.persistQueryValue(s),U(s,s.serverCursor),O(s,R(r,s.optimisticLayers)),this.tabCoordinator?.isLeader()){const i=k.keyOf(s);this.tabCoordinator.broadcastSubscriptionData(i,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=Math.max(t.lastMutationId??0,e.lastMutationId));for(const s of t.checkpointCallbacks)s({checkpoint:t.serverCursor,mutationId:t.lastMutationId});if(this.tabCoordinator?.isLeader()){const s=k.keyOf(t);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),U(e,e.serverCursor)&&O(e,R(e.serverBase,e.optimisticLayers)))}resolveDataPayload(e,t){if("data"in e&&e.data!==void 0)return T(e.data);const s=T(e.delta);return ne(s)?t.serverBase===void 0?s:ae(t.serverBase,s)??z:s}dispatchWhisper(e,t){const s=this.whisperHandlers.get(l(t))?.get(e.topic);if(!s)return;const r=T(e.data);for(const i of s)try{i(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,E(s.errorCallbacks,{code:"SUBSCRIPTION_CANCELLED",message:"subscription was cancelled by the server"}))}unpersist(e){e&&this.persistence?.remove(e).catch(t=>{ye(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 i=e.charCodeAt(r);t^=i,t=Math.imul(t,16777619),s=Math.imul(s,33)+i}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}adoptResolvedSubject(e,t){this.closed||t===null||this.authToken!==e||this.setAuthToken(e,t.id)}subjectAwaitingReconfirm(){return this.authSubject!==void 0&&this.authSubject!==null&&this.subjectToken!==this.authToken}stampOf(e){const t=e.id===void 0?void 0:this.queuedIdentities.get(e.id);return t===void 0?e.identity:t}rejectQueuedForIdentityChange(e){const t=this.offlineQueue.drain(),s=[];for(const r of t){if(this.replayIdentityVerdict(this.stampOf(r))!=="mismatch"){s.push(r);continue}this.queuedIdentities.delete(r.id??""),this.unpersist(r.id);const i=new Error("offline mutation discarded: auth identity changed before replay");i.code="OFFLINE_IDENTITY_CHANGED",r.reject(i),this.emitItemSettled(r,"rejected",i)}this.offlineQueue.requeue(s),e!==null&&this.clearQueryCacheForIdentityChange()}restampConnectionIdentity(e,t){for(const s of this.connections.values())s.identity===e&&(s.identity=t)}restampQueuedIdentity(e,t){for(const[s,r]of this.queuedIdentities)r===e&&this.queuedIdentities.set(s,t);this.offlineQueue.restampIdentity(e,t)}restampWatermarks(e,t){const s=e??"",r=this.clientWatermarks.get(s);if(r===void 0)return;this.clientWatermarks.delete(s);const i=t??"",n=this.clientWatermarks.get(i);if(n===void 0)this.clientWatermarks.set(i,r);else for(const[a,c]of r)n.set(a,c)}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=l(e),s=this.offlineFlushes.get(t);if(s===void 0&&this.offlineQueue.size===0)return;const r=(async()=>{await(s??Promise.resolve());try{await this.drainOfflineQueue(e)}catch{}})();this.offlineFlushes.set(t,r),await r,this.offlineFlushes.get(t)===r&&this.offlineFlushes.delete(t)}async drainOfflineQueue(e){const t=this.offlineQueue.drainConflict();for(const h of t){this.unpersist(h.id),this.queuedIdentities.delete(h.id??"");const d=new Error("offline mutation skipped: precondition failed before replay");d.code="OFFLINE_PRECONDITION_FAILED",this.emitItemSettled(h,"rejected",d)}const s=l(e),r=this.offlineQueue.drain(h=>l(h.shardKey)===s);if(r.length===0)return;const i=[],n=[];for(const h of r){const d=this.replayGateVerdict(h);d==="send"?i.push(h):d==="hold"&&n.push(h)}if(this.offlineQueue.requeue(n),n.length>0&&this.subjectAwaitingReconfirm()&&this.getCurrentUser().catch(()=>{}),i.length===0)return;const a=this.encodableOrSettleTerminal(i);if(a.length===0)return;if(a.length===1){await this.replaySequential(a,e),this.scheduleRateLimitedRetry(e);return}const c=[];for(let h=0;h<a.length;h+=x){const d=a.slice(h,h+x),u=await this.replayBatched(d,e);if(c.push(...u.requeue),u.stop){c.push(...a.slice(h+x));break}}c.length>0&&this.offlineQueue.requeue(c),this.scheduleRateLimitedRetry(e)}noteReplayRetryDelay(e,t){const s=l(e),r=this.replayRetryState.get(s),i=(r?.attempts??0)+1,n=Ie(t,i);this.replayRetryState.set(s,{attempts:i,delayMs:n===void 0?r?.delayMs:Math.max(r?.delayMs??0,n)})}scheduleRateLimitedRetry(e){const t=l(e),s=this.replayRetryState.get(t),r=s?.delayMs;if(s===void 0||r===void 0||this.closed||this.offlineQueue.size===0){this.replayRetryState.delete(t);return}s.delayMs=void 0;const i=this.replayRetryTimers.get(t);i!==void 0&&clearTimeout(i),this.replayRetryTimers.set(t,setTimeout(()=>{this.replayRetryTimers.delete(t),this.flushOfflineQueue(e).catch(()=>{})},r))}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}replayGateVerdict(e){const t=this.stampOf(e);if(t===void 0)return this.queuedIdentities.delete(e.id??""),"send";const s=this.replayIdentityVerdict(t);if(s==="unknown")return"hold";if(this.queuedIdentities.delete(e.id??""),s==="match")return"send";this.unpersist(e.id);const r=new Error("offline mutation skipped: auth identity changed before replay");return r.code="OFFLINE_IDENTITY_CHANGED",e.reject(r),this.emitItemSettled(e,"rejected",r),"reject"}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,t){for(let s=0;s<e.length;s+=1){const r=e[s];if(r)try{let i;const n=await this.rpc(r.functionPath,r.args,r.shardKey,{captureBookmark:!0,clientId:r.clientId??this.clientId,mutationId:r.id,onCommitCursor:a=>{i=a}});this.settleReplaySuccess(r,n,i)}catch(i){if(!ke(i)){this.settleReplayTerminal(r,i);continue}this.noteReplayRetryDelay(t,i),this.offlineQueue.requeue(e.slice(s));return}}}async replayBatched(e,t){if(!this.fetchImpl)return{requeue:e,stop:!0};const s=JSON.stringify({calls:e.map((c,h)=>({args:v(c.args,`args for '${c.functionPath}'`),functionPath:c.functionPath,id:h,clientId:c.clientId??this.clientId,mutationId:c.id,shardKey:c.shardKey}))});if(e.length>1&&Re(s)>Oe)return await this.replayBatchedHalves(e,t);let r;try{r=await this.fetchImpl(C(this.url,j),{body:s,headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"})}catch{return{requeue:e,stop:!0}}const i=r.headers.get("x-d1-bookmark");if(i&&this.bookmark.set(i),r.status===413&&e.length>1)return await this.replayBatchedHalves(e,t);let n;const a=r.headers.get("retry-after");try{n=await r.json()}catch{return this.settleWholeBatchError(e,M(r.status,r.statusText,a),t)}if(!n.results){const c=n.error===void 0?M(r.status,r.statusText,a):X(n.error,a);return this.settleWholeBatchError(e,c,t)}return{requeue:this.settleReplayBatchSlots(e,n.results,t),stop:!1}}settleWholeBatchError(e,t,s){if(t instanceof A||t.code!==void 0&&L.has(t.code))return this.noteReplayRetryDelay(s,t),{requeue:e,stop:!0};for(const r of e)this.settleReplayTerminal(r,t);return{requeue:[],stop:!1}}async replayBatchedHalves(e,t){const s=Math.ceil(e.length/2),r=await this.replayBatched(e.slice(0,s),t);if(r.stop)return{requeue:[...r.requeue,...e.slice(s)],stop:!0};const i=await this.replayBatched(e.slice(s),t);return{requeue:[...r.requeue,...i.requeue],stop:i.stop}}settleReplayBatchSlots(e,t,s){const r=new Map;for(const n of t)typeof n.id=="number"&&n.body!==void 0&&r.set(n.id,n.body);const i=[];for(const[n,a]of e.entries()){const c=r.get(n);c===void 0?i.push(a):"error"in c?L.has(c.error.code)?(this.noteReplayRetryDelay(s,_(c.error)),i.push(a)):this.settleReplayTerminal(a,_(c.error)):this.settleReplaySuccess(a,T(c.result),c.commitCursor)}return i}}export{re as LunoraClient};
@@ -1 +1 @@
1
- import{LunoraClient as r}from"./LunoraClient-BoqhqR-g.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};
1
+ import{LunoraClient as r}from"./LunoraClient-CXm7h69q.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};
@@ -1699,6 +1699,18 @@ declare class LunoraClient {
1699
1699
  * `setAuthToken` / `identityFingerprint`.
1700
1700
  */
1701
1701
  private authSubject;
1702
+ /**
1703
+ * The bearer token `authSubject` was last asserted against. A subject
1704
+ * is a claim about WHO a specific credential belongs to; once the token
1705
+ * rotates, the sticky label is carried forward on the assumption it is the
1706
+ * same user — but nothing has confirmed that yet, and the alternative (an
1707
+ * account switch) would replay one user's queued writes as another. While
1708
+ * this is out of step with `authToken` the identity counts as unconfirmed
1709
+ * and every replay verdict is `"unknown"` (hold), until the next session
1710
+ * resolve re-asserts the subject. Only used when a subject is established;
1711
+ * a token-hash identity is self-confirming.
1712
+ */
1713
+ private subjectToken;
1702
1714
  /**
1703
1715
  * Identity stamp recorded against each queued offline mutation, keyed by
1704
1716
  * the queue-assigned mutation id. Captured at enqueue from the auth token
@@ -1817,12 +1829,20 @@ declare class LunoraClient {
1817
1829
  * doesn't read as an identity change and discard queued writes. The subject is
1818
1830
  * **sticky**: a later call that omits it (or passes `undefined`) keeps the
1819
1831
  * established subject — so `setAuthToken(refreshedToken)` after a prior
1820
- * `setAuthToken(token, user.id)` retains the identity. Pass `null` to clear it
1821
- * (an explicit sign-out). Establishing the subject for the first time on an
1822
- * UNCHANGED token (e.g. the user id resolves a tick after the token was set)
1823
- * re-stamps any in-flight queued writes rather than dropping them same
1824
- * credential, just a more stable label. A real user switch (the token AND
1825
- * subject both change) still drops the previous user's writes.
1832
+ * `setAuthToken(token, user.id)` retains the identity. Clearing the token
1833
+ * clears it too a credential-less subject would let the NEXT sign-in
1834
+ * inherit the previous user's identity (and their queue and read cache).
1835
+ * Establishing the subject on an UNCHANGED token (e.g. the user id resolves a
1836
+ * tick after the token was set see {@link getCurrentUser}, which does this
1837
+ * for every adapter) re-stamps any in-flight queued writes rather than
1838
+ * dropping them: same credential, just a more stable label. A real user
1839
+ * switch still drops the previous user's writes.
1840
+ *
1841
+ * A sticky subject carried across a token change is not re-confirmed until
1842
+ * the next session resolve says which user the NEW credential belongs to.
1843
+ * Queued writes are HELD (never sent, never dropped) for that window — see
1844
+ * {@link replayIdentityVerdict} — so a refresh can't replay them and an
1845
+ * account switch can't replay the previous user's writes as the new one.
1826
1846
  *
1827
1847
  * Does NOT update the WebSocket auth — the WS token is fixed at upgrade
1828
1848
  * time and lives in the URL. To refresh live WS auth, call
@@ -1855,6 +1875,11 @@ declare class LunoraClient {
1855
1875
  * is `null` for both), which is the safe conflation: holding a write for a
1856
1876
  * signed-out app costs a retry, dropping it costs the write.
1857
1877
  *
1878
+ * A sticky subject carried across a token change is `"unknown"` for the same
1879
+ * reason: the label says user A, the credential in hand has not been checked
1880
+ * against it, and the two answers (a refresh vs an account switch) call for
1881
+ * opposite verdicts. Hold until the next session resolve settles it.
1882
+ *
1858
1883
  * `"mismatch"` is a different identity signed in, and is the one that must be
1859
1884
  * terminal: replaying would attribute one user's write to another and pass
1860
1885
  * THEIR row-level security.
@@ -1909,6 +1934,13 @@ declare class LunoraClient {
1909
1934
  *
1910
1935
  * Framework-agnostic: pair it with {@link onAuthTokenChange} to refetch when
1911
1936
  * the token changes (that's what `@lunora/react`'s `useAuth` does).
1937
+ *
1938
+ * A resolved user also ESTABLISHES the identity subject for the credential
1939
+ * that resolved it ({@link setAuthToken}'s second argument). This is the one
1940
+ * call every adapter's identity store already makes, and the only place that
1941
+ * knows the answer — leaving it to each adapter is what left the sticky-subject
1942
+ * contract unreached in every shipped one, so a routine JWT refresh read as a
1943
+ * user switch and discarded the user's own queued writes and read cache.
1912
1944
  */
1913
1945
  getCurrentUser(): Promise<User | null>;
1914
1946
  /**
@@ -3413,13 +3445,61 @@ declare class LunoraClient {
3413
3445
  */
3414
3446
  private isSameCredentialUnderTokenHash;
3415
3447
  /**
3416
- * Drain every in-memory offline write and reject it because the auth
3417
- * identity changed. Durable entries are also dropped from persistence so a
3418
- * later `hydrate` can't resurrect another user's writes. Stamps are cleared
3419
- * alongside. Persisted entries restored without a live awaiter still get
3420
- * unpersisted here.
3448
+ * Key the offline-queue identity on the resolved user id rather than the
3449
+ * token bytes, so the NEXT token refresh keeps the same identity.
3450
+ *
3451
+ * Only a resolved user labels anything. A 401, a network failure or an
3452
+ * empty session resolves `null` for reasons that say nothing about who is
3453
+ * signed in, and a token that rotated mid-flight belongs to a session this
3454
+ * answer predates — both leave the established label alone rather than
3455
+ * clearing it (which would look like an identity change and drop the queue).
3456
+ */
3457
+ private adoptResolvedSubject;
3458
+ /**
3459
+ * True while an established subject labels a credential it was never checked
3460
+ * against — see the `subjectToken` field. Every replay verdict is
3461
+ * `"unknown"` (hold) until the next session resolve re-asserts the subject.
3462
+ */
3463
+ private subjectAwaitingReconfirm;
3464
+ /**
3465
+ * The identity a queued write is stamped with. The live `queuedIdentities`
3466
+ * map is the source of truth for this session; a hydrated write whose id
3467
+ * isn't in it falls back to the stamp persisted with the record. `Map.get`
3468
+ * returns `undefined` for unstamped/hydrated ids and `item.identity` is
3469
+ * `undefined` for legacy records (persisted before stamps were durable),
3470
+ * while a persisted `null` (queued while signed out) is a real value that
3471
+ * must not collapse into `undefined` — hence `=== undefined`, not `??`.
3472
+ */
3473
+ private stampOf;
3474
+ /**
3475
+ * Reject the in-memory offline writes that can no longer replay under the
3476
+ * identity now signed in, dropping their durable records so a later
3477
+ * `hydrate` can't resurrect another user's writes.
3478
+ *
3479
+ * Per item, not wholesale: this runs on a plain sign-in too (`null` → a
3480
+ * signed-in identity is a credential change like any other), where the
3481
+ * queue is the *signing-in user's own* restored writes. Every stamp goes
3482
+ * through {@link replayIdentityVerdict}, the one comparison, and only
3483
+ * `"mismatch"` is terminal — `"match"` and `"unknown"` stay queued.
3484
+ *
3485
+ * The durable read cache is cleared only when there WAS a previous identity
3486
+ * to protect. Wiping it on a sign-in from signed-out would destroy the
3487
+ * offline-first cache on every cold boot, and buys nothing: cache entries
3488
+ * are identity-stamped and gated at every read.
3421
3489
  */
3422
3490
  private rejectQueuedForIdentityChange;
3491
+ /**
3492
+ * Move the identity stamp of every open shard socket from `from` to `to` —
3493
+ * the sibling of {@link restampQueuedIdentity} for the read cache. A socket
3494
+ * pins the identity it was upgraded under (see `ShardConnection.identity`)
3495
+ * and {@link persistQueryValue} stamps cached reads with it, deliberately,
3496
+ * so a still-open previous-user socket can't file frames under the new
3497
+ * user's stamp. A same-credential relabel is the one case where that pin is
3498
+ * stale rather than protective: without this, every read cached for the rest
3499
+ * of the session is filed under a fingerprint the next session's identity
3500
+ * gate rejects, and the durable read cache silently yields nothing.
3501
+ */
3502
+ private restampConnectionIdentity;
3423
3503
  /**
3424
3504
  * Migrate every identity stamp from `from` to `to` — used when the auth
3425
3505
  * identity label changes but the underlying credential (token) does NOT, e.g.
@@ -3516,22 +3596,23 @@ declare class LunoraClient {
3516
3596
  */
3517
3597
  private encodableOrSettleTerminal;
3518
3598
  /**
3519
- * Identity guard for one queued write about to replay: a write stamped under
3520
- * one identity must never replay under another. The live `queuedIdentities`
3521
- * map is the source of truth for the current session; a hydrated write whose
3522
- * id isn't in the map falls back to the stamp persisted with the record
3523
- * (`item.identity`), so a reload can't replay another user's queued writes.
3524
- * Only legacy records (persisted before stamps were durable
3525
- * `item.identity === undefined`) replay under whatever identity is current.
3526
- *
3527
- * `Map.get` returns `undefined` for unstamped/hydrated ids and `item.identity`
3528
- * is `undefined` for legacy records; a persisted `null` (queued while signed
3529
- * out) is a real value that must not collapse into `undefined` hence the
3530
- * explicit `=== undefined` check rather than `??`. Returns `true` when the
3531
- * write may replay; otherwise settles it `OFFLINE_IDENTITY_CHANGED` and returns
3532
- * `false`. Either way the live stamp is consumed.
3533
- */
3534
- private passesReplayIdentityGate;
3599
+ * Identity gate for one queued write about to replay: a write stamped under
3600
+ * one identity must never replay under another, and must never be DESTROYED
3601
+ * because the identity isn't known yet.
3602
+ *
3603
+ * The three-way verdict is {@link replayIdentityVerdict}'s, not a second
3604
+ * hand-rolled comparison `@lunora/db`'s durable outbox holds on `"unknown"`
3605
+ * through the same call, and this path (the default for the standalone
3606
+ * client) used to drop there instead, purging the queuing user's own write
3607
+ * on every reload that opened its socket before the session resolved.
3608
+ *
3609
+ * `"send"` replays it and consumes the live stamp. `"hold"` leaves it queued
3610
+ * and persisted, stamp intact, for a later flush once an identity is
3611
+ * established (see `setAuthToken`). `"reject"` means a different identity is
3612
+ * signed in: settle it terminally `OFFLINE_IDENTITY_CHANGED` and purge the
3613
+ * durable record.
3614
+ */
3615
+ private replayGateVerdict;
3535
3616
  /** Settle a write that replayed successfully: confirm its optimistic layer against the echoed commit cursor BEFORE resolving, so the gapless drop is in place when the awaiter (and any confirming frame) observes the settle. */
3536
3617
  private settleReplaySuccess;
3537
3618
  /**
@@ -1699,6 +1699,18 @@ declare class LunoraClient {
1699
1699
  * `setAuthToken` / `identityFingerprint`.
1700
1700
  */
1701
1701
  private authSubject;
1702
+ /**
1703
+ * The bearer token `authSubject` was last asserted against. A subject
1704
+ * is a claim about WHO a specific credential belongs to; once the token
1705
+ * rotates, the sticky label is carried forward on the assumption it is the
1706
+ * same user — but nothing has confirmed that yet, and the alternative (an
1707
+ * account switch) would replay one user's queued writes as another. While
1708
+ * this is out of step with `authToken` the identity counts as unconfirmed
1709
+ * and every replay verdict is `"unknown"` (hold), until the next session
1710
+ * resolve re-asserts the subject. Only used when a subject is established;
1711
+ * a token-hash identity is self-confirming.
1712
+ */
1713
+ private subjectToken;
1702
1714
  /**
1703
1715
  * Identity stamp recorded against each queued offline mutation, keyed by
1704
1716
  * the queue-assigned mutation id. Captured at enqueue from the auth token
@@ -1817,12 +1829,20 @@ declare class LunoraClient {
1817
1829
  * doesn't read as an identity change and discard queued writes. The subject is
1818
1830
  * **sticky**: a later call that omits it (or passes `undefined`) keeps the
1819
1831
  * established subject — so `setAuthToken(refreshedToken)` after a prior
1820
- * `setAuthToken(token, user.id)` retains the identity. Pass `null` to clear it
1821
- * (an explicit sign-out). Establishing the subject for the first time on an
1822
- * UNCHANGED token (e.g. the user id resolves a tick after the token was set)
1823
- * re-stamps any in-flight queued writes rather than dropping them same
1824
- * credential, just a more stable label. A real user switch (the token AND
1825
- * subject both change) still drops the previous user's writes.
1832
+ * `setAuthToken(token, user.id)` retains the identity. Clearing the token
1833
+ * clears it too a credential-less subject would let the NEXT sign-in
1834
+ * inherit the previous user's identity (and their queue and read cache).
1835
+ * Establishing the subject on an UNCHANGED token (e.g. the user id resolves a
1836
+ * tick after the token was set see {@link getCurrentUser}, which does this
1837
+ * for every adapter) re-stamps any in-flight queued writes rather than
1838
+ * dropping them: same credential, just a more stable label. A real user
1839
+ * switch still drops the previous user's writes.
1840
+ *
1841
+ * A sticky subject carried across a token change is not re-confirmed until
1842
+ * the next session resolve says which user the NEW credential belongs to.
1843
+ * Queued writes are HELD (never sent, never dropped) for that window — see
1844
+ * {@link replayIdentityVerdict} — so a refresh can't replay them and an
1845
+ * account switch can't replay the previous user's writes as the new one.
1826
1846
  *
1827
1847
  * Does NOT update the WebSocket auth — the WS token is fixed at upgrade
1828
1848
  * time and lives in the URL. To refresh live WS auth, call
@@ -1855,6 +1875,11 @@ declare class LunoraClient {
1855
1875
  * is `null` for both), which is the safe conflation: holding a write for a
1856
1876
  * signed-out app costs a retry, dropping it costs the write.
1857
1877
  *
1878
+ * A sticky subject carried across a token change is `"unknown"` for the same
1879
+ * reason: the label says user A, the credential in hand has not been checked
1880
+ * against it, and the two answers (a refresh vs an account switch) call for
1881
+ * opposite verdicts. Hold until the next session resolve settles it.
1882
+ *
1858
1883
  * `"mismatch"` is a different identity signed in, and is the one that must be
1859
1884
  * terminal: replaying would attribute one user's write to another and pass
1860
1885
  * THEIR row-level security.
@@ -1909,6 +1934,13 @@ declare class LunoraClient {
1909
1934
  *
1910
1935
  * Framework-agnostic: pair it with {@link onAuthTokenChange} to refetch when
1911
1936
  * the token changes (that's what `@lunora/react`'s `useAuth` does).
1937
+ *
1938
+ * A resolved user also ESTABLISHES the identity subject for the credential
1939
+ * that resolved it ({@link setAuthToken}'s second argument). This is the one
1940
+ * call every adapter's identity store already makes, and the only place that
1941
+ * knows the answer — leaving it to each adapter is what left the sticky-subject
1942
+ * contract unreached in every shipped one, so a routine JWT refresh read as a
1943
+ * user switch and discarded the user's own queued writes and read cache.
1912
1944
  */
1913
1945
  getCurrentUser(): Promise<User | null>;
1914
1946
  /**
@@ -3413,13 +3445,61 @@ declare class LunoraClient {
3413
3445
  */
3414
3446
  private isSameCredentialUnderTokenHash;
3415
3447
  /**
3416
- * Drain every in-memory offline write and reject it because the auth
3417
- * identity changed. Durable entries are also dropped from persistence so a
3418
- * later `hydrate` can't resurrect another user's writes. Stamps are cleared
3419
- * alongside. Persisted entries restored without a live awaiter still get
3420
- * unpersisted here.
3448
+ * Key the offline-queue identity on the resolved user id rather than the
3449
+ * token bytes, so the NEXT token refresh keeps the same identity.
3450
+ *
3451
+ * Only a resolved user labels anything. A 401, a network failure or an
3452
+ * empty session resolves `null` for reasons that say nothing about who is
3453
+ * signed in, and a token that rotated mid-flight belongs to a session this
3454
+ * answer predates — both leave the established label alone rather than
3455
+ * clearing it (which would look like an identity change and drop the queue).
3456
+ */
3457
+ private adoptResolvedSubject;
3458
+ /**
3459
+ * True while an established subject labels a credential it was never checked
3460
+ * against — see the `subjectToken` field. Every replay verdict is
3461
+ * `"unknown"` (hold) until the next session resolve re-asserts the subject.
3462
+ */
3463
+ private subjectAwaitingReconfirm;
3464
+ /**
3465
+ * The identity a queued write is stamped with. The live `queuedIdentities`
3466
+ * map is the source of truth for this session; a hydrated write whose id
3467
+ * isn't in it falls back to the stamp persisted with the record. `Map.get`
3468
+ * returns `undefined` for unstamped/hydrated ids and `item.identity` is
3469
+ * `undefined` for legacy records (persisted before stamps were durable),
3470
+ * while a persisted `null` (queued while signed out) is a real value that
3471
+ * must not collapse into `undefined` — hence `=== undefined`, not `??`.
3472
+ */
3473
+ private stampOf;
3474
+ /**
3475
+ * Reject the in-memory offline writes that can no longer replay under the
3476
+ * identity now signed in, dropping their durable records so a later
3477
+ * `hydrate` can't resurrect another user's writes.
3478
+ *
3479
+ * Per item, not wholesale: this runs on a plain sign-in too (`null` → a
3480
+ * signed-in identity is a credential change like any other), where the
3481
+ * queue is the *signing-in user's own* restored writes. Every stamp goes
3482
+ * through {@link replayIdentityVerdict}, the one comparison, and only
3483
+ * `"mismatch"` is terminal — `"match"` and `"unknown"` stay queued.
3484
+ *
3485
+ * The durable read cache is cleared only when there WAS a previous identity
3486
+ * to protect. Wiping it on a sign-in from signed-out would destroy the
3487
+ * offline-first cache on every cold boot, and buys nothing: cache entries
3488
+ * are identity-stamped and gated at every read.
3421
3489
  */
3422
3490
  private rejectQueuedForIdentityChange;
3491
+ /**
3492
+ * Move the identity stamp of every open shard socket from `from` to `to` —
3493
+ * the sibling of {@link restampQueuedIdentity} for the read cache. A socket
3494
+ * pins the identity it was upgraded under (see `ShardConnection.identity`)
3495
+ * and {@link persistQueryValue} stamps cached reads with it, deliberately,
3496
+ * so a still-open previous-user socket can't file frames under the new
3497
+ * user's stamp. A same-credential relabel is the one case where that pin is
3498
+ * stale rather than protective: without this, every read cached for the rest
3499
+ * of the session is filed under a fingerprint the next session's identity
3500
+ * gate rejects, and the durable read cache silently yields nothing.
3501
+ */
3502
+ private restampConnectionIdentity;
3423
3503
  /**
3424
3504
  * Migrate every identity stamp from `from` to `to` — used when the auth
3425
3505
  * identity label changes but the underlying credential (token) does NOT, e.g.
@@ -3516,22 +3596,23 @@ declare class LunoraClient {
3516
3596
  */
3517
3597
  private encodableOrSettleTerminal;
3518
3598
  /**
3519
- * Identity guard for one queued write about to replay: a write stamped under
3520
- * one identity must never replay under another. The live `queuedIdentities`
3521
- * map is the source of truth for the current session; a hydrated write whose
3522
- * id isn't in the map falls back to the stamp persisted with the record
3523
- * (`item.identity`), so a reload can't replay another user's queued writes.
3524
- * Only legacy records (persisted before stamps were durable
3525
- * `item.identity === undefined`) replay under whatever identity is current.
3526
- *
3527
- * `Map.get` returns `undefined` for unstamped/hydrated ids and `item.identity`
3528
- * is `undefined` for legacy records; a persisted `null` (queued while signed
3529
- * out) is a real value that must not collapse into `undefined` hence the
3530
- * explicit `=== undefined` check rather than `??`. Returns `true` when the
3531
- * write may replay; otherwise settles it `OFFLINE_IDENTITY_CHANGED` and returns
3532
- * `false`. Either way the live stamp is consumed.
3533
- */
3534
- private passesReplayIdentityGate;
3599
+ * Identity gate for one queued write about to replay: a write stamped under
3600
+ * one identity must never replay under another, and must never be DESTROYED
3601
+ * because the identity isn't known yet.
3602
+ *
3603
+ * The three-way verdict is {@link replayIdentityVerdict}'s, not a second
3604
+ * hand-rolled comparison `@lunora/db`'s durable outbox holds on `"unknown"`
3605
+ * through the same call, and this path (the default for the standalone
3606
+ * client) used to drop there instead, purging the queuing user's own write
3607
+ * on every reload that opened its socket before the session resolved.
3608
+ *
3609
+ * `"send"` replays it and consumes the live stamp. `"hold"` leaves it queued
3610
+ * and persisted, stamp intact, for a later flush once an identity is
3611
+ * established (see `setAuthToken`). `"reject"` means a different identity is
3612
+ * signed in: settle it terminally `OFFLINE_IDENTITY_CHANGED` and purge the
3613
+ * durable record.
3614
+ */
3615
+ private replayGateVerdict;
3535
3616
  /** Settle a write that replayed successfully: confirm its optimistic layer against the echoed commit cursor BEFORE resolving, so the gapless drop is in place when the awaiter (and any confirming frame) observes the settle. */
3536
3617
  private settleReplaySuccess;
3537
3618
  /**
@@ -1,4 +1,4 @@
1
- import { L as LunoraClient, P as Preloaded } from "./lunora-client.d-CyDr665D.js";
1
+ import { L as LunoraClient, P as Preloaded } from "./lunora-client.d-ljp6sQC5.js";
2
2
  import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./function-reference.d-Br_hsKje.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, P as Preloaded } from "./lunora-client.d-Cb_0IT8r.mjs";
1
+ import { L as LunoraClient, P as Preloaded } from "./lunora-client.d-DIphNr-G.mjs";
2
2
  import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "./function-reference.d-Br_hsKje.mjs";
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 { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-Cb_0IT8r.mjs";
1
+ import { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DIphNr-G.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
- b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-Cb_0IT8r.mjs";
13
+ b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DIphNr-G.mjs";
14
14
  import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.mjs";
15
15
  import '@lunora/errors';
16
16
  import '@lunora/runtime';
@@ -1,4 +1,4 @@
1
- import { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-CyDr665D.js";
1
+ import { S as SubscriptionError, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-ljp6sQC5.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
- b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-CyDr665D.js";
13
+ b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-ljp6sQC5.js";
14
14
  import { F as FunctionReference, A as ArgsOf, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.js";
15
15
  import '@lunora/errors';
16
16
  import '@lunora/runtime';
@@ -1,4 +1,4 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-Cb_0IT8r.mjs";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DIphNr-G.mjs";
2
2
  export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.mjs";
3
3
  export {
4
4
  /**
@@ -20,7 +20,7 @@ p as preloadQuery,
20
20
  * WebSocket or touches a UI framework, so it is safe to import from any SSR
21
21
  * loader.
22
22
  */
23
- a as preloadedQueryResult } from "../packem_shared/preload.d-BrV8gNAa.mjs";
23
+ a as preloadedQueryResult } from "../packem_shared/preload.d-DxVLGSy_.mjs";
24
24
  import '@lunora/errors';
25
25
  import '@lunora/runtime';
26
26
  /**
@@ -1,4 +1,4 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-CyDr665D.js";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-ljp6sQC5.js";
2
2
  export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/function-reference.d-Br_hsKje.js";
3
3
  export {
4
4
  /**
@@ -20,7 +20,7 @@ p as preloadQuery,
20
20
  * WebSocket or touches a UI framework, so it is safe to import from any SSR
21
21
  * loader.
22
22
  */
23
- a as preloadedQueryResult } from "../packem_shared/preload.d-8LuiLYlj.js";
23
+ a as preloadedQueryResult } from "../packem_shared/preload.d-6JPSWNGq.js";
24
24
  import '@lunora/errors';
25
25
  import '@lunora/runtime';
26
26
  /**
@@ -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-CepVN0C6.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};
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-B2AUk9YY.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,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/client",
3
- "version": "1.0.0-alpha.74",
3
+ "version": "1.0.0-alpha.75",
4
4
  "description": "Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -70,7 +70,7 @@
70
70
  "access": "public"
71
71
  },
72
72
  "dependencies": {
73
- "@lunora/errors": "1.0.0-alpha.30",
73
+ "@lunora/errors": "1.0.0-alpha.31",
74
74
  "@visulima/storage-client": "1.0.2"
75
75
  },
76
76
  "peerDependencies": {
@@ -1 +0,0 @@
1
- import{LunoraError as m}from"@lunora/errors";import{i as ie,a as ne,P as ae}from"./delta-merge-Ds6tHkFX.mjs";import{e as W,d as T}from"./wire-codec-BOMWQpoF.mjs";import{s as q}from"./wire-key-CmT1XyQI.mjs";import oe from"./createInMemoryBookmarkStorage-BooZhW0n.mjs";import{ClientQueryStore as ce}from"./createClientQuery-B8Nfj-7o.mjs";import{TabCoordinator as he}from"./TabCoordinator-CXD7vulJ.mjs";import{TransportError as A,getRetryAfterMs as X}from"./CONFLICT_ERROR_CODE-BOeeP_Wl.mjs";import{httpStream as de}from"./httpStream-x6q-x4yK.mjs";import{d as U,n as O,f as R,a as ue,c as le}from"./local-store-irMi9H2G.mjs";import{O as fe,n as $,i as me,r as pe}from"./offline-queue-xntsWiKt.mjs";import{resolvePersistenceAdapter as ye}from"./createInMemoryPersistence-Cz2W6XVj.mjs";import{resolveQueryCacheAdapter as Se,queryCacheKey as P}from"./createInMemoryQueryCache-D2uNHLfM.mjs";import{createReconnect as Q}from"./createReconnect-CjTmjJDH.mjs";import be from"./createSnapshotPrecondition-B7kQcZUF.mjs";import{createStream as Te}from"./DEFAULT_MAX_BUFFER-D3QH2iaq.mjs";import{SubscriptionRegistry as k}from"./SubscriptionRegistry-BQTQZYoI.mjs";const x=500,ve=async o=>{const e=[];let t;for(;;){const s=await o(t);if(e.push(...Array.isArray(s.records)?s.records:[]),s.truncated!==!0||typeof s.cursor!="string"||s.cursor.length===0)return e;if(s.cursor===t)throw new Error("collectPages: the list did not advance its cursor — refusing to page forever");t=s.cursor}},ge=(o,e)=>{if(o.size<e)return;const t=o.keys().next().value;t!==void 0&&o.delete(t)};class w{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 L=new Set(["RATE_LIMITED","SHARD_ERROR","SHARD_UNAVAILABLE","TOO_MANY_REQUESTS"]),ke=o=>{if(o instanceof A)return!0;const e=o?.code;return e===void 0||L.has(e)},Z=6e4,Ce=1e3,ee=o=>{if(o===null)return;const e=Number(o);if(Number.isFinite(e))return e>0?e*1e3:void 0;const t=Date.parse(o);if(Number.isNaN(t))return;const s=t-Date.now();return s>0?s:void 0},we={401:"UNAUTHORIZED",403:"FORBIDDEN",404:"NOT_FOUND",413:"PAYLOAD_TOO_LARGE",429:"TOO_MANY_REQUESTS"},M=(o,e,t)=>{const s=ee(t),r=s===void 0?void 0:{retryAfterMs:s},i=`LunoraClient: response carried no error envelope (status ${o.toString()}${e?` ${e}`:""})`;return o<400||o>=500||o===408?new A(i,r):new m(we[o]??"BAD_REQUEST",i,{data:r})},Ee=(o,e)=>{const t=ee(e);if(!(t===void 0||X(o)!==void 0))return o.data===void 0?{retryAfterMs:t}:typeof o.data=="object"&&o.data!==null&&!Array.isArray(o.data)?{...o.data,retryAfterMs:t}:void 0},_e=(o,e=Math.random)=>{const t=Math.min(Ce*2**Math.max(o-1,0),Z);return Math.round(t*(.5+e()*.5))},Ae=o=>o instanceof A||L.has(o?.code??""),Ie=(o,e,t)=>{const s=X(o);return s!==void 0&&s>0?Math.min(s,Z):Ae(o)?_e(e,t):void 0},Oe=983040,Re=o=>typeof TextEncoder>"u"?o.length:new TextEncoder().encode(o).length,Pe="/_lunora/rpc",G="/_lunora/rpc-batch",Me="/_lunora/ws",N=o=>o===void 0||o===""?"":`&bucket=${encodeURIComponent(o)}`,H=o=>{for(let e=o.length-1;e>=0;e-=1)o[e]?.()},z=Symbol("lunora.unmergeableDelta"),He=(o,e)=>{for(const t of e)t.op==="delete"?o.delete(t.key):t.value!==void 0&&o.set(t.key,t.value)},Le="lunora-ping",Fe=3e4,Ue=1e4,xe=250,Ne=5e3,De=64,Be="/_lunora/admin/shard-traffic",Ke="/_lunora/admin/scheduled",We="/_lunora/admin/scheduled/status",qe="/_lunora/admin/scheduled/ws",$e="/_lunora/admin/scheduled/cancel",V="/_lunora/admin/scheduled/dead",Qe="/_lunora/admin/scheduled/dead/retry",Ge="/_lunora/admin/scheduled/dead/cancel",ze="/_lunora/admin/workflows/instances",Ve="/_lunora/admin/workflows/instance",je="/_lunora/admin/workflows/status",D="/_lunora/admin/storage",Je="/_lunora/admin/storage/url",Ye="/_lunora/admin/storage/buckets",Xe="/_lunora/admin/functions",Ze="/_lunora/admin/cron-jobs",et="/_lunora/admin/cron-jobs/run",tt="/_lunora/admin/openapi",st="/_lunora/admin/openrpc",rt="/_lunora/admin/global/tables",it="/_lunora/admin/global/table",nt="/_lunora/admin/global/facet",at="/_lunora/admin/vector/indexes",ot="/_lunora/admin/vector/query",ct="/_lunora/admin/logs/archive",ht="/_lunora/admin/kv/namespaces",dt="/_lunora/admin/kv/keys",B="/_lunora/admin/kv/value",ut="/_lunora/admin/auth/users",lt="/_lunora/admin/auth/sessions",ft="/_lunora/admin/auth/users/create",mt="/_lunora/admin/auth/users/role",pt="/_lunora/admin/auth/users/ban",yt="/_lunora/admin/auth/users/unban",St="/_lunora/admin/auth/users/password",bt="/_lunora/admin/auth/users/remove",Tt="/_lunora/admin/auth/users/impersonate",vt="/_lunora/admin/auth/sessions/revoke",gt="/_lunora/admin/auth/sessions/revoke-all",kt="/_lunora/admin/auth/capabilities",Ct="/_lunora/admin/auth/users/update",wt="/_lunora/admin/auth/accounts",Et="/_lunora/admin/auth/accounts/unlink",_t="/_lunora/admin/auth/passkeys",At="/_lunora/admin/auth/passkeys/delete",It="/_lunora/admin/auth/two-factor/disable",Ot="/_lunora/admin/auth/organizations",Rt="/_lunora/admin/auth/organizations/members",Pt="/_lunora/admin/auth/organizations/invitations",Mt="/_lunora/admin/auth/organizations/members/remove",Ht="/_lunora/admin/auth/organizations/invitations/cancel",Lt="/_lunora/admin/auth/config",Ft="/_lunora/admin/auth/organizations/create",Ut="/_lunora/admin/auth/organizations/update",xt="/_lunora/admin/auth/organizations/remove",Nt="/_lunora/admin/auth/organizations/members/add",Dt="/_lunora/admin/auth/organizations/members/invite",Bt="/_lunora/admin/auth/organizations/members/role",Kt="/_lunora/admin/auth/organizations/teams",Wt="/_lunora/admin/auth/organizations/teams/create",qt="/_lunora/admin/auth/organizations/teams/update",$t="/_lunora/admin/auth/organizations/teams/remove",Qt="/_lunora/admin/auth/organizations/teams/members",Gt="/_lunora/admin/auth/organizations/teams/members/add",zt="/_lunora/admin/auth/organizations/teams/members/remove",Vt="/_lunora/admin/auth/organizations/roles",jt="/_lunora/admin/auth/organizations/roles/create",Jt="/_lunora/admin/auth/organizations/roles/update",Yt="/_lunora/admin/auth/organizations/roles/remove",Xt="/api/auth",Zt="/get-session",j=o=>o.startsWith("https://")?`wss://${o.slice(8)}`:o.startsWith("http://")?`ws://${o.slice(7)}`:o,C=(o,e)=>`${o.endsWith("/")?o.slice(0,-1):o}${e}`,y=(o,e)=>{const t=new URLSearchParams;for(const[r,i]of Object.entries(e))i!==void 0&&i!==""&&t.set(r,String(i));const s=t.toString();return s===""?o:`${o}?${s}`},es=[ae],l=o=>o??"",te=(o,e)=>{const t=o.error,s=typeof t?.code=="string"?t.code:void 0,r=typeof t?.message=="string"?t.message:void 0;return{code:s,messageText:(typeof o.message=="string"?o.message:void 0)??r??e}},ts=o=>{const{code:e,messageText:t}=te(o,"stream error");return e===void 0?new Error(t):new m(e,t)},J=o=>{const{code:e,messageText:t}=te(o,"subscription error");return{message:t,...e===void 0?{}:{code:e}}};function K(o){if(o!==void 0)return e=>{o(e)}}const E=(o,e)=>{for(const t of o)try{t(e)}catch{}},ss=new TextDecoder,rs=o=>{if(typeof o=="string")return o;if(o instanceof ArrayBuffer)return ss.decode(o)},b=(o,e)=>{if(!o.socket||o.wsState!=="open")return!1;try{return o.socket.send(JSON.stringify(e)),!0}catch{return!1}},_=o=>{const e=new Error(o.message??"request failed");return e.code=o.code,o.data!==void 0&&(e.data=T(o.data)),o.hint!==void 0&&(e.hint=o.hint),o.docsUrl!==void 0&&(e.docsUrl=o.docsUrl),e},Y=(o,e)=>{const t=_(o),s=Ee(t,e);return s!==void 0&&(t.data=s),t},v=(o,e)=>{try{return W(o)}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)}},is=(o,e)=>{const t=Array.from({length:e});for(const s of o){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:T(r?.result)}}return t.map(s=>s??{error:new Error("batch call returned no result"),ok:!1})},ns=Promise.resolve();class se{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 k;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 w;statusListeners=new w;tokenExpiredListeners=new w;mutationSettledListeners=new w;pendingChangeListeners=new w;whisperHandlers=new Map;lastStatus="idle";nextSubId=0;nextStreamId=0;streams=new Map;adminSocketTeardowns=new Set;offlineFlushes=new Map;replayRetryState=new Map;replayRetryTimers=new Map;shapeSubscriptions=new Map;pokeBuffers=new Map;nextShapeId=0;constructor(e){this.url=e.url,this.wsUrl=e.wsUrl??C(j(e.url),Me),this.wsToken=e.wsToken;const t=e.authBasePath??Xt;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??oe(),this.reconnectOptions=e.reconnect,this.heartbeatIntervalMs=e.heartbeatIntervalMs??Fe,this.connectTimeoutMs=e.connectTimeoutMs??Ue,this.defaultConnectionContext=e.connectionContext,this.persistence=ye(e.persistence,e.outbox===void 0),this.persistenceVersion=e.persistenceVersion,this.queryCache=Se(e.queryCache),this.onPersistenceError=e.offlineQueue?.onPersistenceError,this.clientQueryStore=new ce,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=ns),this.offlineQueue=new fe(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-${$()}`,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 i=this.identityFingerprint();if(i!==r&&(s?this.rejectQueuedForIdentityChange():(this.restampQueuedIdentity(r,i),this.restampWatermarks(r,i)),this.tabCoordinator)){const n=this.tabCoordinator.isLeader();this.tabCoordinator.stop(),this.tabCoordinator=this.createTabCoordinator(),this.tabCoordinator.start(),n&&this.tabCoordinator.promoteImmediately()}s&&this.authTokenListeners.emit(e)}getAuthToken(){return this.authToken}currentIdentity(){return this.identityFingerprint()}replayIdentityVerdict(e){const t=this.identityFingerprint();return e===t||e!==void 0&&this.isSameCredentialUnderTokenHash(e)?"match":t===null?"unknown":"mismatch"}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 m("INTERNAL",`callMutator: clientSeq must be a positive integer, got ${String(r)}`);const i=s?.shardKey??"",n=this.identityFingerprint();let a;const c=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(n??"")?.get(i)??0)){let d=this.clientWatermarks.get(n??"");d===void 0&&(d=new Map,this.clientWatermarks.set(n??"",d)),d.set(i,a)}return{applied:a===void 0||a===r,result:c}}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(C(this.url,`${this.authBasePath}${Zt}`),{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={}){this.assertLeaderOwnedSurface("setConnectionContext");const s=l(t.shardKey);e===void 0?this.connectionContexts.delete(s):this.connectionContexts.set(s,e),this.refreshConnectionContext(s)}acquireConnectionContext(e,t={}){if(this.followsAnotherTab())return()=>{};const s=l(t.shardKey),r={context:e},i=this.connectionContextHolders.get(s);i?i.push(r):this.connectionContextHolders.set(s,[r]),this.refreshConnectionContext(s);let n=!1;return()=>{if(n)return;n=!0;const a=this.connectionContextHolders.get(s);if(!a)return;const c=a.indexOf(r);c!==-1&&a.splice(c,1),a.length===0&&this.connectionContextHolders.delete(s),this.refreshConnectionContext(s)}}whisperSubscribe(e,t,s={}){this.assertLeaderOwnedSurface("whisperSubscribe");const r=l(s.shardKey);let i=this.whisperHandlers.get(r);i||(i=new Map,this.whisperHandlers.set(r,i));let n=i.get(e);const a=n===void 0;if(n||(n=new Set,i.set(e,n)),n.add(t),this.ensureSocket(s.shardKey),a){const c=this.getConnection(s.shardKey);c&&b(c,{topic:e,type:"whisper_subscribe"})}return()=>{const c=this.whisperHandlers.get(r),h=c?.get(e);if(!h?.delete(t)||h.size>0)return;c?.delete(e),c?.size===0&&this.whisperHandlers.delete(r);const d=this.getConnection(s.shardKey);d&&b(d,{topic:e,type:"whisper_unsubscribe"})}}whisper(e,t,s={}){this.assertLeaderOwnedSurface("whisper"),this.ensureSocket(s.shardKey);const r=this.getConnection(s.shardKey);r&&b(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 i of s){const n=this.connections.get(i);e.push({confirmedMutationWatermark:t?.get(i)??0,hasSocket:n?.socket!==void 0,shardKey:i===""?void 0:i,wasEverConnected:n?.wasEverConnected??!1,wsState:n?.wsState??"idle"})}const r=this.subscriptions.all().map(i=>({acked:i.acked,functionPath:i.fn.__lunoraRef,id:i.id,kind:"query",lastMutationId:i.lastMutationId,pendingOptimisticLayers:i.optimisticLayers.length,serverCursor:i.serverCursor,shardKey:i.shardKey,subscriberCount:i.callbacks.size}));for(const i of this.shapeSubscriptions.values())r.push({acked:i.serverCursor!==void 0,functionPath:`shape:${i.name}`,id:i.id,kind:"shape",lastMutationId:i.lastMutationId,pendingOptimisticLayers:0,rowCount:i.rows.size,serverCursor:i.serverCursor,shardKey:i.shardKey,subscriberCount:i.callbacks.size});return{clientId:this.clientId,closed:this.closed,connectionStatus:this.computeStatus(),pendingWrites:this.offlineQueue.size,shards:e.toSorted((i,n)=>(i.shardKey??"").localeCompare(n.shardKey??"")),subscriptions:r.toSorted((i,n)=>i.functionPath.localeCompare(n.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 be(this,e,t,s)}whenReady(){return this.readyPromise}get isReady(){return this.readyResolved}peekHydratedQuery(e,t,s){if(!this.readyResolved)return;const r=q(t),i=P(e,r,s),n=this.hydratedQueryCache.get(i);if(n!==void 0)return n.identity===this.identityFingerprint()?n.value:void 0}peekActiveQuerySnapshot(e,t,s){const r=k.key(e,t,s),i=this.subscriptions.get(r);return{present:i!==void 0,value:i?.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 m("INTERNAL","LunoraClient: no `fetch` implementation available");if(e.length===0)return[];const t=await this.fetchImpl(C(this.url,G),{body:JSON.stringify({calls:e.map((i,n)=>({args:v(i.args??{},`args for batch call '${i.fn.__lunoraRef}'`),functionPath:i.fn.__lunoraRef,id:n,shardKey:i.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 m("INTERNAL",`LunoraClient: batch response was not JSON (status ${t.status.toString()})`)}if(!t.ok||r.error&&!r.results)throw r.error?_(r.error):new m("INTERNAL",`LunoraClient: batch request failed (status ${t.status.toString()})`);for(const i of r.results??[]){const n=i.body?.commitCursor;typeof i.id=="number"&&typeof n=="number"&&this.recordShardCursor(e[i.id]?.shardKey,n)}return is(r.results??[],e.length)}async mutation(e,t,s={}){this.assertOpen();const r=t,i=s.mutationId??$(),{confirms:n,rollbacks:a}=this.applyOptimisticUpdates(e.__lunoraRef,r,s.shardKey,s.optimistic);s.optimisticUpdate&&this.applyOptimisticUpdate(s.optimisticUpdate,t,s.shardKey,a,n);const c=this.offlineFlushes.get(l(s.shardKey));c!==void 0&&await c;const{hasSocket:h,wasEverConnected:d,wsState:u}=this.connectionGateState(s.shardKey),{queueBeforeFirstConnect:f}=this.offlineQueue,S=d||f,p=this.WebSocketImpl!==void 0&&S;if(u!=="open"&&!h&&p||u==="connecting"&&S)return this.enqueueOfflineMutation(e,r,s.shardKey,i,a,n,s.precondition);try{let I;const re=await this.rpc(e.__lunoraRef,r,s.shardKey,{captureBookmark:!0,mutationId:i,onCommitCursor:F=>{I=F}});for(const F of n)F(I);return re}catch(I){throw H(a),I}}async action(e,t,s={}){return this.assertOpen(),await this.rpc(e.__lunoraRef,t,s.shardKey,{attachBookmark:!0,captureBookmark:!0})}async importRows(e,t,s={}){this.assertOpen();const r=Math.max(1,Math.trunc(s.chunkSize??500)),i=s.toArgs??(h=>({rows:h})),n=t.length;let a=0,c=0;for(let h=0;h<n;h+=r){const d=t.slice(h,h+r),u=c;await this.mutation(e,i(d),{...s.importId===void 0?{}:{mutationId:`${s.importId}:${String(u)}`},shardKey:s.shardKey}),c+=1,a+=d.length,s.onProgress?.({done:a,total:n})}return{chunks:c,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(Ke,"GET")).records??[]}async schedulerStatus(){this.assertOpen();const e=await this.adminFetch(We,"GET");return{backlog:e.backlog??0,inFlight:e.inFlight??0,pools:e.pools??[]}}async cancelScheduledJob(e){return this.assertOpen(),{cancelled:(await this.adminFetch($e,"POST",{id:e})).cancelled===!0}}async listDeadJobs(){return this.assertOpen(),await ve(async e=>await this.adminFetch(e===void 0?V:`${V}?cursor=${encodeURIComponent(e)}`,"GET"))}async retryDeadJob(e){return this.assertOpen(),{retried:(await this.adminFetch(Qe,"POST",{id:e})).retried===!0}}async removeDeadJob(e){return this.assertOpen(),{removed:(await this.adminFetch(Ge,"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(`${ze}?${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(`${Ve}?${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(je,"POST",{action:e.action,id:e.id,name:e.name})).status??"unknown"}}subscribeScheduledJobs(e){if(this.assertOpen(),this.WebSocketImpl===void 0)return()=>{};const t=C(j(this.url),qe),s=Q(this.reconnectOptions),r={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,socket:void 0};let i,n=!1;const a=()=>{n||this.closed||(i=setTimeout(d,s.next()))},c=f=>{if(n||this.WebSocketImpl===void 0)return;const S=f===void 0?t:`${t}?token=${encodeURIComponent(f)}`;this.openManagedSocket(r,S,this.connectTimeoutMs,{onClose:()=>{a()},onMessage:p=>{try{const g=JSON.parse(typeof p.data=="string"?p.data:"");g.type==="jobs"&&Array.isArray(g.records)&&(s.reset(),e(g.records))}catch{}}})},h=async f=>{let S;try{S=await f()}catch{a();return}c(S)},d=()=>{if(n||this.WebSocketImpl===void 0)return;const{wsToken:f}=this;if(typeof f=="function"){h(f).catch(()=>{});return}c(f)};d();const u=()=>{n=!0,i!==void 0&&(clearTimeout(i),i=void 0),r.connectTimer!==void 0&&(clearTimeout(r.connectTimer),r.connectTimer=void 0),this.stopHeartbeat(r),r.socket?.close(),r.socket=void 0};return this.adminSocketTeardowns.add(u),()=>{this.adminSocketTeardowns.delete(u),u()}}async listFunctions(){return this.assertOpen(),(await this.adminFetch(Xe,"GET")).functions??[]}async getCronJobs(){return this.assertOpen(),(await this.adminFetch(Ze,"GET")).jobs??[]}async runCronJob(e){this.assertOpen();const t=await this.adminFetch(et,"POST",{name:e});return{name:t.name??e,ran:t.ran===!0}}async fetchOpenApi(){return this.assertOpen(),await this.adminFetch(tt,"GET")}async fetchOpenRpc(){return this.assertOpen(),await this.adminFetch(st,"GET")}async listStorageObjects(e={}){this.assertOpen();const t=y(D,{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=`${D}?key=${encodeURIComponent(e)}${N(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(Ye,"GET")).buckets??[]}async uploadStorageObject(e){this.assertOpen();const t=`${D}?key=${encodeURIComponent(e.key)}${N(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())}`,i=`${Je}?key=${encodeURIComponent(e)}${r}${N(t?.bucket)}`,n=await this.adminFetch(i,"GET");if(typeof n.url!="string")throw new TypeError("LunoraClient: storage URL endpoint returned no `url`");return n.url}async listGlobalTables(){return this.assertOpen(),await this.adminFetch(rt,"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(W(e.filters))),T(await this.adminFetch(`${it}?${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(W(e.filters))),T(await this.adminFetch(`${nt}?${t.toString()}`,"GET"))}async listVectorIndexes(){return this.assertOpen(),(await this.adminFetch(at,"GET")).indexes??[]}async queryVectorIndex(e){return this.assertOpen(),(await this.adminFetch(ot,"POST",e)).matches??[]}async queryLogArchive(e={}){this.assertOpen();const t=await this.adminFetch(ct,"POST",e);return{nextCursor:t.nextCursor,rows:t.rows??[]}}async listKvNamespaces(){return this.assertOpen(),(await this.adminFetch(ht,"GET")).namespaces??[]}async listKvKeys(e){this.assertOpen();const t=y(dt,{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(B,{key:e.key,namespace:e.namespace});return await this.adminFetch(t,"GET")}async putKvValue(e){this.assertOpen(),await this.adminFetch(B,"PUT",e)}async deleteKvKey(e){this.assertOpen();const t=y(B,{key:e.key,namespace:e.namespace});await this.adminFetch(t,"DELETE")}async listAuthUsers(e={}){this.assertOpen();const t=y(ut,{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(ft,"POST",e)}async setAuthUserRole(e){return await this.adminFetch(mt,"POST",e)}async banAuthUser(e){return await this.adminFetch(pt,"POST",e)}async unbanAuthUser(e){return await this.adminFetch(yt,"POST",e)}async setAuthUserPassword(e){await this.adminFetch(St,"POST",e)}async removeAuthUser(e){await this.adminFetch(bt,"POST",e)}async impersonateAuthUser(e){return await this.adminFetch(Tt,"POST",e)}async revokeAuthSession(e){await this.adminFetch(vt,"POST",e)}async revokeAuthUserSessions(e){await this.adminFetch(gt,"POST",e)}async getAuthCapabilities(){return await this.adminFetch(kt,"GET")}async updateAuthUser(e){return await this.adminFetch(Ct,"POST",e)}async listAuthAccounts(e){return await this.adminFetch(y(wt,{userId:e.userId}),"GET")}async unlinkAuthAccount(e){await this.adminFetch(Et,"POST",e)}async listAuthPasskeys(e){return await this.adminFetch(y(_t,{userId:e.userId}),"GET")}async deleteAuthPasskey(e){await this.adminFetch(At,"POST",e)}async disableAuthTwoFactor(e){await this.adminFetch(It,"POST",e)}async listAuthOrganizations(e={}){return await this.adminFetch(y(Ot,{limit:e.limit,offset:e.offset}),"GET")}async listAuthOrgMembers(e){const t=y(Rt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async listAuthOrgInvitations(e){const t=y(Pt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async removeAuthOrgMember(e){await this.adminFetch(Mt,"POST",e)}async cancelAuthOrgInvitation(e){await this.adminFetch(Ht,"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(Ut,"POST",e)}async deleteAuthOrganization(e){await this.adminFetch(xt,"POST",e)}async addAuthOrgMember(e){return await this.adminFetch(Nt,"POST",e)}async inviteAuthOrgMember(e){return await this.adminFetch(Dt,"POST",e)}async setAuthOrgMemberRole(e){return await this.adminFetch(Bt,"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(Wt,"POST",e)}async updateAuthOrgTeam(e){return await this.adminFetch(qt,"POST",e)}async removeAuthOrgTeam(e){await this.adminFetch($t,"POST",e)}async listAuthOrgTeamMembers(e){const t=y(Qt,{limit:e.limit,offset:e.offset,teamId:e.teamId});return await this.adminFetch(t,"GET")}async addAuthOrgTeamMember(e){return await this.adminFetch(Gt,"POST",e)}async removeAuthOrgTeamMember(e){await this.adminFetch(zt,"POST",e)}async listAuthOrgRoles(e){const t=y(Vt,{limit:e.limit,offset:e.offset,organizationId:e.organizationId});return await this.adminFetch(t,"GET")}async createAuthOrgRole(e){return await this.adminFetch(jt,"POST",e)}async updateAuthOrgRole(e){return await this.adminFetch(Jt,"POST",e)}async deleteAuthOrgRole(e){await this.adminFetch(Yt,"POST",e)}async listAuthSessions(e={}){this.assertOpen();const t=y(lt,{limit:e.limit,offset:e.offset,userId:e.userId});return await this.adminFetch(t,"GET")}subscribe(e,t,s,r={}){this.assertOpen();const i=t??{},n=k.key(e.__lunoraRef,i,r.shardKey);let a=this.subscriptions.get(n);const c=K(s),h=K(r.onError),d=K(r.onCheckpoint);if(!a){this.nextSubId+=1;const f=`sub_${this.nextSubId.toString()}`,S=q(i),p=this.takeHydratedCache(e.__lunoraRef,S,r.shardKey);a={acked:!1,args:i,argsKey:S,callbacks:new Set,checkpointCallbacks:new Set,errorCallbacks:new Set,fn:e,id:f,lastValue:p?.value,optimisticLayers:[],serverBase:p?.value,serverCursor:p?.serverCursor,shardKey:r.shardKey,wireArgs:v(i,`args for '${e.__lunoraRef}'`),...p?.serverEpoch===void 0?{}:{serverEpoch:p.serverEpoch}},this.subscriptions.add(a)}if(a.callbacks.add(c),h&&a.errorCallbacks.add(h),d&&a.checkpointCallbacks.add(d),a.lastValue!==void 0)try{c(a.lastValue)}catch{}this.ensureSocket(r.shardKey),this.sendSubscribeIfOpen(a);const u=a;return()=>{u.callbacks.delete(c),h&&u.errorCallbacks.delete(h),d&&u.checkpointCallbacks.delete(d),u.callbacks.size===0&&(this.sendOrQueueUnsubscribe(u.shardKey,u.id,"unsubscribe"),this.subscriptions.remove(u))}}subscribeShape(e,t,s={}){if(this.assertOpen(),this.followsAnotherTab())return()=>{};this.nextShapeId+=1;const r=`shape_${this.nextShapeId.toString()}`,i={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,i),this.ensureSocket(s.shardKey),this.sendShapeSubscribeIfOpen(i),()=>{this.shapeSubscriptions.delete(r),this.sendOrQueueUnsubscribe(i.shardKey,r,"shape_unsubscribe")}}stream(e,t,s={}){if(this.assertOpen(),this.WebSocketImpl===void 0)throw new m("INTERNAL","LunoraClient: streams require a WebSocket implementation");this.nextStreamId+=1;const r=`stream_${this.nextStreamId.toString()}`,{shardKey:i}=s,n=t??{},{handle:a,iterable:c}=Te({maxBuffer:s.maxBuffer,onCancel:()=>{this.cancelStream(r,i)}});this.ensureSocket(i);const h=this.getConnection(i),d={id:r,query:{args:v(n,`stream args for '${e.__lunoraRef}'`),functionPath:e.__lunoraRef,shardKey:i},type:"stream"},u={durable:s.durable===!0,generation:void 0,handle:a,lastSeq:0,message:d,shardKey:i,started:!1};this.streams.set(r,u);const f=h?.wsState==="open"&&b(h,d);if(u.started=f,!f&&h===void 0)return this.streams.delete(r),a.fail(new m("STREAM_DISCONNECTED","stream unavailable: this tab is not the cross-tab WebSocket leader, so it holds no socket to stream over")),c;if(!f){for(h.pendingStreams=h.pendingStreams??[];h.pendingStreams.length>=De;){const p=h.pendingStreams.shift()?.id,g=p?this.streams.get(p):void 0;g&&(g.handle.fail(new m("STREAM_QUEUE_OVERFLOW","stream-start frame evicted while socket was unreachable")),this.streams.delete(p))}h.pendingStreams.push(d)}return c}httpStream(e,t,s={}){if(this.closed)throw new m("CLIENT_CLOSED","LunoraClient is closed");if(!this.fetchImpl)throw new m("INTERNAL","LunoraClient: no `fetch` implementation available");const r={...this.authToken?{authorization:`Bearer ${this.authToken}`}:{},...s.headers};return de(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 m("CLIENT_CLOSED","LunoraClient closed"));this.streams.clear();for(const e of this.connections.values())this.teardownConnection(e);for(const e of this.adminSocketTeardowns)e();this.adminSocketTeardowns.clear();for(const e of this.replayRetryTimers.values())clearTimeout(e);this.replayRetryTimers.clear(),this.replayRetryState.clear(),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.subscriptions.clear(),this.clientQueryStore.clear(),this.hydratedQueryCache.clear(),this.tabCoordinator?.stop(),this.tabCoordinator=void 0}assertOpen(){if(this.closed)throw new m("INTERNAL","LunoraClient is closed")}followsAnotherTab(){const e=this.tabCoordinator;if(e===void 0||e.isLeader())return!1;const t=e.leaderTabId;return t!==void 0&&t!==e.id}assertLeaderOwnedSurface(e){if(this.followsAnotherTab())throw new m("NOT_IMPLEMENTED",`LunoraClient: \`${e}\` is unavailable on a cross-tab follower tab. The \`crossTabSync\` channel only carries data from the leader tab outward, so this call could never reach the server. Turn off \`crossTabSync\`, or keep \`${e}\` on the leader tab.`)}clearConnectionTimers(e){clearTimeout(e.reconnectTimer),clearTimeout(e.connectTimer),clearTimeout(e.stableTimer),e.reconnectTimer=void 0,e.connectTimer=void 0,e.stableTimer=void 0}teardownConnection(e){const t=l(e.shardKey);for(const[s,r]of this.streams)l(r.shardKey)===t&&(r.handle.fail(new m("STREAM_DISCONNECTED","stream terminated: the connection carrying it was torn down")),this.streams.delete(s));if(e.pendingStreams=void 0,e.pendingUnsubscribes=[],this.clearConnectionTimers(e),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 he({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,i,n)=>{if(n!==void 0&&n!==this.identityFingerprint())return;const a=this.subscriptions.get(t);a&&(a.serverBase=s,r!==void 0&&(a.serverCursor=r,i!==void 0&&(a.serverEpoch=i),U(a,r)),O(a,R(s,a.optimisticLayers)))},onLeaderClaimAnswered:()=>{this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastConnectionStatus(this.computeStatus(),this.identityFingerprint())},onSubscriptionError:(t,s,r)=>{if(r!==void 0&&r!==this.identityFingerprint())return;const i=this.subscriptions.get(t);i&&E(i.errorCallbacks,s)},onSubscriptionSettled:(t,s,r,i,n,a)=>{if(a!==void 0&&a!==this.identityFingerprint())return;const c=this.subscriptions.get(t);if(c){this.ackAndAdvanceCursor(c,s,r),i!==void 0&&n===this.clientId&&(c.lastMutationId=Math.max(c.lastMutationId??0,i));for(const h of c.checkpointCallbacks)h({checkpoint:c.serverCursor,mutationId:c.lastMutationId})}}})}async enqueueOfflineMutation(e,t,s,r,i,n,a){const c=this.identityFingerprint();if(this.outbox){this.outboxMutationCounter+=1;const h=this.outboxMutationCounter;try{await this.outbox.enqueue({args:t,clientId:this.clientId,functionPath:e.__lunoraRef,idempotencyKey:`${this.clientId}:${String(h)}`,identity:c,mutationId:h,shardKey:s})}catch(d){throw H(i),d instanceof Error?d:new Error(String(d))}for(const d of n)d(void 0);return}return new Promise((h,d)=>{const u={args:t,functionPath:e.__lunoraRef,liveAwaiter:!0,id:r,clientId:this.clientId,identity:c,precondition:a,onCommit:f=>{for(const S of n)S(f)},reject:f=>{this.queuedIdentities.delete(r),H(i),d(f instanceof Error?f:new Error(String(f)))},resolve:h,shardKey:s};this.offlineQueue.enqueue(u),this.queuedOfflineShardKeys.add(s),u.id!==void 0&&this.queuedIdentities.set(u.id,c)})}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(),t=new Map;for(const s of this.subscriptions.all())t.set(P(s.fn.__lunoraRef,s.argsKey,s.shardKey),s);for(const{key:s,...r}of e){if(me(this.persistenceVersion,r.version)){this.queryCache.remove(s).catch(()=>{});continue}const i=t.get(s);if(i){this.seedSubscriptionFromCache(i,r);continue}this.hydratedQueryCache.set(s,r)}}catch{}}seedSubscriptionFromCache(e,t){e.serverBase!==void 0||e.lastValue!==void 0||t.identity!==this.identityFingerprint()||(e.serverBase=t.value,e.serverCursor=t.serverCursor,t.serverEpoch!==void 0&&(e.serverEpoch=t.serverEpoch),O(e,R(t.value,e.optimisticLayers)))}takeHydratedCache(e,t,s){const r=P(e,t,s),i=this.hydratedQueryCache.get(r);if(i!==void 0)return this.hydratedQueryCache.delete(r),i.identity===this.identityFingerprint()?i:void 0}persistQueryValue(e){const t=e.serverBase;if(!this.queryCache||t===void 0)return;const s=P(e.fn.__lunoraRef,e.argsKey,e.shardKey),r=this.getConnection(e.shardKey)?.identity;this.pendingCacheWrites.set(s,{identity:r===void 0?this.identityFingerprint():r,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(()=>{})},xe)}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(async([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 i=[],n=[];if(!r)return{confirms:i,rollbacks:n};const a=k.key(e,t,s),c=this.subscriptions.get(a);if(c){const h=ue(c,r);h&&(i.push(h.confirm),n.push(h.rollback))}return{confirms:i,rollbacks:n}}applyOptimisticUpdate(e,t,s,r,i){const{confirms:n,rollbacks:a,store:c}=le(this.subscriptions,s);try{e(c,t)}catch{H(a);return}r.push(...a),i.push(...n)}getConnection(e){return this.connections.get(l(e))}sendOrQueueUnsubscribe(e,t,s){const r=this.getConnection(e);r&&!b(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=l(e);let s=this.connections.get(t);return s||(s={connectTimer:void 0,heartbeatTimer:void 0,lastFrameAt:0,pendingUnsubscribes:[],reconnect:Q(this.reconnectOptions),reconnectTimer:void 0,shardKey:e,socket:void 0,stableTimer: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 i=this.bookmark.get();i&&(s["x-d1-bookmark"]=i)}return s}async rpc(e,t,s,r={}){if(!this.fetchImpl)throw new A("LunoraClient: no `fetch` implementation available");const i=this.rpcRequestHeaders(r,s),n=await this.fetchImpl(C(this.url,Pe),{body:JSON.stringify({args:v(t,`args for '${e}'`),functionPath:e,shardKey:s}),headers:i,method:"POST"});if(r.captureBookmark){const c=n.headers.get("x-d1-bookmark");c&&this.bookmark.set(c)}let a;try{a=await n.json()}catch{throw M(n.status,n.statusText,n.headers.get("retry-after"))}if("error"in a)throw Y(a.error,n.headers.get("retry-after"));if(!n.ok)throw M(n.status,n.statusText,n.headers.get("retry-after"));return r.onMutationAck?.(a.lastMutationId),r.onCommitCursor?.(a.commitCursor),this.learnDefaultShardKey(n,s),this.recordShardCursor(s,a.commitCursor),T(a.result)}async adminFetch(e,t,s,r){if(!this.fetchImpl)throw new m("INTERNAL","LunoraClient: no `fetch` implementation available");const i={};this.authToken&&(i.authorization=`Bearer ${this.authToken}`);const n=s instanceof ArrayBuffer||s instanceof Blob;let a;s===void 0?a=void 0:n?(a=s,r!==void 0&&(i["content-type"]=r)):(a=JSON.stringify(s),i["content-type"]="application/json");const c=await this.fetchImpl(C(this.url,e),{body:a,headers:i,method:t});let h;try{h=await c.json()}catch{const d=c.statusText?` ${c.statusText}`:"";throw new m("INTERNAL",`LunoraClient: response was not JSON (status ${c.status.toString()}${d})`)}if(typeof h=="object"&&h!==null&&"error"in h){const d=h.error,u=new Error(d.message??"admin request failed");throw u.code=d.code,u}if(!c.ok){const d=c.statusText?` ${c.statusText}`:"";throw new m("INTERNAL",`LunoraClient: admin request failed (status ${c.status.toString()}${d})`)}return h}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(l(e.shardKey));b(e,{caps:es,clientId:this.clientId,id:"connect",type:"connect",...t===void 0?{}:{context:t}})}resendShapeSubscriptions(e){for(const t of this.shapeSubscriptions.values())l(t.shardKey)===l(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:i}=this;if(i===void 0)throw new m("INTERNAL","no WebSocket implementation available");const n=new i(t);e.socket=n;const a=()=>{this.stopHeartbeat(e),e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.socket===n&&(e.socket=void 0)},c=h=>{a(),r.onClose(h)};s>0&&(e.connectTimer=setTimeout(()=>{if(e.connectTimer=void 0,e.socket===n){try{n.close()}catch{}c()}},s)),n.addEventListener("open",()=>{if(e.socket===n){e.connectTimer!==void 0&&(clearTimeout(e.connectTimer),e.connectTimer=void 0),e.lastFrameAt=Date.now();try{r.onOpen?.()}catch(h){console.error("[lunora] connection open handler threw",h)}this.startHeartbeat(e,c)}}),n.addEventListener("message",h=>{if(e.socket===n){e.lastFrameAt=Date.now();try{r.onMessage(h)}catch(d){console.error("[lunora] server frame handler threw",d)}}}),n.addEventListener("close",h=>{e.socket===n&&c(h)}),n.addEventListener("error",()=>{e.socket===n&&c()})}openSocket(e,t,s){this.WebSocketImpl!==void 0&&(e.identity=this.identityFingerprint(),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,clearTimeout(e.stableTimer),e.stableTimer=setTimeout(()=>{e.wsState==="open"&&e.reconnect.reset()},Ne),this.emitConnectionStatus(),this.sendConnectEnvelope(e),this.markShardPendingAck(t);for(const i of this.subscriptions.all())l(i.shardKey)===l(t)&&this.sendSubscribeIfOpen(i);if(this.resendShapeSubscriptions(t),e.pendingUnsubscribes.length>0){const i=e.pendingUnsubscribes;e.pendingUnsubscribes=[];for(const{id:n,type:a}of i)b(e,{id:n,type:a})}this.flushPendingStreams(e);const r=this.whisperHandlers.get(l(t));if(r)for(const i of r.keys())b(e,{topic:i,type:"whisper_subscribe"});this.flushOfflineQueue(t).catch(()=>{})}}))}flushPendingStreams(e){if(!e.pendingStreams||e.pendingStreams.length===0)return;const t=e.pendingStreams;e.pendingStreams=[];for(const s of t){const r=b(e,s)?this.streams.get(String(s.id)):void 0;r&&(r.started=!0)}}cancelStream(e,t){const s=this.getConnection(t),r=this.streams.get(e);s&&(s.pendingStreams=s.pendingStreams?.filter(i=>i.id!==e),!b(s,{id:e,type:"unsubscribe"})&&r?.durable===!0&&r.started&&s.pendingUnsubscribes.push({id:e,type:"unsubscribe"})),this.streams.delete(e)}handleDisconnect(e){if(this.closed||e.wsState==="idle"||e.wsState==="closed")return;this.stopHeartbeat(e),this.clearConnectionTimers(e),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,i]of this.streams)if(!(l(i.shardKey)!==l(e.shardKey)||t.has(r))){if(i.durable){const n={...i.message,...i.generation===void 0?{}:{generation:i.generation},sinceChunk:i.lastSeq};i.message=n,e.pendingStreams=[...(e.pendingStreams??[]).filter(a=>a.id!==r),n];continue}i.handle.fail(new m("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=l(e);for(const s of this.subscriptions.all())l(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,r=e.serverCursor!==void 0&&e.serverBase!==void 0;b(t,{id:e.id,query:{args:e.wireArgs,functionPath:e.fn.__lunoraRef,table:s,...r?{sinceSeq:e.serverCursor}:{},...r&&e.serverEpoch!==void 0?{sinceEpoch:e.serverEpoch}:{}},type:"subscribe"})}sendShapeSubscribeIfOpen(e){const t=this.getConnection(e.shardKey);t?.wsState==="open"&&b(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=rs(e);if(s===void 0)return;let r;try{r=JSON.parse(s)}catch{return}switch(r.type!=="error"&&this.getConnection(t)?.reconnect.reset(),r.type){case"ack":{const i=this.subscriptions.getById(r.id);i&&(i.acked=!0);return}case"chunk":{const{data:i,generation:n,id:a,seq:c}=r,h=this.streams.get(a);h&&typeof c=="number"&&(h.lastSeq=c,typeof n=="number"&&(h.generation=n),h.durable=!0),h?.handle.push(T(i));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,t);break}case"pokePart":{this.handlePokePart(r,t);break}case"pokeStart":{this.handlePokeStart(r,t);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(ts(e)),this.streams.delete(s);return}const i=s===void 0?void 0:this.subscriptions.getById(s);if(i){const a=J(e),c=this.identityFingerprint(),h=k.keyOf(i);E(i.errorCallbacks,a),this.tabCoordinator?.isLeader()&&this.tabCoordinator.broadcastSubscriptionError(h,a,c);return}const n=s===void 0?void 0:this.shapeSubscriptions.get(s);n&&E(n.errorCallbacks,J(e))}pokeBufferKey(e,t){return`${l(e)}\0${t}`}handlePokeStart(e,t){ge(this.pokeBuffers,se.MAX_POKE_BUFFERS),this.pokeBuffers.set(this.pokeBufferKey(t,e.pokeId),{baseCheckpoint:e.baseCheckpoint,bases:new Map,epoch:e.epoch,lastMutationId:new Map,parts:new Map,resets:new Set})}handlePokePart(e,t){const s=this.pokeBuffers.get(this.pokeBufferKey(t,e.pokeId));if(!s)return;const r=s.parts.get(e.shapeId)??[];for(const n of e.rowsPatch)r.push(n.value===void 0?n:{...n,value:T(n.value)});s.parts.set(e.shapeId,r),e.lastMutationId!==void 0&&s.lastMutationId.set(e.shapeId,e.lastMutationId);const i=e.baseCheckpoint??s.baseCheckpoint;i!==void 0&&s.bases.set(e.shapeId,i),e.reset===!0&&s.resets.add(e.shapeId)}handlePokeEnd(e,t){const s=this.pokeBufferKey(t,e.pokeId),r=this.pokeBuffers.get(s);if(r){this.pokeBuffers.delete(s);for(const i of r.parts.keys()){const n=this.shapeSubscriptions.get(i);n&&this.applyPokePart(n,r,e)}}}applyPokePart(e,t,s){const r=t.parts.get(e.id)??[],i=t.resets.has(e.id),n=t.bases.get(e.id),a=t.epoch!==void 0&&e.serverEpoch!==void 0&&t.epoch!==e.serverEpoch,c=n!==void 0&&e.serverCursor!==void 0&&e.serverCursor!==n;if(!i&&(a||c)){e.rows.clear(),e.serverCursor=void 0,e.serverEpoch=void 0,this.emitShapeRows(e),this.sendShapeSubscribeIfOpen(e);return}i&&e.rows.clear(),He(e.rows,r),s.checkpoint!==void 0&&(e.serverCursor=s.checkpoint),s.epoch!==void 0&&(e.serverEpoch=s.epoch);const h=t.lastMutationId.get(e.id);h!==void 0&&(e.lastMutationId=h),this.emitShapeRows(e),e.onCheckpoint?.({checkpoint:e.serverCursor,mutationId:e.lastMutationId})}resnapshotSubscription(e){e.acked=!1,e.serverCursor=void 0,e.serverEpoch=void 0,console.warn("[lunora] could not merge a row delta into the cached result; re-subscribing for a full snapshot"),this.sendSubscribeIfOpen(e)}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;let r;try{r=this.resolveDataPayload(e,s)}catch(i){E(s.errorCallbacks,{code:"WIRE_DECODE_FAILED",message:`could not decode a server frame for this subscription — ${i instanceof Error?i.message:String(i)}`});return}if(r===z){this.resnapshotSubscription(s);return}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 i of s.checkpointCallbacks)i({checkpoint:s.serverCursor,mutationId:s.lastMutationId})}if(this.persistQueryValue(s),U(s,s.serverCursor),O(s,R(r,s.optimisticLayers)),this.tabCoordinator?.isLeader()){const i=k.keyOf(s);this.tabCoordinator.broadcastSubscriptionData(i,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=Math.max(t.lastMutationId??0,e.lastMutationId));for(const s of t.checkpointCallbacks)s({checkpoint:t.serverCursor,mutationId:t.lastMutationId});if(this.tabCoordinator?.isLeader()){const s=k.keyOf(t);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),U(e,e.serverCursor)&&O(e,R(e.serverBase,e.optimisticLayers)))}resolveDataPayload(e,t){if("data"in e&&e.data!==void 0)return T(e.data);const s=T(e.delta);return ie(s)?t.serverBase===void 0?s:ne(t.serverBase,s)??z:s}dispatchWhisper(e,t){const s=this.whisperHandlers.get(l(t))?.get(e.topic);if(!s)return;const r=T(e.data);for(const i of s)try{i(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,E(s.errorCallbacks,{code:"SUBSCRIPTION_CANCELLED",message:"subscription was cancelled by the server"}))}unpersist(e){e&&this.persistence?.remove(e).catch(t=>{pe(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 i=e.charCodeAt(r);t^=i,t=Math.imul(t,16777619),s=Math.imul(s,33)+i}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);this.offlineQueue.restampIdentity(e,t)}restampWatermarks(e,t){const s=e??"",r=this.clientWatermarks.get(s);if(r===void 0)return;this.clientWatermarks.delete(s);const i=t??"",n=this.clientWatermarks.get(i);if(n===void 0)this.clientWatermarks.set(i,r);else for(const[a,c]of r)n.set(a,c)}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=l(e),s=this.offlineFlushes.get(t);if(s===void 0&&this.offlineQueue.size===0)return;const r=(async()=>{await(s??Promise.resolve());try{await this.drainOfflineQueue(e)}catch{}})();this.offlineFlushes.set(t,r),await r,this.offlineFlushes.get(t)===r&&this.offlineFlushes.delete(t)}async drainOfflineQueue(e){const t=this.offlineQueue.drainConflict();for(const h of t){this.unpersist(h.id),this.queuedIdentities.delete(h.id??"");const d=new Error("offline mutation skipped: precondition failed before replay");d.code="OFFLINE_PRECONDITION_FAILED",this.emitItemSettled(h,"rejected",d)}const s=l(e),r=this.offlineQueue.drain(h=>l(h.shardKey)===s);if(r.length===0)return;const i=this.identityFingerprint(),n=[];for(const h of r)this.passesReplayIdentityGate(h,i)&&n.push(h);if(n.length===0)return;const a=this.encodableOrSettleTerminal(n);if(a.length===0)return;if(a.length===1){await this.replaySequential(a,e),this.scheduleRateLimitedRetry(e);return}const c=[];for(let h=0;h<a.length;h+=x){const d=a.slice(h,h+x),u=await this.replayBatched(d,e);if(c.push(...u.requeue),u.stop){c.push(...a.slice(h+x));break}}c.length>0&&this.offlineQueue.requeue(c),this.scheduleRateLimitedRetry(e)}noteReplayRetryDelay(e,t){const s=l(e),r=this.replayRetryState.get(s),i=(r?.attempts??0)+1,n=Ie(t,i);this.replayRetryState.set(s,{attempts:i,delayMs:n===void 0?r?.delayMs:Math.max(r?.delayMs??0,n)})}scheduleRateLimitedRetry(e){const t=l(e),s=this.replayRetryState.get(t),r=s?.delayMs;if(s===void 0||r===void 0||this.closed||this.offlineQueue.size===0){this.replayRetryState.delete(t);return}s.delayMs=void 0;const i=this.replayRetryTimers.get(t);i!==void 0&&clearTimeout(i),this.replayRetryTimers.set(t,setTimeout(()=>{this.replayRetryTimers.delete(t),this.flushOfflineQueue(e).catch(()=>{})},r))}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 i=new Error("offline mutation skipped: auth identity changed before replay");return i.code="OFFLINE_IDENTITY_CHANGED",e.reject(i),this.emitItemSettled(e,"rejected",i),!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,t){for(let s=0;s<e.length;s+=1){const r=e[s];if(r)try{let i;const n=await this.rpc(r.functionPath,r.args,r.shardKey,{captureBookmark:!0,clientId:r.clientId??this.clientId,mutationId:r.id,onCommitCursor:a=>{i=a}});this.settleReplaySuccess(r,n,i)}catch(i){if(!ke(i)){this.settleReplayTerminal(r,i);continue}this.noteReplayRetryDelay(t,i),this.offlineQueue.requeue(e.slice(s));return}}}async replayBatched(e,t){if(!this.fetchImpl)return{requeue:e,stop:!0};const s=JSON.stringify({calls:e.map((c,h)=>({args:v(c.args,`args for '${c.functionPath}'`),functionPath:c.functionPath,id:h,clientId:c.clientId??this.clientId,mutationId:c.id,shardKey:c.shardKey}))});if(e.length>1&&Re(s)>Oe)return await this.replayBatchedHalves(e,t);let r;try{r=await this.fetchImpl(C(this.url,G),{body:s,headers:this.rpcRequestHeaders({attachBookmark:!0}),method:"POST"})}catch{return{requeue:e,stop:!0}}const i=r.headers.get("x-d1-bookmark");if(i&&this.bookmark.set(i),r.status===413&&e.length>1)return await this.replayBatchedHalves(e,t);let n;const a=r.headers.get("retry-after");try{n=await r.json()}catch{return this.settleWholeBatchError(e,M(r.status,r.statusText,a),t)}if(!n.results){const c=n.error===void 0?M(r.status,r.statusText,a):Y(n.error,a);return this.settleWholeBatchError(e,c,t)}return{requeue:this.settleReplayBatchSlots(e,n.results,t),stop:!1}}settleWholeBatchError(e,t,s){if(t instanceof A||t.code!==void 0&&L.has(t.code))return this.noteReplayRetryDelay(s,t),{requeue:e,stop:!0};for(const r of e)this.settleReplayTerminal(r,t);return{requeue:[],stop:!1}}async replayBatchedHalves(e,t){const s=Math.ceil(e.length/2),r=await this.replayBatched(e.slice(0,s),t);if(r.stop)return{requeue:[...r.requeue,...e.slice(s)],stop:!0};const i=await this.replayBatched(e.slice(s),t);return{requeue:[...r.requeue,...i.requeue],stop:i.stop}}settleReplayBatchSlots(e,t,s){const r=new Map;for(const n of t)typeof n.id=="number"&&n.body!==void 0&&r.set(n.id,n.body);const i=[];for(const[n,a]of e.entries()){const c=r.get(n);c===void 0?i.push(a):"error"in c?L.has(c.error.code)?(this.noteReplayRetryDelay(s,_(c.error)),i.push(a)):this.settleReplayTerminal(a,_(c.error)):this.settleReplaySuccess(a,T(c.result),c.commitCursor)}return i}}export{se as LunoraClient};