@lunora/client 1.0.0-alpha.20 → 1.0.0-alpha.21

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.
Files changed (27) hide show
  1. package/dist/auth/index.d.mts +1 -1
  2. package/dist/auth/index.d.ts +1 -1
  3. package/dist/index.d.mts +3 -3
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.mjs +6 -6
  6. package/dist/packem_shared/{LunoraClient-hrmLXEHd.mjs → LunoraClient-kXpHNyaE.mjs} +62 -13
  7. package/dist/packem_shared/SubscriptionRegistry-DjGKZsqq.mjs +1 -0
  8. package/dist/packem_shared/{applyDelta-4jFGTPA3.mjs → applyDelta-CRKZ1PBt.mjs} +21 -1
  9. package/dist/packem_shared/{createInMemoryPersistence-Ds7z8n8d.mjs → createInMemoryPersistence-DZ2VHWgm.mjs} +7 -47
  10. package/dist/packem_shared/{createInMemoryQueryCache-iWtKPrid.mjs → createInMemoryQueryCache-DiaGZkA2.mjs} +7 -47
  11. package/dist/packem_shared/createLocalStore-jRoqmazl.mjs +2 -0
  12. package/dist/packem_shared/{createServerClient-CKKZrXLc.mjs → createServerClient-DF-3mLmb.mjs} +1 -1
  13. package/dist/packem_shared/idb-utility-DrSVX43Q.mjs +48 -0
  14. package/dist/packem_shared/{local-store-BNgN3Dw3.mjs → local-store-BveBeFEo.mjs} +7 -12
  15. package/dist/packem_shared/{lunora-client.d-DVdVtJV8.d.mts → lunora-client.d-BYkEjCEJ.d.mts} +29 -1
  16. package/dist/packem_shared/{lunora-client.d-DVdVtJV8.d.ts → lunora-client.d-BYkEjCEJ.d.ts} +29 -1
  17. package/dist/packem_shared/{preload.d-Bb69VRgE.d.ts → preload.d-B-vyHnml.d.ts} +1 -1
  18. package/dist/packem_shared/{preload.d-BXFvxpiv.d.mts → preload.d-DrfuisCE.d.mts} +1 -1
  19. package/dist/packem_shared/{subscription-DoyO04-2.mjs → subscription-BjynOXCU.mjs} +4 -1
  20. package/dist/query/index.d.mts +2 -2
  21. package/dist/query/index.d.ts +2 -2
  22. package/dist/ssr/index.d.mts +3 -3
  23. package/dist/ssr/index.d.ts +3 -3
  24. package/dist/ssr/index.mjs +1 -1
  25. package/package.json +2 -2
  26. package/dist/packem_shared/SubscriptionRegistry-Cxr70og-.mjs +0 -1
  27. package/dist/packem_shared/createLocalStore-IOur0jHF.mjs +0 -1
@@ -1,4 +1,4 @@
1
- import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-DVdVtJV8.mjs";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-BYkEjCEJ.mjs";
2
2
  import '@lunora/runtime';
3
3
  interface IdentityStore {
4
4
  /** Read the current resolved user, or `null` when signed out / not yet resolved. */
@@ -1,4 +1,4 @@
1
- import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-DVdVtJV8.js";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-BYkEjCEJ.js";
2
2
  import '@lunora/runtime';
3
3
  interface IdentityStore {
4
4
  /** Read the current resolved user, or `null` when signed out / not yet resolved. */
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { c as PersistenceAdapter, B as BookmarkStorage, F as FunctionReference, A as ArgsOf, M as MutationCallOptions, R as ReturnOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, d as ReconnectOptions } from "./packem_shared/lunora-client.d-DVdVtJV8.mjs";
2
- export { type e as BatchSlot, C as CONFLICT_ERROR_CODE, type f as CachedQuery, type g as ClientMessage, type h as ClientShapeSubscribeMessage, type i as ClientShapeUnsubscribeMessage, type j as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type k as FunctionArgumentDescriptor, type l as FunctionDescriptor, type G as GlobalFacetResult, type m as GlobalFacetValue, type n as GlobalFilterClause, type o as GlobalTableInfo, type p as GlobalTablePage, L as LunoraClient, type q as LunoraClientError, type r as LunoraClientOptions, type s as LunoraErrorCode, type t as MutationSettledEvent, type u as OptimisticLocalStore, type v as OptimisticUpdate, type w as OutboxMutation, type x as OutboxSink, type y as PersistedMutation, type P as Preloaded, type z as RowOp, type E as RpcEnvelope, type H as RpcResponseBody, type I as ScheduleRecord, type J as SchedulerPoolStatus, type K as SchedulerStatus, type N as ServerMessage, type T as ServerPokeEndMessage, type V as ServerPokePartMessage, type W as ServerPokeStartMessage, type X as ShardTrafficEntry, type Y as ShardTrafficResult, type Z as StorageListPage, type _ as StorageObject, type $ as StreamHandle, type a0 as StreamIterable, type a1 as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a2 as SubscriptionRegistry, type a3 as SubscriptionState, type a4 as SyncWatermark, type a as Unsubscribe, type U as User, type a5 as WorkflowInstanceAction, type a6 as WorkflowInstanceDetail, type a7 as WorkflowInstancePage, type a8 as WorkflowInstanceStatus, type a9 as WorkflowInstanceSummary, type aa as WorkflowStepDetail, ab as createLocalStore, ac as createStream, ad as getErrorCode, ae as getRetryAfterMs, af as isConflictError, ag as isForbiddenError, ah as isRateLimitedError, ai as isUnauthorizedError } from "./packem_shared/lunora-client.d-DVdVtJV8.mjs";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-BXFvxpiv.mjs";
1
+ import { c as PersistenceAdapter, B as BookmarkStorage, F as FunctionReference, A as ArgsOf, M as MutationCallOptions, R as ReturnOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, d as ReconnectOptions } from "./packem_shared/lunora-client.d-BYkEjCEJ.mjs";
2
+ export { type e as BatchSlot, C as CONFLICT_ERROR_CODE, type f as CachedQuery, type g as ClientMessage, type h as ClientShapeSubscribeMessage, type i as ClientShapeUnsubscribeMessage, type j as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type k as FunctionArgumentDescriptor, type l as FunctionDescriptor, type G as GlobalFacetResult, type m as GlobalFacetValue, type n as GlobalFilterClause, type o as GlobalTableInfo, type p as GlobalTablePage, L as LunoraClient, type q as LunoraClientError, type r as LunoraClientOptions, type s as LunoraErrorCode, type t as MutationSettledEvent, type u as OptimisticLocalStore, type v as OptimisticUpdate, type w as OutboxMutation, type x as OutboxSink, type y as PersistedMutation, type P as Preloaded, type z as RowOp, type E as RpcEnvelope, type H as RpcResponseBody, type I as ScheduleRecord, type J as SchedulerPoolStatus, type K as SchedulerStatus, type N as ServerMessage, type T as ServerPokeEndMessage, type V as ServerPokePartMessage, type W as ServerPokeStartMessage, type X as ShardTrafficEntry, type Y as ShardTrafficResult, type Z as StorageListPage, type _ as StorageObject, type $ as StreamHandle, type a0 as StreamIterable, type a1 as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a2 as SubscriptionRegistry, type a3 as SubscriptionState, type a4 as SyncWatermark, type a as Unsubscribe, type U as User, type a5 as WorkflowInstanceAction, type a6 as WorkflowInstanceDetail, type a7 as WorkflowInstancePage, type a8 as WorkflowInstanceStatus, type a9 as WorkflowInstanceSummary, type aa as WorkflowStepDetail, ab as createLocalStore, ac as createStream, ad as getErrorCode, ae as getRetryAfterMs, af as isConflictError, ag as isForbiddenError, ah as isRateLimitedError, ai as isUnauthorizedError } from "./packem_shared/lunora-client.d-BYkEjCEJ.mjs";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-DrfuisCE.mjs";
4
4
  export type { AuthCapabilities, AuthConfigInfo, AuthImpersonation, AuthPage, AuthSession, AuthUser, AuthUserFieldSpec, CronJobInfo, KvKeyEntry, KvKeyListResult, KvNamespaceSummary, KvValueResult, VectorIndexSummary, VectorQueryMatch } from '@lunora/runtime';
5
5
  /**
6
6
  * The slice of React Native's `AsyncStorage` (or any async key/value store —
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { c as PersistenceAdapter, B as BookmarkStorage, F as FunctionReference, A as ArgsOf, M as MutationCallOptions, R as ReturnOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, d as ReconnectOptions } from "./packem_shared/lunora-client.d-DVdVtJV8.js";
2
- export { type e as BatchSlot, C as CONFLICT_ERROR_CODE, type f as CachedQuery, type g as ClientMessage, type h as ClientShapeSubscribeMessage, type i as ClientShapeUnsubscribeMessage, type j as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type k as FunctionArgumentDescriptor, type l as FunctionDescriptor, type G as GlobalFacetResult, type m as GlobalFacetValue, type n as GlobalFilterClause, type o as GlobalTableInfo, type p as GlobalTablePage, L as LunoraClient, type q as LunoraClientError, type r as LunoraClientOptions, type s as LunoraErrorCode, type t as MutationSettledEvent, type u as OptimisticLocalStore, type v as OptimisticUpdate, type w as OutboxMutation, type x as OutboxSink, type y as PersistedMutation, type P as Preloaded, type z as RowOp, type E as RpcEnvelope, type H as RpcResponseBody, type I as ScheduleRecord, type J as SchedulerPoolStatus, type K as SchedulerStatus, type N as ServerMessage, type T as ServerPokeEndMessage, type V as ServerPokePartMessage, type W as ServerPokeStartMessage, type X as ShardTrafficEntry, type Y as ShardTrafficResult, type Z as StorageListPage, type _ as StorageObject, type $ as StreamHandle, type a0 as StreamIterable, type a1 as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a2 as SubscriptionRegistry, type a3 as SubscriptionState, type a4 as SyncWatermark, type a as Unsubscribe, type U as User, type a5 as WorkflowInstanceAction, type a6 as WorkflowInstanceDetail, type a7 as WorkflowInstancePage, type a8 as WorkflowInstanceStatus, type a9 as WorkflowInstanceSummary, type aa as WorkflowStepDetail, ab as createLocalStore, ac as createStream, ad as getErrorCode, ae as getRetryAfterMs, af as isConflictError, ag as isForbiddenError, ah as isRateLimitedError, ai as isUnauthorizedError } from "./packem_shared/lunora-client.d-DVdVtJV8.js";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-Bb69VRgE.js";
1
+ import { c as PersistenceAdapter, B as BookmarkStorage, F as FunctionReference, A as ArgsOf, M as MutationCallOptions, R as ReturnOf, O as OfflineQueueOptions, Q as QueryCacheAdapter, d as ReconnectOptions } from "./packem_shared/lunora-client.d-BYkEjCEJ.js";
2
+ export { type e as BatchSlot, C as CONFLICT_ERROR_CODE, type f as CachedQuery, type g as ClientMessage, type h as ClientShapeSubscribeMessage, type i as ClientShapeUnsubscribeMessage, type j as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type k as FunctionArgumentDescriptor, type l as FunctionDescriptor, type G as GlobalFacetResult, type m as GlobalFacetValue, type n as GlobalFilterClause, type o as GlobalTableInfo, type p as GlobalTablePage, L as LunoraClient, type q as LunoraClientError, type r as LunoraClientOptions, type s as LunoraErrorCode, type t as MutationSettledEvent, type u as OptimisticLocalStore, type v as OptimisticUpdate, type w as OutboxMutation, type x as OutboxSink, type y as PersistedMutation, type P as Preloaded, type z as RowOp, type E as RpcEnvelope, type H as RpcResponseBody, type I as ScheduleRecord, type J as SchedulerPoolStatus, type K as SchedulerStatus, type N as ServerMessage, type T as ServerPokeEndMessage, type V as ServerPokePartMessage, type W as ServerPokeStartMessage, type X as ShardTrafficEntry, type Y as ShardTrafficResult, type Z as StorageListPage, type _ as StorageObject, type $ as StreamHandle, type a0 as StreamIterable, type a1 as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a2 as SubscriptionRegistry, type a3 as SubscriptionState, type a4 as SyncWatermark, type a as Unsubscribe, type U as User, type a5 as WorkflowInstanceAction, type a6 as WorkflowInstanceDetail, type a7 as WorkflowInstancePage, type a8 as WorkflowInstanceStatus, type a9 as WorkflowInstanceSummary, type aa as WorkflowStepDetail, ab as createLocalStore, ac as createStream, ad as getErrorCode, ae as getRetryAfterMs, af as isConflictError, ag as isForbiddenError, ah as isRateLimitedError, ai as isUnauthorizedError } from "./packem_shared/lunora-client.d-BYkEjCEJ.js";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-B-vyHnml.js";
4
4
  export type { AuthCapabilities, AuthConfigInfo, AuthImpersonation, AuthPage, AuthSession, AuthUser, AuthUserFieldSpec, CronJobInfo, KvKeyEntry, KvKeyListResult, KvNamespaceSummary, KvValueResult, VectorIndexSummary, VectorQueryMatch } from '@lunora/runtime';
5
5
  /**
6
6
  * The slice of React Native's `AsyncStorage` (or any async key/value store —
package/dist/index.mjs CHANGED
@@ -1,15 +1,15 @@
1
1
  export { createAsyncStoragePersistence } from './packem_shared/createAsyncStoragePersistence-1Z5BZ8RC.mjs';
2
2
  export { default as createInMemoryBookmarkStorage } from './packem_shared/createInMemoryBookmarkStorage-BoN7a7TH.mjs';
3
- export { applyDelta, isMutationDelta } from './packem_shared/applyDelta-4jFGTPA3.mjs';
3
+ export { applyDelta, isMutationDelta } from './packem_shared/applyDelta-CRKZ1PBt.mjs';
4
4
  export { CONFLICT_ERROR_CODE, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from './packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs';
5
- export { c as createLocalStore } from './packem_shared/local-store-BNgN3Dw3.mjs';
6
- export { LunoraClient } from './packem_shared/LunoraClient-hrmLXEHd.mjs';
5
+ export { c as createLocalStore } from './packem_shared/local-store-BveBeFEo.mjs';
6
+ export { LunoraClient } from './packem_shared/LunoraClient-kXpHNyaE.mjs';
7
7
  export { createMutationRunner } from './packem_shared/createMutationRunner-BqsavzvG.mjs';
8
8
  export { createMutatorRunner } from './packem_shared/createMutatorRunner-BETvCd0p.mjs';
9
9
  export { O as OfflineQueue } from './packem_shared/offline-queue-B9vfdSqp.mjs';
10
- export { createInMemoryPersistence, createIndexedDbPersistence } from './packem_shared/createInMemoryPersistence-Ds7z8n8d.mjs';
10
+ export { createInMemoryPersistence, createIndexedDbPersistence } from './packem_shared/createInMemoryPersistence-DZ2VHWgm.mjs';
11
11
  export { preloadQuery, preloadedQueryResult } from './packem_shared/preloadQuery-lobFkD2Z.mjs';
12
- export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey } from './packem_shared/createInMemoryQueryCache-iWtKPrid.mjs';
12
+ export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey } from './packem_shared/createInMemoryQueryCache-DiaGZkA2.mjs';
13
13
  export { createReconnect } from './packem_shared/createReconnect-Di_-oHH7.mjs';
14
14
  export { DEFAULT_MAX_BUFFER, createStream } from './packem_shared/DEFAULT_MAX_BUFFER-7hFnzNk9.mjs';
15
- export { S as SubscriptionRegistry } from './packem_shared/subscription-DoyO04-2.mjs';
15
+ export { S as SubscriptionRegistry } from './packem_shared/subscription-BjynOXCU.mjs';
@@ -1,16 +1,26 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
- import { S as SubscriptionRegistry, s as stableStringify } from './subscription-DoyO04-2.mjs';
2
+ import { S as SubscriptionRegistry, s as stableStringify } from './subscription-BjynOXCU.mjs';
3
3
  import createInMemoryBookmarkStorage from './createInMemoryBookmarkStorage-BoN7a7TH.mjs';
4
- import { isMutationDelta, applyDelta } from './applyDelta-4jFGTPA3.mjs';
5
- import { a as applyOptimisticLayer, d as dropConfirmedLayers, n as notifySubscription, f as foldOptimistic, c as createLocalStore } from './local-store-BNgN3Dw3.mjs';
4
+ import { isMutationDelta, applyDelta } from './applyDelta-CRKZ1PBt.mjs';
5
+ import { a as applyOptimisticLayer, d as dropConfirmedLayers, n as notifySubscription, f as foldOptimistic, c as createLocalStore } from './local-store-BveBeFEo.mjs';
6
6
  import { O as OfflineQueue, n as nextId, i as isStaleVersion, r as reportPersistenceError } from './offline-queue-B9vfdSqp.mjs';
7
- import { resolvePersistenceAdapter } from './createInMemoryPersistence-Ds7z8n8d.mjs';
8
- import { resolveQueryCacheAdapter, queryCacheKey } from './createInMemoryQueryCache-iWtKPrid.mjs';
7
+ import { resolvePersistenceAdapter } from './createInMemoryPersistence-DZ2VHWgm.mjs';
8
+ import { resolveQueryCacheAdapter, queryCacheKey } from './createInMemoryQueryCache-DiaGZkA2.mjs';
9
9
  import { createReconnect } from './createReconnect-Di_-oHH7.mjs';
10
10
  import { createStream } from './DEFAULT_MAX_BUFFER-7hFnzNk9.mjs';
11
11
 
12
12
  const MAX_BATCH_ENTRIES = 500;
13
13
 
14
+ const evictOldestEntry = (map, capacity) => {
15
+ if (map.size < capacity) {
16
+ return;
17
+ }
18
+ const oldest = map.keys().next().value;
19
+ if (oldest !== void 0) {
20
+ map.delete(oldest);
21
+ }
22
+ };
23
+
14
24
  const TAG = "$lunora.wire$";
15
25
  const MAX_DEPTH = 64;
16
26
  const MAX_BIGINT_DIGITS = 1024;
@@ -2380,7 +2390,7 @@ class LunoraClient {
2380
2390
  * mutation or leave a partial patch live.
2381
2391
  */
2382
2392
  applyOptimisticUpdate(optimisticUpdate, args, shardKey, optimisticRollbacks, optimisticConfirms) {
2383
- const { confirms, rollbacks, store } = createLocalStore(this.subscriptions, shardKey, stableStringify);
2393
+ const { confirms, rollbacks, store } = createLocalStore(this.subscriptions, shardKey);
2384
2394
  try {
2385
2395
  optimisticUpdate(store, args);
2386
2396
  } catch {
@@ -2709,6 +2719,13 @@ class LunoraClient {
2709
2719
  conn.wsState = "idle";
2710
2720
  this.emitConnectionStatus();
2711
2721
  this.markShardPendingAck(conn.shardKey);
2722
+ const pendingStreamIds = new Set((conn.pendingStreams ?? []).map((message) => message.id));
2723
+ for (const [id, stream] of this.streams) {
2724
+ if (connectionKey(stream.shardKey) === connectionKey(conn.shardKey) && !pendingStreamIds.has(id)) {
2725
+ stream.handle.fail(new LunoraError("STREAM_DISCONNECTED", "stream terminated: WebSocket disconnected"));
2726
+ this.streams.delete(id);
2727
+ }
2728
+ }
2712
2729
  if (this.WebSocketImpl === void 0) {
2713
2730
  return;
2714
2731
  }
@@ -2881,12 +2898,7 @@ class LunoraClient {
2881
2898
  }
2882
2899
  }
2883
2900
  handlePokeStart(message) {
2884
- if (this.pokeBuffers.size >= LunoraClient.MAX_POKE_BUFFERS) {
2885
- const oldest = this.pokeBuffers.keys().next().value;
2886
- if (oldest !== void 0) {
2887
- this.pokeBuffers.delete(oldest);
2888
- }
2889
- }
2901
+ evictOldestEntry(this.pokeBuffers, LunoraClient.MAX_POKE_BUFFERS);
2890
2902
  this.pokeBuffers.set(message.pokeId, { baseCheckpoint: message.baseCheckpoint, epoch: message.epoch, lastMutationId: /* @__PURE__ */ new Map(), parts: /* @__PURE__ */ new Map() });
2891
2903
  }
2892
2904
  handlePokePart(message) {
@@ -3108,6 +3120,24 @@ class LunoraClient {
3108
3120
  if (token === null) {
3109
3121
  return null;
3110
3122
  }
3123
+ return this.hashToken(token);
3124
+ }
3125
+ /**
3126
+ * Stable token-hash fingerprint of a bearer token (the `&lt;len>:&lt;fnv>:&lt;djb2>`
3127
+ * format a token-stamped queued write carries). Extracted so the replay gate
3128
+ * can recompute the hash of the current credential and recognise a write
3129
+ * stamped under it — even after the fingerprint was relabelled to a subject.
3130
+ *
3131
+ * Two independent 32-bit passes (FNV-1a + djb2) give a ~64-bit digest, so
3132
+ * two distinct equal-length tokens are astronomically unlikely to share a
3133
+ * fingerprint. A single 32-bit hash collides ~1-in-4e9 per equal-length
3134
+ * pair — enough that, on a shared device, user B could hydrate A's cached
3135
+ * reads. Different algorithms (not the same FNV with a different seed, which
3136
+ * would be affine-related) keep the two passes genuinely independent.
3137
+ * Still synchronous (no crypto) and stable across surrogate pairs.
3138
+ */
3139
+ // eslint-disable-next-line class-methods-use-this -- pure helper; a method for locality with identityFingerprint, reads no shared state
3140
+ hashToken(token) {
3111
3141
  let fnv = 2166136261;
3112
3142
  let djb2 = 5381;
3113
3143
  for (let index = 0; index < token.length; index += 1) {
@@ -3118,6 +3148,25 @@ class LunoraClient {
3118
3148
  }
3119
3149
  return `${token.length.toString(36)}:${(fnv >>> 0).toString(36)}:${(djb2 >>> 0).toString(36)}`;
3120
3150
  }
3151
+ /**
3152
+ * True when `stamped` is a token-hash of the SAME credential still held now,
3153
+ * even though the live identity has since been relabelled to a subject. Covers
3154
+ * `setAuthToken(token, userId)` where the subject resolved a tick after the
3155
+ * token was set: a write persisted (or requeued) under the token hash must
3156
+ * still replay — the credential never changed, only its label — instead of
3157
+ * being dropped as an identity mismatch. This is the durable counterpart to
3158
+ * {@link restampQueuedIdentity}, which only relabels the in-memory live stamp
3159
+ * (consumed on the first flush) and never touches `item.identity` or the
3160
+ * persisted record, so a reload or a transient-failure requeue would otherwise
3161
+ * fall back to the stale token-hash and wrongly reject the same user's write.
3162
+ */
3163
+ isSameCredentialUnderTokenHash(stamped) {
3164
+ if (stamped === null || stamped.startsWith("subj:")) {
3165
+ return false;
3166
+ }
3167
+ const token = this.authToken;
3168
+ return token === null ? false : this.hashToken(token) === stamped;
3169
+ }
3121
3170
  /**
3122
3171
  * Drain every in-memory offline write and reject it because the auth
3123
3172
  * identity changed. Durable entries are also dropped from persistence so a
@@ -3246,7 +3295,7 @@ class LunoraClient {
3246
3295
  passesReplayIdentityGate(item, currentIdentity) {
3247
3296
  const liveStamp = item.id === void 0 ? void 0 : this.queuedIdentities.get(item.id);
3248
3297
  const stamped = liveStamp === void 0 ? item.identity : liveStamp;
3249
- if (stamped !== void 0 && stamped !== currentIdentity) {
3298
+ if (stamped !== void 0 && stamped !== currentIdentity && !this.isSameCredentialUnderTokenHash(stamped)) {
3250
3299
  this.queuedIdentities.delete(item.id ?? "");
3251
3300
  this.unpersist(item.id);
3252
3301
  const error = new Error("offline mutation skipped: auth identity changed before replay");
@@ -0,0 +1 @@
1
+ export { S as SubscriptionRegistry } from './subscription-BjynOXCU.mjs';
@@ -7,14 +7,34 @@ const rowId = (row) => {
7
7
  const id = row[ID_FIELD];
8
8
  return typeof id === "string" ? id : void 0;
9
9
  };
10
+ const isDescending = (list) => {
11
+ let previous;
12
+ for (const existingRow of list) {
13
+ const existing = existingRow[CREATION_FIELD];
14
+ if (typeof existing !== "number") {
15
+ continue;
16
+ }
17
+ if (previous !== void 0) {
18
+ if (existing < previous) {
19
+ return true;
20
+ }
21
+ if (existing > previous) {
22
+ return false;
23
+ }
24
+ }
25
+ previous = existing;
26
+ }
27
+ return false;
28
+ };
10
29
  const insertionIndex = (list, row) => {
11
30
  const creation = row[CREATION_FIELD];
12
31
  if (typeof creation !== "number") {
13
32
  return list.length;
14
33
  }
34
+ const descending = isDescending(list);
15
35
  for (const [index, existingRow] of list.entries()) {
16
36
  const existing = existingRow[CREATION_FIELD];
17
- if (typeof existing === "number" && existing > creation) {
37
+ if (typeof existing === "number" && (descending ? existing < creation : existing > creation)) {
18
38
  return index;
19
39
  }
20
40
  }
@@ -1,4 +1,5 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
+ import { p as promisifyRequest, c as createWithStore, a as createDatabaseOpener } from './idb-utility-DrSVX43Q.mjs';
2
3
 
3
4
  const createInMemoryPersistence = () => {
4
5
  const entries = /* @__PURE__ */ new Map();
@@ -30,14 +31,6 @@ const createInMemoryPersistence = () => {
30
31
  const DEFAULT_DATABASE = "lunora-outbox";
31
32
  const DEFAULT_STORE = "offline-mutations";
32
33
  const ID_INDEX = "by_id";
33
- const promisifyRequest = (request) => new Promise((resolve, reject) => {
34
- request.addEventListener("success", () => {
35
- resolve(request.result);
36
- });
37
- request.addEventListener("error", () => {
38
- reject(request.error ?? new Error("IndexedDB request failed"));
39
- });
40
- });
41
34
  const createIndexedDbPersistence = (options = {}) => {
42
35
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
43
36
  if (!factory) {
@@ -45,46 +38,13 @@ const createIndexedDbPersistence = (options = {}) => {
45
38
  }
46
39
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
47
40
  const storeName = options.storeName ?? DEFAULT_STORE;
48
- let databasePromise;
49
- const openDatabase = () => {
50
- if (databasePromise) {
51
- return databasePromise;
41
+ const openDatabase = createDatabaseOpener(factory, databaseName, 1, (database) => {
42
+ if (!database.objectStoreNames.contains(storeName)) {
43
+ const store = database.createObjectStore(storeName, { autoIncrement: true });
44
+ store.createIndex(ID_INDEX, "id", { unique: true });
52
45
  }
53
- databasePromise = new Promise((resolve, reject) => {
54
- const request = factory.open(databaseName, 1);
55
- request.addEventListener("upgradeneeded", () => {
56
- const database = request.result;
57
- if (!database.objectStoreNames.contains(storeName)) {
58
- const store = database.createObjectStore(storeName, { autoIncrement: true });
59
- store.createIndex(ID_INDEX, "id", { unique: true });
60
- }
61
- });
62
- request.addEventListener("success", () => {
63
- resolve(request.result);
64
- });
65
- request.addEventListener("error", () => {
66
- reject(request.error ?? new Error("IndexedDB open failed"));
67
- });
68
- });
69
- return databasePromise;
70
- };
71
- const withStore = async (mode, run) => {
72
- const database = await openDatabase();
73
- const transaction = database.transaction(storeName, mode);
74
- const result = await run(transaction.objectStore(storeName));
75
- await new Promise((resolve, reject) => {
76
- transaction.addEventListener("complete", () => {
77
- resolve();
78
- });
79
- transaction.addEventListener("error", () => {
80
- reject(transaction.error ?? new Error("IndexedDB transaction failed"));
81
- });
82
- transaction.addEventListener("abort", () => {
83
- reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
84
- });
85
- });
86
- return result;
87
- };
46
+ });
47
+ const withStore = createWithStore(openDatabase, storeName);
88
48
  return {
89
49
  append: async (mutation) => {
90
50
  await withStore("readwrite", (store) => promisifyRequest(store.add(mutation)));
@@ -1,4 +1,5 @@
1
1
  import { LunoraError } from '@lunora/errors';
2
+ import { p as promisifyRequest, c as createWithStore, a as createDatabaseOpener } from './idb-utility-DrSVX43Q.mjs';
2
3
 
3
4
  const queryCacheKey = (functionPath, argsKey, shardKey) => `${functionPath}::${argsKey}::${shardKey ?? ""}`;
4
5
  const DEFAULT_MAX_ENTRIES = 500;
@@ -41,14 +42,6 @@ const DEFAULT_DATABASE = "lunora-query-cache";
41
42
  const DEFAULT_STORE = "query-cache";
42
43
  const TS_INDEX = "by_ts";
43
44
  const DATABASE_VERSION = 1;
44
- const promisifyRequest = (request) => new Promise((resolve, reject) => {
45
- request.addEventListener("success", () => {
46
- resolve(request.result);
47
- });
48
- request.addEventListener("error", () => {
49
- reject(request.error ?? new Error("IndexedDB request failed"));
50
- });
51
- });
52
45
  const createIndexedDbQueryCache = (options = {}) => {
53
46
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
54
47
  if (!factory) {
@@ -57,46 +50,13 @@ const createIndexedDbQueryCache = (options = {}) => {
57
50
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
58
51
  const storeName = options.storeName ?? DEFAULT_STORE;
59
52
  const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
60
- let databasePromise;
61
- const openDatabase = () => {
62
- if (databasePromise) {
63
- return databasePromise;
53
+ const openDatabase = createDatabaseOpener(factory, databaseName, DATABASE_VERSION, (database) => {
54
+ if (!database.objectStoreNames.contains(storeName)) {
55
+ const store = database.createObjectStore(storeName, { keyPath: "key" });
56
+ store.createIndex(TS_INDEX, "ts", { unique: false });
64
57
  }
65
- databasePromise = new Promise((resolve, reject) => {
66
- const request = factory.open(databaseName, DATABASE_VERSION);
67
- request.addEventListener("upgradeneeded", () => {
68
- const database = request.result;
69
- if (!database.objectStoreNames.contains(storeName)) {
70
- const store = database.createObjectStore(storeName, { keyPath: "key" });
71
- store.createIndex(TS_INDEX, "ts", { unique: false });
72
- }
73
- });
74
- request.addEventListener("success", () => {
75
- resolve(request.result);
76
- });
77
- request.addEventListener("error", () => {
78
- reject(request.error ?? new Error("IndexedDB open failed"));
79
- });
80
- });
81
- return databasePromise;
82
- };
83
- const withStore = async (mode, run) => {
84
- const database = await openDatabase();
85
- const transaction = database.transaction(storeName, mode);
86
- const result = await run(transaction.objectStore(storeName));
87
- await new Promise((resolve, reject) => {
88
- transaction.addEventListener("complete", () => {
89
- resolve();
90
- });
91
- transaction.addEventListener("error", () => {
92
- reject(transaction.error ?? new Error("IndexedDB transaction failed"));
93
- });
94
- transaction.addEventListener("abort", () => {
95
- reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
96
- });
97
- });
98
- return result;
99
- };
58
+ });
59
+ const withStore = createWithStore(openDatabase, storeName);
100
60
  const evict = async (store) => {
101
61
  const count = await promisifyRequest(store.count());
102
62
  let overflow = count - maxEntries;
@@ -0,0 +1,2 @@
1
+ export { c as createLocalStore } from './local-store-BveBeFEo.mjs';
2
+ import './subscription-BjynOXCU.mjs';
@@ -1,4 +1,4 @@
1
- import { LunoraClient } from './LunoraClient-hrmLXEHd.mjs';
1
+ import { LunoraClient } from './LunoraClient-kXpHNyaE.mjs';
2
2
 
3
3
  const createServerClient = (options) => {
4
4
  const client = new LunoraClient({ fetch: options.fetch, url: options.url });
@@ -0,0 +1,48 @@
1
+ const promisifyRequest = (request) => new Promise((resolve, reject) => {
2
+ request.addEventListener("success", () => {
3
+ resolve(request.result);
4
+ });
5
+ request.addEventListener("error", () => {
6
+ reject(request.error ?? new Error("IndexedDB request failed"));
7
+ });
8
+ });
9
+ const createDatabaseOpener = (factory, databaseName, version, upgrade) => {
10
+ let databasePromise;
11
+ return () => {
12
+ if (databasePromise) {
13
+ return databasePromise;
14
+ }
15
+ databasePromise = new Promise((resolve, reject) => {
16
+ const request = factory.open(databaseName, version);
17
+ request.addEventListener("upgradeneeded", () => {
18
+ upgrade(request.result);
19
+ });
20
+ request.addEventListener("success", () => {
21
+ resolve(request.result);
22
+ });
23
+ request.addEventListener("error", () => {
24
+ reject(request.error ?? new Error("IndexedDB open failed"));
25
+ });
26
+ });
27
+ return databasePromise;
28
+ };
29
+ };
30
+ const createWithStore = (open, storeName) => async (mode, run) => {
31
+ const database = await open();
32
+ const transaction = database.transaction(storeName, mode);
33
+ const result = await run(transaction.objectStore(storeName));
34
+ await new Promise((resolve, reject) => {
35
+ transaction.addEventListener("complete", () => {
36
+ resolve();
37
+ });
38
+ transaction.addEventListener("error", () => {
39
+ reject(transaction.error ?? new Error("IndexedDB transaction failed"));
40
+ });
41
+ transaction.addEventListener("abort", () => {
42
+ reject(transaction.error ?? new Error("IndexedDB transaction aborted"));
43
+ });
44
+ });
45
+ return result;
46
+ };
47
+
48
+ export { createDatabaseOpener as a, createWithStore as c, promisifyRequest as p };
@@ -1,3 +1,5 @@
1
+ import { S as SubscriptionRegistry } from './subscription-BjynOXCU.mjs';
2
+
1
3
  const foldOptimistic = (base, layers) => {
2
4
  let value = base;
3
5
  for (const layer of layers) {
@@ -68,33 +70,26 @@ const dropConfirmedLayers = (state, cursor) => {
68
70
  return state.optimisticLayers.length !== before;
69
71
  };
70
72
 
71
- const createLocalStore = (subscriptions, shardKey, stableStringify) => {
73
+ const createLocalStore = (subscriptions, shardKey) => {
72
74
  const confirms = [];
73
75
  const rollbacks = [];
74
- const findState = (functionRef, argsKey) => {
75
- for (const state of subscriptions.all()) {
76
- if (state.fn.__lunoraRef === functionRef && state.shardKey === shardKey && state.argsKey === argsKey) {
77
- return state;
78
- }
79
- }
80
- return void 0;
81
- };
76
+ const findState = (functionRef, args) => subscriptions.get(SubscriptionRegistry.key(functionRef, args, shardKey));
82
77
  const store = {
83
78
  getAllQueries: (function_) => {
84
79
  const matches = [];
85
80
  for (const state of subscriptions.all()) {
86
- if (state.fn.__lunoraRef === function_.__lunoraRef && state.shardKey === shardKey) {
81
+ if (state.fn.__lunoraRef === function_.__lunoraRef && (state.shardKey ?? "") === (shardKey ?? "")) {
87
82
  matches.push({ args: state.args, value: state.lastValue });
88
83
  }
89
84
  }
90
85
  return matches;
91
86
  },
92
87
  getQuery: (function_, args) => {
93
- const state = findState(function_.__lunoraRef, stableStringify(args ?? {}));
88
+ const state = findState(function_.__lunoraRef, args ?? {});
94
89
  return state?.lastValue;
95
90
  },
96
91
  setQuery: (function_, args, value) => {
97
- const state = findState(function_.__lunoraRef, stableStringify(args ?? {}));
92
+ const state = findState(function_.__lunoraRef, args ?? {});
98
93
  if (!state) {
99
94
  return;
100
95
  }
@@ -1076,7 +1076,7 @@ type OptimisticUpdate<Args> = (localStore: OptimisticLocalStore, args: Args) =>
1076
1076
  * `confirm` (success) and `rollback` (failure) closures every `setQuery` produced,
1077
1077
  * so the caller settles the whole batch when the mutation does.
1078
1078
  */
1079
- declare const createLocalStore: (subscriptions: SubscriptionRegistry, shardKey: string | undefined, stableStringify: (value: unknown) => string) => {
1079
+ declare const createLocalStore: (subscriptions: SubscriptionRegistry, shardKey: string | undefined) => {
1080
1080
  confirms: ((commitCursor: number | undefined) => void)[];
1081
1081
  rollbacks: (() => void)[];
1082
1082
  store: OptimisticLocalStore;
@@ -2412,6 +2412,34 @@ declare class LunoraClient {
2412
2412
  */
2413
2413
  private identityFingerprint;
2414
2414
  /**
2415
+ * Stable token-hash fingerprint of a bearer token (the `&lt;len>:&lt;fnv>:&lt;djb2>`
2416
+ * format a token-stamped queued write carries). Extracted so the replay gate
2417
+ * can recompute the hash of the current credential and recognise a write
2418
+ * stamped under it — even after the fingerprint was relabelled to a subject.
2419
+ *
2420
+ * Two independent 32-bit passes (FNV-1a + djb2) give a ~64-bit digest, so
2421
+ * two distinct equal-length tokens are astronomically unlikely to share a
2422
+ * fingerprint. A single 32-bit hash collides ~1-in-4e9 per equal-length
2423
+ * pair — enough that, on a shared device, user B could hydrate A's cached
2424
+ * reads. Different algorithms (not the same FNV with a different seed, which
2425
+ * would be affine-related) keep the two passes genuinely independent.
2426
+ * Still synchronous (no crypto) and stable across surrogate pairs.
2427
+ */
2428
+ private hashToken;
2429
+ /**
2430
+ * True when `stamped` is a token-hash of the SAME credential still held now,
2431
+ * even though the live identity has since been relabelled to a subject. Covers
2432
+ * `setAuthToken(token, userId)` where the subject resolved a tick after the
2433
+ * token was set: a write persisted (or requeued) under the token hash must
2434
+ * still replay — the credential never changed, only its label — instead of
2435
+ * being dropped as an identity mismatch. This is the durable counterpart to
2436
+ * {@link restampQueuedIdentity}, which only relabels the in-memory live stamp
2437
+ * (consumed on the first flush) and never touches `item.identity` or the
2438
+ * persisted record, so a reload or a transient-failure requeue would otherwise
2439
+ * fall back to the stale token-hash and wrongly reject the same user's write.
2440
+ */
2441
+ private isSameCredentialUnderTokenHash;
2442
+ /**
2415
2443
  * Drain every in-memory offline write and reject it because the auth
2416
2444
  * identity changed. Durable entries are also dropped from persistence so a
2417
2445
  * later `hydrate` can't resurrect another user's writes. Stamps are cleared
@@ -1076,7 +1076,7 @@ type OptimisticUpdate<Args> = (localStore: OptimisticLocalStore, args: Args) =>
1076
1076
  * `confirm` (success) and `rollback` (failure) closures every `setQuery` produced,
1077
1077
  * so the caller settles the whole batch when the mutation does.
1078
1078
  */
1079
- declare const createLocalStore: (subscriptions: SubscriptionRegistry, shardKey: string | undefined, stableStringify: (value: unknown) => string) => {
1079
+ declare const createLocalStore: (subscriptions: SubscriptionRegistry, shardKey: string | undefined) => {
1080
1080
  confirms: ((commitCursor: number | undefined) => void)[];
1081
1081
  rollbacks: (() => void)[];
1082
1082
  store: OptimisticLocalStore;
@@ -2412,6 +2412,34 @@ declare class LunoraClient {
2412
2412
  */
2413
2413
  private identityFingerprint;
2414
2414
  /**
2415
+ * Stable token-hash fingerprint of a bearer token (the `&lt;len>:&lt;fnv>:&lt;djb2>`
2416
+ * format a token-stamped queued write carries). Extracted so the replay gate
2417
+ * can recompute the hash of the current credential and recognise a write
2418
+ * stamped under it — even after the fingerprint was relabelled to a subject.
2419
+ *
2420
+ * Two independent 32-bit passes (FNV-1a + djb2) give a ~64-bit digest, so
2421
+ * two distinct equal-length tokens are astronomically unlikely to share a
2422
+ * fingerprint. A single 32-bit hash collides ~1-in-4e9 per equal-length
2423
+ * pair — enough that, on a shared device, user B could hydrate A's cached
2424
+ * reads. Different algorithms (not the same FNV with a different seed, which
2425
+ * would be affine-related) keep the two passes genuinely independent.
2426
+ * Still synchronous (no crypto) and stable across surrogate pairs.
2427
+ */
2428
+ private hashToken;
2429
+ /**
2430
+ * True when `stamped` is a token-hash of the SAME credential still held now,
2431
+ * even though the live identity has since been relabelled to a subject. Covers
2432
+ * `setAuthToken(token, userId)` where the subject resolved a tick after the
2433
+ * token was set: a write persisted (or requeued) under the token hash must
2434
+ * still replay — the credential never changed, only its label — instead of
2435
+ * being dropped as an identity mismatch. This is the durable counterpart to
2436
+ * {@link restampQueuedIdentity}, which only relabels the in-memory live stamp
2437
+ * (consumed on the first flush) and never touches `item.identity` or the
2438
+ * persisted record, so a reload or a transient-failure requeue would otherwise
2439
+ * fall back to the stale token-hash and wrongly reject the same user's write.
2440
+ */
2441
+ private isSameCredentialUnderTokenHash;
2442
+ /**
2415
2443
  * Drain every in-memory offline write and reject it because the auth
2416
2444
  * identity changed. Durable entries are also dropped from persistence so a
2417
2445
  * later `hydrate` can't resurrect another user's writes. Stamps are cleared
@@ -1,4 +1,4 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DVdVtJV8.js";
1
+ import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-BYkEjCEJ.js";
2
2
  /**
3
3
  * Run a query once on the server (during SSR) and capture its result in a
4
4
  * serializable {@link Preloaded} token. Embed the token in the rendered HTML and
@@ -1,4 +1,4 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DVdVtJV8.mjs";
1
+ import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-BYkEjCEJ.mjs";
2
2
  /**
3
3
  * Run a query once on the server (during SSR) and capture its result in a
4
4
  * serializable {@link Preloaded} token. Embed the token in the rendered HTML and
@@ -54,7 +54,10 @@ class SubscriptionRegistry {
54
54
  this.byId.set(state.id, state);
55
55
  }
56
56
  remove(state) {
57
- this.byKey.delete(SubscriptionRegistry.key(state.fn.__lunoraRef, state.args, state.shardKey));
57
+ const key = SubscriptionRegistry.key(state.fn.__lunoraRef, state.args, state.shardKey);
58
+ if (this.byKey.get(key) === state) {
59
+ this.byKey.delete(key);
60
+ }
58
61
  this.byId.delete(state.id);
59
62
  }
60
63
  all() {
@@ -1,5 +1,5 @@
1
- import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DVdVtJV8.mjs";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DVdVtJV8.mjs";
1
+ import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-BYkEjCEJ.mjs";
2
+ export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-BYkEjCEJ.mjs";
3
3
  import '@lunora/runtime';
4
4
  /**
5
5
  * The sentinel a framework adapter resolves its reactive args to when it wants
@@ -1,5 +1,5 @@
1
- import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-DVdVtJV8.js";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DVdVtJV8.js";
1
+ import { S as SubscriptionError, F as FunctionReference, A as ArgsOf, R as ReturnOf, L as LunoraClient, a as Unsubscribe } from "../packem_shared/lunora-client.d-BYkEjCEJ.js";
2
+ export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-BYkEjCEJ.js";
3
3
  import '@lunora/runtime';
4
4
  /**
5
5
  * The sentinel a framework adapter resolves its reactive args to when it wants
@@ -1,6 +1,6 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DVdVtJV8.mjs";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DVdVtJV8.mjs";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-BXFvxpiv.mjs";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-BYkEjCEJ.mjs";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-BYkEjCEJ.mjs";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-DrfuisCE.mjs";
4
4
  import '@lunora/runtime';
5
5
  /**
6
6
  * Structural shape of a better-auth `getSession` call's resolved value.
@@ -1,6 +1,6 @@
1
- import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DVdVtJV8.js";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DVdVtJV8.js";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-Bb69VRgE.js";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-BYkEjCEJ.js";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-BYkEjCEJ.js";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-B-vyHnml.js";
4
4
  import '@lunora/runtime';
5
5
  /**
6
6
  * Structural shape of a better-auth `getSession` call's resolved value.
@@ -1,4 +1,4 @@
1
1
  export { getServerSession } from '../packem_shared/getServerSession-8jXewqxd.mjs';
2
2
  export { deserializePreloaded, serializePreloaded } from '../packem_shared/deserializePreloaded-C0eJTY_W.mjs';
3
- export { createServerClient } from '../packem_shared/createServerClient-CKKZrXLc.mjs';
3
+ export { createServerClient } from '../packem_shared/createServerClient-DF-3mLmb.mjs';
4
4
  export { preloadQuery, preloadedQueryResult } from '../packem_shared/preloadQuery-lobFkD2Z.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/client",
3
- "version": "1.0.0-alpha.20",
3
+ "version": "1.0.0-alpha.21",
4
4
  "description": "Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -62,7 +62,7 @@
62
62
  "access": "public"
63
63
  },
64
64
  "dependencies": {
65
- "@lunora/errors": "1.0.0-alpha.3"
65
+ "@lunora/errors": "1.0.0-alpha.4"
66
66
  },
67
67
  "engines": {
68
68
  "node": "^22.15.0 || >=24.11.0"
@@ -1 +0,0 @@
1
- export { S as SubscriptionRegistry } from './subscription-DoyO04-2.mjs';
@@ -1 +0,0 @@
1
- export { c as createLocalStore } from './local-store-BNgN3Dw3.mjs';