@lunora/client 1.0.0-alpha.15 → 1.0.0-alpha.17

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-CtSRWJJ7.mjs";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-DPLSlPiP.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-CtSRWJJ7.js";
1
+ import { U as User, L as LunoraClient } from "../packem_shared/lunora-client.d-DPLSlPiP.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-CtSRWJJ7.mjs";
2
- export { type e as BatchSlot, type C as CachedQuery, type f as ClientMessage, type g as ClientShapeSubscribeMessage, type h as ClientShapeUnsubscribeMessage, type i as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type j as FunctionArgumentDescriptor, type k as FunctionDescriptor, type G as GlobalFacetResult, type l as GlobalFacetValue, type m as GlobalFilterClause, type n as GlobalTableInfo, type o as GlobalTablePage, L as LunoraClient, type p as LunoraClientError, type q as LunoraClientOptions, type r as MutationSettledEvent, type s as OptimisticLocalStore, type t as OptimisticUpdate, type u as OutboxMutation, type v as OutboxSink, type w as PersistedMutation, type P as Preloaded, type x as RowOp, type y as RpcEnvelope, type z as RpcResponseBody, type E as ScheduleRecord, type H as SchedulerPoolStatus, type I as SchedulerStatus, type J as ServerMessage, type K as ServerPokeEndMessage, type N as ServerPokePartMessage, type T as ServerPokeStartMessage, type V as ShardTrafficEntry, type W as ShardTrafficResult, type X as StorageListPage, type Y as StorageObject, type Z as StreamHandle, type _ as StreamIterable, type $ as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a0 as SubscriptionRegistry, type a1 as SubscriptionState, type a2 as SyncWatermark, type a as Unsubscribe, type U as User, type a3 as WorkflowInstanceAction, type a4 as WorkflowInstanceDetail, type a5 as WorkflowInstancePage, type a6 as WorkflowInstanceStatus, type a7 as WorkflowInstanceSummary, type a8 as WorkflowStepDetail, a9 as createLocalStore, aa as createStream } from "./packem_shared/lunora-client.d-CtSRWJJ7.mjs";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-GjXaOwY9.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-DPLSlPiP.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-DPLSlPiP.mjs";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-Bpi7xweC.mjs";
4
4
  export type { AuthCapabilities, AuthImpersonation, AuthPage, AuthSession, AuthUser, 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 —
@@ -95,17 +95,6 @@ declare const isMutationDelta: (value: unknown) => value is MutationDelta;
95
95
  * when an `insert`/`update` delta carries no `row` to splice in.
96
96
  */
97
97
  declare const applyDelta: (current: unknown, delta: MutationDelta) => undefined | unknown[];
98
- /** Error code the server uses for optimistic-concurrency conflicts (HTTP 409). */
99
- declare const CONFLICT_ERROR_CODE = "CONFLICT";
100
- /**
101
- * Whether an unknown rejection is an optimistic-concurrency conflict — the
102
- * server lost a write race and the caller should refetch and retry (or surface
103
- * the conflict). Structural check on the `code` property the client attaches
104
- * when decoding the worker's `{ error: { code, message } }` envelope.
105
- */
106
- declare const isConflictError: (error: unknown) => error is Error & {
107
- code: "CONFLICT";
108
- };
109
98
  /** The single transport method a mutation runner needs — narrowed so adapters can test against a stub. */
110
99
  interface MutationCapableClient<F extends FunctionReference> {
111
100
  mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
@@ -409,4 +398,4 @@ interface ReconnectCalculator {
409
398
  reset: () => void;
410
399
  }
411
400
  declare const createReconnect: (options?: ReconnectOptions, random?: () => number) => ReconnectCalculator;
412
- export { type ArgsOf, type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, CONFLICT_ERROR_CODE, type FunctionReference, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, type MutationCallOptions, type MutationDelta, type MutationRunnerSinks, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, type ReconnectCalculator, type ReconnectOptions, type ReturnOf, applyDelta, createAsyncStoragePersistence, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutationRunner, createMutatorRunner, createReconnect, isConflictError, isMutationDelta, queryCacheKey };
401
+ export { type ArgsOf, type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, type FunctionReference, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, type MutationCallOptions, type MutationDelta, type MutationRunnerSinks, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, type ReconnectCalculator, type ReconnectOptions, type ReturnOf, applyDelta, createAsyncStoragePersistence, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutationRunner, createMutatorRunner, createReconnect, isMutationDelta, queryCacheKey };
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-CtSRWJJ7.js";
2
- export { type e as BatchSlot, type C as CachedQuery, type f as ClientMessage, type g as ClientShapeSubscribeMessage, type h as ClientShapeUnsubscribeMessage, type i as ConnectionStatus, D as DEFAULT_MAX_BUFFER, type j as FunctionArgumentDescriptor, type k as FunctionDescriptor, type G as GlobalFacetResult, type l as GlobalFacetValue, type m as GlobalFilterClause, type n as GlobalTableInfo, type o as GlobalTablePage, L as LunoraClient, type p as LunoraClientError, type q as LunoraClientOptions, type r as MutationSettledEvent, type s as OptimisticLocalStore, type t as OptimisticUpdate, type u as OutboxMutation, type v as OutboxSink, type w as PersistedMutation, type P as Preloaded, type x as RowOp, type y as RpcEnvelope, type z as RpcResponseBody, type E as ScheduleRecord, type H as SchedulerPoolStatus, type I as SchedulerStatus, type J as ServerMessage, type K as ServerPokeEndMessage, type N as ServerPokePartMessage, type T as ServerPokeStartMessage, type V as ShardTrafficEntry, type W as ShardTrafficResult, type X as StorageListPage, type Y as StorageObject, type Z as StreamHandle, type _ as StreamIterable, type $ as SubscriptionCallback, type S as SubscriptionError, type b as SubscriptionErrorCallback, a0 as SubscriptionRegistry, type a1 as SubscriptionState, type a2 as SyncWatermark, type a as Unsubscribe, type U as User, type a3 as WorkflowInstanceAction, type a4 as WorkflowInstanceDetail, type a5 as WorkflowInstancePage, type a6 as WorkflowInstanceStatus, type a7 as WorkflowInstanceSummary, type a8 as WorkflowStepDetail, a9 as createLocalStore, aa as createStream } from "./packem_shared/lunora-client.d-CtSRWJJ7.js";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-NMFbch9j.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-DPLSlPiP.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-DPLSlPiP.js";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "./packem_shared/preload.d-CmFdZFQi.js";
4
4
  export type { AuthCapabilities, AuthImpersonation, AuthPage, AuthSession, AuthUser, 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 —
@@ -95,17 +95,6 @@ declare const isMutationDelta: (value: unknown) => value is MutationDelta;
95
95
  * when an `insert`/`update` delta carries no `row` to splice in.
96
96
  */
97
97
  declare const applyDelta: (current: unknown, delta: MutationDelta) => undefined | unknown[];
98
- /** Error code the server uses for optimistic-concurrency conflicts (HTTP 409). */
99
- declare const CONFLICT_ERROR_CODE = "CONFLICT";
100
- /**
101
- * Whether an unknown rejection is an optimistic-concurrency conflict — the
102
- * server lost a write race and the caller should refetch and retry (or surface
103
- * the conflict). Structural check on the `code` property the client attaches
104
- * when decoding the worker's `{ error: { code, message } }` envelope.
105
- */
106
- declare const isConflictError: (error: unknown) => error is Error & {
107
- code: "CONFLICT";
108
- };
109
98
  /** The single transport method a mutation runner needs — narrowed so adapters can test against a stub. */
110
99
  interface MutationCapableClient<F extends FunctionReference> {
111
100
  mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
@@ -409,4 +398,4 @@ interface ReconnectCalculator {
409
398
  reset: () => void;
410
399
  }
411
400
  declare const createReconnect: (options?: ReconnectOptions, random?: () => number) => ReconnectCalculator;
412
- export { type ArgsOf, type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, CONFLICT_ERROR_CODE, type FunctionReference, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, type MutationCallOptions, type MutationDelta, type MutationRunnerSinks, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, type ReconnectCalculator, type ReconnectOptions, type ReturnOf, applyDelta, createAsyncStoragePersistence, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutationRunner, createMutatorRunner, createReconnect, isConflictError, isMutationDelta, queryCacheKey };
401
+ export { type ArgsOf, type AsyncStorageLike, type AsyncStoragePersistenceOptions, type BookmarkStorage, type FunctionReference, type IndexedDbPersistenceOptions, type IndexedDbQueryCacheOptions, type MutationCallOptions, type MutationDelta, type MutationRunnerSinks, type MutatorHandle, type MutatorRunnerSinks, type MutatorTransaction, OfflineQueue, type OfflineQueueOptions, type PersistenceAdapter, type QueryCacheAdapter, type QueuedMutation, type ReconnectCalculator, type ReconnectOptions, type ReturnOf, applyDelta, createAsyncStoragePersistence, createInMemoryBookmarkStorage, createInMemoryPersistence, createInMemoryQueryCache, createIndexedDbPersistence, createIndexedDbQueryCache, createMutationRunner, createMutatorRunner, createReconnect, isMutationDelta, queryCacheKey };
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
3
  export { applyDelta, isMutationDelta } from './packem_shared/applyDelta-4jFGTPA3.mjs';
4
- export { CONFLICT_ERROR_CODE, isConflictError } from './packem_shared/CONFLICT_ERROR_CODE-aUdVbEDw.mjs';
4
+ export { CONFLICT_ERROR_CODE, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from './packem_shared/CONFLICT_ERROR_CODE-B8gQ8tyU.mjs';
5
5
  export { c as createLocalStore } from './packem_shared/local-store-BNgN3Dw3.mjs';
6
- export { LunoraClient } from './packem_shared/LunoraClient-ClBd8JUG.mjs';
6
+ export { LunoraClient } from './packem_shared/LunoraClient-jOfAmV8f.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-CY6F0ZvQ.mjs';
10
+ export { createInMemoryPersistence, createIndexedDbPersistence } from './packem_shared/createInMemoryPersistence-Ds7z8n8d.mjs';
11
11
  export { preloadQuery, preloadedQueryResult } from './packem_shared/preloadQuery-lobFkD2Z.mjs';
12
- export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey } from './packem_shared/createInMemoryQueryCache-Bv4Ruv6n.mjs';
12
+ export { createInMemoryQueryCache, createIndexedDbQueryCache, queryCacheKey } from './packem_shared/createInMemoryQueryCache-iWtKPrid.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-BDkqO5PW.mjs';
15
15
  export { S as SubscriptionRegistry } from './packem_shared/subscription-DoyO04-2.mjs';
@@ -0,0 +1,33 @@
1
+ const LUNORA_ERROR_CODES = [
2
+ "BAD_REQUEST",
3
+ "CONFLICT",
4
+ "COUNT_RLS_UNSUPPORTED",
5
+ "FORBIDDEN",
6
+ "INTERNAL_SERVER_ERROR",
7
+ "MASK_UNSUPPORTED",
8
+ "NOT_FOUND",
9
+ "NOT_IMPLEMENTED",
10
+ "RELATION_PREDICATE_UNSUPPORTED",
11
+ "TOO_MANY_REQUESTS",
12
+ "UNAUTHORIZED",
13
+ "UNPROCESSABLE"
14
+ ];
15
+ const KNOWN_ERROR_CODES = new Set(LUNORA_ERROR_CODES);
16
+ const CONFLICT_ERROR_CODE = "CONFLICT";
17
+ const isConflictError = (error) => error instanceof Error && error.code === CONFLICT_ERROR_CODE;
18
+ const isForbiddenError = (error) => error instanceof Error && error.code === "FORBIDDEN";
19
+ const isUnauthorizedError = (error) => error instanceof Error && error.code === "UNAUTHORIZED";
20
+ const isRateLimitedError = (error) => error instanceof Error && error.code === "TOO_MANY_REQUESTS";
21
+ const getErrorCode = (error) => {
22
+ if (!(error instanceof Error)) {
23
+ return void 0;
24
+ }
25
+ const { code } = error;
26
+ return typeof code === "string" && KNOWN_ERROR_CODES.has(code) ? code : void 0;
27
+ };
28
+ const getRetryAfterMs = (error) => {
29
+ const value = error?.data?.retryAfterMs;
30
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
31
+ };
32
+
33
+ export { CONFLICT_ERROR_CODE, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError };
@@ -1,10 +1,11 @@
1
+ import { LunoraError } from '@lunora/errors';
1
2
  import { S as SubscriptionRegistry, s as stableStringify } from './subscription-DoyO04-2.mjs';
2
3
  import createInMemoryBookmarkStorage from './createInMemoryBookmarkStorage-BoN7a7TH.mjs';
3
4
  import { isMutationDelta, applyDelta } from './applyDelta-4jFGTPA3.mjs';
4
5
  import { a as applyOptimisticLayer, d as dropConfirmedLayers, n as notifySubscription, f as foldOptimistic, c as createLocalStore } from './local-store-BNgN3Dw3.mjs';
5
6
  import { O as OfflineQueue, n as nextId, i as isStaleVersion, r as reportPersistenceError } from './offline-queue-B9vfdSqp.mjs';
6
- import { resolvePersistenceAdapter } from './createInMemoryPersistence-CY6F0ZvQ.mjs';
7
- import { resolveQueryCacheAdapter, queryCacheKey } from './createInMemoryQueryCache-Bv4Ruv6n.mjs';
7
+ import { resolvePersistenceAdapter } from './createInMemoryPersistence-Ds7z8n8d.mjs';
8
+ import { resolveQueryCacheAdapter, queryCacheKey } from './createInMemoryQueryCache-iWtKPrid.mjs';
8
9
  import { createReconnect } from './createReconnect-Di_-oHH7.mjs';
9
10
  import { createStream } from './DEFAULT_MAX_BUFFER-BDkqO5PW.mjs';
10
11
 
@@ -182,7 +183,14 @@ const decodeWire = (value, depth = 0) => {
182
183
  if (error.name !== name) {
183
184
  Object.defineProperty(error, "name", { configurable: true, value: name, writable: true });
184
185
  }
185
- Object.assign(error, decodeWire(value[4], depth + 1));
186
+ const props = decodeWire(value[4], depth + 1);
187
+ for (const key of Object.keys(props)) {
188
+ if (key === UNSAFE_KEY) {
189
+ Object.defineProperty(error, key, { configurable: true, enumerable: true, value: props[key], writable: true });
190
+ } else {
191
+ error[key] = props[key];
192
+ }
193
+ }
186
194
  if (value.length > 5) {
187
195
  Object.defineProperty(error, "cause", { configurable: true, value: decodeWire(value[5], depth + 1), writable: true });
188
196
  }
@@ -399,6 +407,12 @@ const reconstructError = (errorBody) => {
399
407
  if (errorBody.data !== void 0) {
400
408
  error.data = decodeWire(errorBody.data);
401
409
  }
410
+ if (errorBody.hint !== void 0) {
411
+ error.hint = errorBody.hint;
412
+ }
413
+ if (errorBody.docsUrl !== void 0) {
414
+ error.docsUrl = errorBody.docsUrl;
415
+ }
402
416
  return error;
403
417
  };
404
418
  const encodeCallArgs = (payload, label) => {
@@ -685,7 +699,7 @@ class LunoraClient {
685
699
  async callMutator(functionPath, args, options) {
686
700
  const clientSeq = options?.clientSeq;
687
701
  if (clientSeq !== void 0 && (!Number.isInteger(clientSeq) || clientSeq <= 0)) {
688
- throw new Error(`callMutator: clientSeq must be a positive integer, got ${String(clientSeq)}`);
702
+ throw new LunoraError("INTERNAL", `callMutator: clientSeq must be a positive integer, got ${String(clientSeq)}`);
689
703
  }
690
704
  const bucket = options?.shardKey ?? "";
691
705
  let ackWatermark;
@@ -969,7 +983,7 @@ class LunoraClient {
969
983
  // --- RPC ---------------------------------------------------------------
970
984
  async query(function_, args, options = {}) {
971
985
  if (this.closed) {
972
- throw new Error("LunoraClient is closed");
986
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
973
987
  }
974
988
  return await this.rpc(function_.__lunoraRef, args, options.shardKey, { attachBookmark: true });
975
989
  }
@@ -989,10 +1003,10 @@ class LunoraClient {
989
1003
  */
990
1004
  async batch(calls) {
991
1005
  if (this.closed) {
992
- throw new Error("LunoraClient is closed");
1006
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
993
1007
  }
994
1008
  if (!this.fetchImpl) {
995
- throw new Error("LunoraClient: no `fetch` implementation available");
1009
+ throw new LunoraError("INTERNAL", "LunoraClient: no `fetch` implementation available");
996
1010
  }
997
1011
  if (calls.length === 0) {
998
1012
  return [];
@@ -1019,13 +1033,13 @@ class LunoraClient {
1019
1033
  try {
1020
1034
  body = await response.json();
1021
1035
  } catch {
1022
- throw new Error(`LunoraClient: batch response was not JSON (status ${response.status.toString()})`);
1036
+ throw new LunoraError("INTERNAL", `LunoraClient: batch response was not JSON (status ${response.status.toString()})`);
1023
1037
  }
1024
1038
  if (!response.ok || body.error && !body.results) {
1025
1039
  if (body.error) {
1026
1040
  throw reconstructError(body.error);
1027
1041
  }
1028
- throw new Error(`LunoraClient: batch request failed (status ${response.status.toString()})`);
1042
+ throw new LunoraError("INTERNAL", `LunoraClient: batch request failed (status ${response.status.toString()})`);
1029
1043
  }
1030
1044
  return demuxBatchResults(body.results ?? [], calls.length);
1031
1045
  }
@@ -1041,7 +1055,7 @@ class LunoraClient {
1041
1055
  */
1042
1056
  async mutation(function_, args, options = {}) {
1043
1057
  if (this.closed) {
1044
- throw new Error("LunoraClient is closed");
1058
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1045
1059
  }
1046
1060
  const argsRecord = args;
1047
1061
  const mutationId = options.mutationId ?? nextId();
@@ -1085,7 +1099,7 @@ class LunoraClient {
1085
1099
  }
1086
1100
  async action(function_, args, options = {}) {
1087
1101
  if (this.closed) {
1088
- throw new Error("LunoraClient is closed");
1102
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1089
1103
  }
1090
1104
  return await this.rpc(function_.__lunoraRef, args, options.shardKey);
1091
1105
  }
@@ -1102,7 +1116,7 @@ class LunoraClient {
1102
1116
  */
1103
1117
  async shardTraffic(table) {
1104
1118
  if (this.closed) {
1105
- throw new Error("LunoraClient is closed");
1119
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1106
1120
  }
1107
1121
  const body = await this.adminFetch(SHARD_TRAFFIC_PATH, "POST", { table });
1108
1122
  return { failed: body.failed ?? 0, ok: body.ok ?? 0, shards: body.shards ?? [] };
@@ -1117,7 +1131,7 @@ class LunoraClient {
1117
1131
  */
1118
1132
  async listScheduledJobs() {
1119
1133
  if (this.closed) {
1120
- throw new Error("LunoraClient is closed");
1134
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1121
1135
  }
1122
1136
  const body = await this.adminFetch(SCHEDULED_PATH, "GET");
1123
1137
  return body.records ?? [];
@@ -1133,7 +1147,7 @@ class LunoraClient {
1133
1147
  */
1134
1148
  async schedulerStatus() {
1135
1149
  if (this.closed) {
1136
- throw new Error("LunoraClient is closed");
1150
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1137
1151
  }
1138
1152
  const body = await this.adminFetch(SCHEDULED_STATUS_PATH, "GET");
1139
1153
  return {
@@ -1145,7 +1159,7 @@ class LunoraClient {
1145
1159
  /** Cancel a pending scheduled job by id. Returns whether a job was removed. */
1146
1160
  async cancelScheduledJob(id) {
1147
1161
  if (this.closed) {
1148
- throw new Error("LunoraClient is closed");
1162
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1149
1163
  }
1150
1164
  const body = await this.adminFetch(SCHEDULED_CANCEL_PATH, "POST", { id });
1151
1165
  return { cancelled: body.cancelled === true };
@@ -1160,7 +1174,7 @@ class LunoraClient {
1160
1174
  */
1161
1175
  async listDeadJobs() {
1162
1176
  if (this.closed) {
1163
- throw new Error("LunoraClient is closed");
1177
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1164
1178
  }
1165
1179
  const body = await this.adminFetch(SCHEDULED_DEAD_PATH, "GET");
1166
1180
  return body.records ?? [];
@@ -1172,7 +1186,7 @@ class LunoraClient {
1172
1186
  */
1173
1187
  async retryDeadJob(id) {
1174
1188
  if (this.closed) {
1175
- throw new Error("LunoraClient is closed");
1189
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1176
1190
  }
1177
1191
  const body = await this.adminFetch(SCHEDULED_DEAD_RETRY_PATH, "POST", { id });
1178
1192
  return { retried: body.retried === true };
@@ -1184,7 +1198,7 @@ class LunoraClient {
1184
1198
  */
1185
1199
  async removeDeadJob(id) {
1186
1200
  if (this.closed) {
1187
- throw new Error("LunoraClient is closed");
1201
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1188
1202
  }
1189
1203
  const body = await this.adminFetch(SCHEDULED_DEAD_CANCEL_PATH, "POST", { id });
1190
1204
  return { removed: body.removed === true };
@@ -1202,7 +1216,7 @@ class LunoraClient {
1202
1216
  */
1203
1217
  async listWorkflowInstances(options) {
1204
1218
  if (this.closed) {
1205
- throw new Error("LunoraClient is closed");
1219
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1206
1220
  }
1207
1221
  const query = new URLSearchParams({ name: options.name });
1208
1222
  if (options.status !== void 0) {
@@ -1226,7 +1240,7 @@ class LunoraClient {
1226
1240
  /** Read one workflow instance with its step timeline (`/_lunora/admin/workflows/instance`). */
1227
1241
  async getWorkflowInstance(options) {
1228
1242
  if (this.closed) {
1229
- throw new Error("LunoraClient is closed");
1243
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1230
1244
  }
1231
1245
  const query = new URLSearchParams({ id: options.id, name: options.name });
1232
1246
  const body = await this.adminFetch(`${WORKFLOWS_INSTANCE_PATH}?${query.toString()}`, "GET");
@@ -1245,7 +1259,7 @@ class LunoraClient {
1245
1259
  /** Pause / resume / terminate a workflow instance (`/_lunora/admin/workflows/status`). Needs an Edit-scoped Cloudflare token. */
1246
1260
  async setWorkflowInstanceStatus(options) {
1247
1261
  if (this.closed) {
1248
- throw new Error("LunoraClient is closed");
1262
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1249
1263
  }
1250
1264
  const body = await this.adminFetch(WORKFLOWS_STATUS_PATH, "POST", { action: options.action, id: options.id, name: options.name });
1251
1265
  return { status: body.status ?? "unknown" };
@@ -1260,7 +1274,7 @@ class LunoraClient {
1260
1274
  */
1261
1275
  subscribeScheduledJobs(onJobs) {
1262
1276
  if (this.closed) {
1263
- throw new Error("LunoraClient is closed");
1277
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1264
1278
  }
1265
1279
  if (this.WebSocketImpl === void 0) {
1266
1280
  return () => void 0;
@@ -1316,7 +1330,7 @@ class LunoraClient {
1316
1330
  */
1317
1331
  async listFunctions() {
1318
1332
  if (this.closed) {
1319
- throw new Error("LunoraClient is closed");
1333
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1320
1334
  }
1321
1335
  const body = await this.adminFetch(FUNCTIONS_PATH, "GET");
1322
1336
  return body.functions ?? [];
@@ -1332,7 +1346,7 @@ class LunoraClient {
1332
1346
  */
1333
1347
  async getCronJobs() {
1334
1348
  if (this.closed) {
1335
- throw new Error("LunoraClient is closed");
1349
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1336
1350
  }
1337
1351
  const body = await this.adminFetch(CRON_JOBS_PATH, "GET");
1338
1352
  return body.jobs ?? [];
@@ -1348,7 +1362,7 @@ class LunoraClient {
1348
1362
  */
1349
1363
  async runCronJob(name) {
1350
1364
  if (this.closed) {
1351
- throw new Error("LunoraClient is closed");
1365
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1352
1366
  }
1353
1367
  const body = await this.adminFetch(CRON_JOBS_RUN_PATH, "POST", { name });
1354
1368
  return { name: body.name ?? name, ran: body.ran === true };
@@ -1363,7 +1377,7 @@ class LunoraClient {
1363
1377
  */
1364
1378
  async fetchOpenApi() {
1365
1379
  if (this.closed) {
1366
- throw new Error("LunoraClient is closed");
1380
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1367
1381
  }
1368
1382
  return await this.adminFetch(OPENAPI_PATH, "GET");
1369
1383
  }
@@ -1379,7 +1393,7 @@ class LunoraClient {
1379
1393
  */
1380
1394
  async fetchOpenRpc() {
1381
1395
  if (this.closed) {
1382
- throw new Error("LunoraClient is closed");
1396
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1383
1397
  }
1384
1398
  return await this.adminFetch(OPENRPC_PATH, "GET");
1385
1399
  }
@@ -1393,7 +1407,7 @@ class LunoraClient {
1393
1407
  */
1394
1408
  async listStorageObjects(options = {}) {
1395
1409
  if (this.closed) {
1396
- throw new Error("LunoraClient is closed");
1410
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1397
1411
  }
1398
1412
  const params = new URLSearchParams();
1399
1413
  if (options.prefix !== void 0 && options.prefix !== "") {
@@ -1421,7 +1435,7 @@ class LunoraClient {
1421
1435
  */
1422
1436
  async deleteStorageObject(key, options) {
1423
1437
  if (this.closed) {
1424
- throw new Error("LunoraClient is closed");
1438
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1425
1439
  }
1426
1440
  const path = `${STORAGE_PATH}?key=${encodeURIComponent(key)}${bucketQuery(options?.bucket)}`;
1427
1441
  const body = await this.adminFetch(path, "DELETE");
@@ -1435,7 +1449,7 @@ class LunoraClient {
1435
1449
  */
1436
1450
  async listStorageBuckets() {
1437
1451
  if (this.closed) {
1438
- throw new Error("LunoraClient is closed");
1452
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1439
1453
  }
1440
1454
  const body = await this.adminFetch(STORAGE_BUCKETS_PATH, "GET");
1441
1455
  return body.buckets ?? [];
@@ -1449,7 +1463,7 @@ class LunoraClient {
1449
1463
  */
1450
1464
  async uploadStorageObject(options) {
1451
1465
  if (this.closed) {
1452
- throw new Error("LunoraClient is closed");
1466
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1453
1467
  }
1454
1468
  const path = `${STORAGE_PATH}?key=${encodeURIComponent(options.key)}${bucketQuery(options.bucket)}`;
1455
1469
  const body = await this.adminFetch(path, "PUT", options.body, options.contentType);
@@ -1468,7 +1482,7 @@ class LunoraClient {
1468
1482
  */
1469
1483
  async signedStorageUrl(key, options) {
1470
1484
  if (this.closed) {
1471
- throw new Error("LunoraClient is closed");
1485
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1472
1486
  }
1473
1487
  const expiresInSeconds = options?.expiresInSeconds;
1474
1488
  const expiryQuery = expiresInSeconds === void 0 ? "" : `&expiresIn=${encodeURIComponent(expiresInSeconds.toString())}`;
@@ -1488,7 +1502,7 @@ class LunoraClient {
1488
1502
  */
1489
1503
  async listGlobalTables() {
1490
1504
  if (this.closed) {
1491
- throw new Error("LunoraClient is closed");
1505
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1492
1506
  }
1493
1507
  return await this.adminFetch(GLOBAL_TABLES_PATH, "GET");
1494
1508
  }
@@ -1500,7 +1514,7 @@ class LunoraClient {
1500
1514
  */
1501
1515
  async readGlobalTablePage(options) {
1502
1516
  if (this.closed) {
1503
- throw new Error("LunoraClient is closed");
1517
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1504
1518
  }
1505
1519
  const params = new URLSearchParams({ table: options.table });
1506
1520
  if (options.limit !== void 0) {
@@ -1523,7 +1537,7 @@ class LunoraClient {
1523
1537
  */
1524
1538
  async facetGlobalColumn(options) {
1525
1539
  if (this.closed) {
1526
- throw new Error("LunoraClient is closed");
1540
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1527
1541
  }
1528
1542
  const params = new URLSearchParams({ column: options.column, table: options.table });
1529
1543
  if (options.limit !== void 0) {
@@ -1546,7 +1560,7 @@ class LunoraClient {
1546
1560
  */
1547
1561
  async listVectorIndexes() {
1548
1562
  if (this.closed) {
1549
- throw new Error("LunoraClient is closed");
1563
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1550
1564
  }
1551
1565
  const body = await this.adminFetch(VECTOR_INDEXES_PATH, "GET");
1552
1566
  return body.indexes ?? [];
@@ -1560,7 +1574,7 @@ class LunoraClient {
1560
1574
  */
1561
1575
  async queryVectorIndex(options) {
1562
1576
  if (this.closed) {
1563
- throw new Error("LunoraClient is closed");
1577
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1564
1578
  }
1565
1579
  const body = await this.adminFetch(VECTOR_QUERY_PATH, "POST", options);
1566
1580
  return body.matches ?? [];
@@ -1574,7 +1588,7 @@ class LunoraClient {
1574
1588
  */
1575
1589
  async listKvNamespaces() {
1576
1590
  if (this.closed) {
1577
- throw new Error("LunoraClient is closed");
1591
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1578
1592
  }
1579
1593
  const body = await this.adminFetch(KV_NAMESPACES_PATH, "GET");
1580
1594
  return body.namespaces ?? [];
@@ -1586,7 +1600,7 @@ class LunoraClient {
1586
1600
  */
1587
1601
  async listKvKeys(options) {
1588
1602
  if (this.closed) {
1589
- throw new Error("LunoraClient is closed");
1603
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1590
1604
  }
1591
1605
  const path = withQuery(KV_KEYS_PATH, {
1592
1606
  cursor: options.cursor,
@@ -1603,7 +1617,7 @@ class LunoraClient {
1603
1617
  */
1604
1618
  async getKvValue(options) {
1605
1619
  if (this.closed) {
1606
- throw new Error("LunoraClient is closed");
1620
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1607
1621
  }
1608
1622
  const path = withQuery(KV_VALUE_PATH, { key: options.key, namespace: options.namespace });
1609
1623
  return await this.adminFetch(path, "GET");
@@ -1616,7 +1630,7 @@ class LunoraClient {
1616
1630
  */
1617
1631
  async putKvValue(options) {
1618
1632
  if (this.closed) {
1619
- throw new Error("LunoraClient is closed");
1633
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1620
1634
  }
1621
1635
  await this.adminFetch(KV_VALUE_PATH, "PUT", options);
1622
1636
  }
@@ -1626,7 +1640,7 @@ class LunoraClient {
1626
1640
  */
1627
1641
  async deleteKvKey(options) {
1628
1642
  if (this.closed) {
1629
- throw new Error("LunoraClient is closed");
1643
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1630
1644
  }
1631
1645
  const path = withQuery(KV_VALUE_PATH, { key: options.key, namespace: options.namespace });
1632
1646
  await this.adminFetch(path, "DELETE");
@@ -1640,7 +1654,7 @@ class LunoraClient {
1640
1654
  */
1641
1655
  async listAuthUsers(options = {}) {
1642
1656
  if (this.closed) {
1643
- throw new Error("LunoraClient is closed");
1657
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1644
1658
  }
1645
1659
  const path = withQuery(AUTH_USERS_PATH, {
1646
1660
  filterField: options.filterField,
@@ -1755,7 +1769,7 @@ class LunoraClient {
1755
1769
  /** List auth sessions, paged and optionally filtered to one user. */
1756
1770
  async listAuthSessions(options = {}) {
1757
1771
  if (this.closed) {
1758
- throw new Error("LunoraClient is closed");
1772
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1759
1773
  }
1760
1774
  const params = new URLSearchParams();
1761
1775
  if (options.userId !== void 0 && options.userId !== "") {
@@ -1773,7 +1787,7 @@ class LunoraClient {
1773
1787
  // --- Subscriptions ------------------------------------------------------
1774
1788
  subscribe(function_, args, callback, options = {}) {
1775
1789
  if (this.closed) {
1776
- throw new Error("LunoraClient is closed");
1790
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1777
1791
  }
1778
1792
  const argsRecord = args ?? {};
1779
1793
  const key = SubscriptionRegistry.key(function_.__lunoraRef, argsRecord, options.shardKey);
@@ -1851,7 +1865,7 @@ class LunoraClient {
1851
1865
  */
1852
1866
  subscribeShape(shape, callback, options = {}) {
1853
1867
  if (this.closed) {
1854
- throw new Error("LunoraClient is closed");
1868
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1855
1869
  }
1856
1870
  this.nextShapeId += 1;
1857
1871
  const id = `shape_${this.nextShapeId.toString()}`;
@@ -1897,10 +1911,10 @@ class LunoraClient {
1897
1911
  */
1898
1912
  stream(function_, args, options = {}) {
1899
1913
  if (this.closed) {
1900
- throw new Error("LunoraClient is closed");
1914
+ throw new LunoraError("INTERNAL", "LunoraClient is closed");
1901
1915
  }
1902
1916
  if (this.WebSocketImpl === void 0) {
1903
- throw new Error("LunoraClient: streams require a WebSocket implementation");
1917
+ throw new LunoraError("INTERNAL", "LunoraClient: streams require a WebSocket implementation");
1904
1918
  }
1905
1919
  this.nextStreamId += 1;
1906
1920
  const id = `stream_${this.nextStreamId.toString()}`;
@@ -2350,7 +2364,7 @@ class LunoraClient {
2350
2364
  }
2351
2365
  async rpc(functionPath, args, shardKey, flags = {}) {
2352
2366
  if (!this.fetchImpl) {
2353
- throw new Error("LunoraClient: no `fetch` implementation available");
2367
+ throw new LunoraError("INTERNAL", "LunoraClient: no `fetch` implementation available");
2354
2368
  }
2355
2369
  const headers = this.rpcRequestHeaders(flags);
2356
2370
  const response = await this.fetchImpl(joinUrl(this.url, RPC_PATH), {
@@ -2372,14 +2386,14 @@ class LunoraClient {
2372
2386
  body = await response.json();
2373
2387
  } catch {
2374
2388
  const statusText = response.statusText ? ` ${response.statusText}` : "";
2375
- throw new Error(`LunoraClient: response was not JSON (status ${response.status.toString()}${statusText})`);
2389
+ throw new LunoraError("INTERNAL", `LunoraClient: response was not JSON (status ${response.status.toString()}${statusText})`);
2376
2390
  }
2377
2391
  if ("error" in body) {
2378
2392
  throw reconstructError(body.error);
2379
2393
  }
2380
2394
  if (!response.ok) {
2381
2395
  const statusText = response.statusText ? ` ${response.statusText}` : "";
2382
- throw new Error(`LunoraClient: request failed (status ${response.status.toString()}${statusText})`);
2396
+ throw new LunoraError("INTERNAL", `LunoraClient: request failed (status ${response.status.toString()}${statusText})`);
2383
2397
  }
2384
2398
  flags.onMutationAck?.(body.lastMutationId);
2385
2399
  flags.onCommitCursor?.(body.commitCursor);
@@ -2393,7 +2407,7 @@ class LunoraClient {
2393
2407
  */
2394
2408
  async adminFetch(path, method, payload, contentType) {
2395
2409
  if (!this.fetchImpl) {
2396
- throw new Error("LunoraClient: no `fetch` implementation available");
2410
+ throw new LunoraError("INTERNAL", "LunoraClient: no `fetch` implementation available");
2397
2411
  }
2398
2412
  const headers = {};
2399
2413
  if (this.authToken) {
@@ -2422,7 +2436,7 @@ class LunoraClient {
2422
2436
  body = await response.json();
2423
2437
  } catch {
2424
2438
  const statusText = response.statusText ? ` ${response.statusText}` : "";
2425
- throw new Error(`LunoraClient: response was not JSON (status ${response.status.toString()}${statusText})`);
2439
+ throw new LunoraError("INTERNAL", `LunoraClient: response was not JSON (status ${response.status.toString()}${statusText})`);
2426
2440
  }
2427
2441
  if (typeof body === "object" && body !== null && "error" in body) {
2428
2442
  const envelope = body.error;
@@ -2432,7 +2446,7 @@ class LunoraClient {
2432
2446
  }
2433
2447
  if (!response.ok) {
2434
2448
  const statusText = response.statusText ? ` ${response.statusText}` : "";
2435
- throw new Error(`LunoraClient: admin request failed (status ${response.status.toString()}${statusText})`);
2449
+ throw new LunoraError("INTERNAL", `LunoraClient: admin request failed (status ${response.status.toString()}${statusText})`);
2436
2450
  }
2437
2451
  return body;
2438
2452
  }
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const createInMemoryPersistence = () => {
2
4
  const entries = /* @__PURE__ */ new Map();
3
5
  const clone = (mutation) => {
@@ -39,7 +41,7 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
39
41
  const createIndexedDbPersistence = (options = {}) => {
40
42
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
41
43
  if (!factory) {
42
- throw new Error("createIndexedDbPersistence: no IndexedDB available — pass `indexedDB` or use createInMemoryPersistence()");
44
+ throw new LunoraError("INTERNAL", "createIndexedDbPersistence: no IndexedDB available — pass `indexedDB` or use createInMemoryPersistence()");
43
45
  }
44
46
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
45
47
  const storeName = options.storeName ?? DEFAULT_STORE;
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const queryCacheKey = (functionPath, argsKey, shardKey) => `${functionPath}::${argsKey}::${shardKey ?? ""}`;
2
4
  const DEFAULT_MAX_ENTRIES = 500;
3
5
  const createInMemoryQueryCache = (options = {}) => {
@@ -50,7 +52,7 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
50
52
  const createIndexedDbQueryCache = (options = {}) => {
51
53
  const factory = options.indexedDB ?? (typeof indexedDB === "undefined" ? void 0 : indexedDB);
52
54
  if (!factory) {
53
- throw new Error("createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
55
+ throw new LunoraError("INTERNAL", "createIndexedDbQueryCache: no IndexedDB available — pass `indexedDB` or use createInMemoryQueryCache()");
54
56
  }
55
57
  const databaseName = options.databaseName ?? DEFAULT_DATABASE;
56
58
  const storeName = options.storeName ?? DEFAULT_STORE;
@@ -1,4 +1,4 @@
1
- import { LunoraClient } from './LunoraClient-ClBd8JUG.mjs';
1
+ import { LunoraClient } from './LunoraClient-jOfAmV8f.mjs';
2
2
 
3
3
  const createServerClient = (options) => {
4
4
  const client = new LunoraClient({ fetch: options.fetch, url: options.url });
@@ -1,4 +1,59 @@
1
1
  import { CronJobInfo, VectorIndexSummary, VectorQueryMatch, KvNamespaceSummary, KvKeyListResult, KvValueResult, AuthUser, AuthPage, AuthImpersonation, AuthCapabilities, AuthSession } from '@lunora/runtime';
2
+ /**
3
+ * The machine-readable error codes a client can observe on a failed
4
+ * RPC/batch/subscription. Mirrors the server's `CODE_STATUS` keys
5
+ * (`@lunora/server`'s `error.ts`) by hand — the client is framework-neutral and
6
+ * must never import the server package (wrong dependency direction / would pull
7
+ * the server into the browser bundle). Keep this list in sync when a server code
8
+ * is added or removed (see the drift-guard note in the plan/maintenance docs).
9
+ */
10
+ declare const LUNORA_ERROR_CODES: readonly ["BAD_REQUEST", "CONFLICT", "COUNT_RLS_UNSUPPORTED", "FORBIDDEN", "INTERNAL_SERVER_ERROR", "MASK_UNSUPPORTED", "NOT_FOUND", "NOT_IMPLEMENTED", "RELATION_PREDICATE_UNSUPPORTED", "TOO_MANY_REQUESTS", "UNAUTHORIZED", "UNPROCESSABLE"];
11
+ /** A machine-readable error `code` the client may observe. Mirror of the server's `LunoraErrorCode`. */
12
+ type LunoraErrorCode = (typeof LUNORA_ERROR_CODES)[number];
13
+ /** Error code the server uses for optimistic-concurrency conflicts (HTTP 409). */
14
+ declare const CONFLICT_ERROR_CODE = "CONFLICT";
15
+ /**
16
+ * Whether an unknown rejection is an optimistic-concurrency conflict — the
17
+ * server lost a write race and the caller should refetch and retry (or surface
18
+ * the conflict). Structural check on the `code` property the client attaches
19
+ * when decoding the worker's `{ error: { code, message } }` envelope.
20
+ */
21
+ declare const isConflictError: (error: unknown) => error is Error & {
22
+ code: "CONFLICT";
23
+ };
24
+ /**
25
+ * Whether a rejection is an RLS/policy denial (`FORBIDDEN`, HTTP 403) — the
26
+ * caller is authenticated but not permitted to read/write the row. The most
27
+ * common per-call error a UI must handle in an RLS-first app.
28
+ */
29
+ declare const isForbiddenError: (error: unknown) => error is Error & {
30
+ code: "FORBIDDEN";
31
+ };
32
+ /** Whether a rejection is an authentication failure (`UNAUTHORIZED`, HTTP 401) — no/invalid identity. */
33
+ declare const isUnauthorizedError: (error: unknown) => error is Error & {
34
+ code: "UNAUTHORIZED";
35
+ };
36
+ /**
37
+ * Whether a rejection is a rate-limit denial (`TOO_MANY_REQUESTS`, HTTP 429).
38
+ * The retry hint (if the server sent one) is read with {@link getRetryAfterMs}.
39
+ */
40
+ declare const isRateLimitedError: (error: unknown) => error is Error & {
41
+ code: "TOO_MANY_REQUESTS";
42
+ };
43
+ /**
44
+ * Read the server's machine-readable `code` off a rejection, narrowed to the
45
+ * known {@link LunoraErrorCode} union. Returns `undefined` for a non-`Error`, a
46
+ * missing code, or an unrecognized code string (forward-compat server codes read
47
+ * as `undefined` here rather than being falsely narrowed).
48
+ */
49
+ declare const getErrorCode: (error: unknown) => LunoraErrorCode | undefined;
50
+ /**
51
+ * Read the rate-limit retry hint (`data.retryAfterMs`) off a
52
+ * `TOO_MANY_REQUESTS` rejection without hand-casting the `unknown` `data`
53
+ * payload. Returns the finite millisecond value the server sent, or `undefined`
54
+ * when absent/non-numeric. Pair with {@link isRateLimitedError}.
55
+ */
56
+ declare const getRetryAfterMs: (error: unknown) => number | undefined;
2
57
  /** The registered function kinds a {@link FunctionReference} can describe. `stream` is a query that yields multiple frames over the WS. */
3
58
  type FunctionKind = "action" | "mutation" | "query" | "stream";
4
59
  /**
@@ -1152,10 +1207,20 @@ interface SyncWatermark {
1152
1207
  checkpoint?: number;
1153
1208
  mutationId?: number;
1154
1209
  }
1155
- /** An `Error` carrying the server's machine-readable `code` and (for a `LunoraError`) structured `data`. The client's public error contract for RPC/batch failures. */
1210
+ /**
1211
+ * An `Error` carrying the server's machine-readable `code` and (for a
1212
+ * `LunoraError`) structured `data`, plus an optional actionable `hint` (Markdown)
1213
+ * and `docsUrl` resolved from the central error catalog. The client's public
1214
+ * error contract for RPC/batch failures — a UI can render `hint`/`docsUrl` to
1215
+ * tell the user how to fix the error. The `(string & {})` arm keeps
1216
+ * forward-compat/unknown server codes assignable without losing autocomplete on
1217
+ * the known {@link LunoraErrorCode} union.
1218
+ */
1156
1219
  type LunoraClientError = Error & {
1157
- code?: string;
1220
+ code?: LunoraErrorCode | (string & {});
1158
1221
  data?: unknown;
1222
+ docsUrl?: string;
1223
+ hint?: string | string[];
1159
1224
  };
1160
1225
  /** One demuxed result slot of a {@link LunoraClient.batch} call (plan 088). */
1161
1226
  type BatchSlot = {
@@ -2357,4 +2422,4 @@ declare class LunoraClient {
2357
2422
  */
2358
2423
  private settleReplayBatchSlots;
2359
2424
  }
2360
- export { SubscriptionCallback as $, ArgsOf as A, BookmarkStorage as B, CachedQuery as C, DEFAULT_MAX_BUFFER as D, ScheduleRecord as E, FunctionReference as F, GlobalFacetResult as G, SchedulerPoolStatus as H, SchedulerStatus as I, ServerMessage as J, ServerPokeEndMessage as K, LunoraClient as L, MutationCallOptions as M, ServerPokePartMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeStartMessage as T, User as U, ShardTrafficEntry as V, ShardTrafficResult as W, StorageListPage as X, StorageObject as Y, StreamHandle as Z, StreamIterable as _, Unsubscribe as a, SubscriptionRegistry as a0, SubscriptionState as a1, SyncWatermark as a2, WorkflowInstanceAction as a3, WorkflowInstanceDetail as a4, WorkflowInstancePage as a5, WorkflowInstanceStatus as a6, WorkflowInstanceSummary as a7, WorkflowStepDetail as a8, createLocalStore as a9, createStream as aa, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, ClientMessage as f, ClientShapeSubscribeMessage as g, ClientShapeUnsubscribeMessage as h, ConnectionStatus as i, FunctionArgumentDescriptor as j, FunctionDescriptor as k, GlobalFacetValue as l, GlobalFilterClause as m, GlobalTableInfo as n, GlobalTablePage as o, LunoraClientError as p, LunoraClientOptions as q, MutationSettledEvent as r, OptimisticLocalStore as s, OptimisticUpdate as t, OutboxMutation as u, OutboxSink as v, PersistedMutation as w, RowOp as x, RpcEnvelope as y, RpcResponseBody as z };
2425
+ export { StreamHandle as $, ArgsOf as A, BookmarkStorage as B, CONFLICT_ERROR_CODE as C, DEFAULT_MAX_BUFFER as D, RpcEnvelope as E, FunctionReference as F, GlobalFacetResult as G, RpcResponseBody as H, ScheduleRecord as I, SchedulerPoolStatus as J, SchedulerStatus as K, LunoraClient as L, MutationCallOptions as M, ServerMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeEndMessage as T, User as U, ServerPokePartMessage as V, ServerPokeStartMessage as W, ShardTrafficEntry as X, ShardTrafficResult as Y, StorageListPage as Z, StorageObject as _, Unsubscribe as a, StreamIterable as a0, SubscriptionCallback as a1, SubscriptionRegistry as a2, SubscriptionState as a3, SyncWatermark as a4, WorkflowInstanceAction as a5, WorkflowInstanceDetail as a6, WorkflowInstancePage as a7, WorkflowInstanceStatus as a8, WorkflowInstanceSummary as a9, WorkflowStepDetail as aa, createLocalStore as ab, createStream as ac, getErrorCode as ad, getRetryAfterMs as ae, isConflictError as af, isForbiddenError as ag, isRateLimitedError as ah, isUnauthorizedError as ai, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, CachedQuery as f, ClientMessage as g, ClientShapeSubscribeMessage as h, ClientShapeUnsubscribeMessage as i, ConnectionStatus as j, FunctionArgumentDescriptor as k, FunctionDescriptor as l, GlobalFacetValue as m, GlobalFilterClause as n, GlobalTableInfo as o, GlobalTablePage as p, LunoraClientError as q, LunoraClientOptions as r, LunoraErrorCode as s, MutationSettledEvent as t, OptimisticLocalStore as u, OptimisticUpdate as v, OutboxMutation as w, OutboxSink as x, PersistedMutation as y, RowOp as z };
@@ -1,4 +1,59 @@
1
1
  import { CronJobInfo, VectorIndexSummary, VectorQueryMatch, KvNamespaceSummary, KvKeyListResult, KvValueResult, AuthUser, AuthPage, AuthImpersonation, AuthCapabilities, AuthSession } from '@lunora/runtime';
2
+ /**
3
+ * The machine-readable error codes a client can observe on a failed
4
+ * RPC/batch/subscription. Mirrors the server's `CODE_STATUS` keys
5
+ * (`@lunora/server`'s `error.ts`) by hand — the client is framework-neutral and
6
+ * must never import the server package (wrong dependency direction / would pull
7
+ * the server into the browser bundle). Keep this list in sync when a server code
8
+ * is added or removed (see the drift-guard note in the plan/maintenance docs).
9
+ */
10
+ declare const LUNORA_ERROR_CODES: readonly ["BAD_REQUEST", "CONFLICT", "COUNT_RLS_UNSUPPORTED", "FORBIDDEN", "INTERNAL_SERVER_ERROR", "MASK_UNSUPPORTED", "NOT_FOUND", "NOT_IMPLEMENTED", "RELATION_PREDICATE_UNSUPPORTED", "TOO_MANY_REQUESTS", "UNAUTHORIZED", "UNPROCESSABLE"];
11
+ /** A machine-readable error `code` the client may observe. Mirror of the server's `LunoraErrorCode`. */
12
+ type LunoraErrorCode = (typeof LUNORA_ERROR_CODES)[number];
13
+ /** Error code the server uses for optimistic-concurrency conflicts (HTTP 409). */
14
+ declare const CONFLICT_ERROR_CODE = "CONFLICT";
15
+ /**
16
+ * Whether an unknown rejection is an optimistic-concurrency conflict — the
17
+ * server lost a write race and the caller should refetch and retry (or surface
18
+ * the conflict). Structural check on the `code` property the client attaches
19
+ * when decoding the worker's `{ error: { code, message } }` envelope.
20
+ */
21
+ declare const isConflictError: (error: unknown) => error is Error & {
22
+ code: "CONFLICT";
23
+ };
24
+ /**
25
+ * Whether a rejection is an RLS/policy denial (`FORBIDDEN`, HTTP 403) — the
26
+ * caller is authenticated but not permitted to read/write the row. The most
27
+ * common per-call error a UI must handle in an RLS-first app.
28
+ */
29
+ declare const isForbiddenError: (error: unknown) => error is Error & {
30
+ code: "FORBIDDEN";
31
+ };
32
+ /** Whether a rejection is an authentication failure (`UNAUTHORIZED`, HTTP 401) — no/invalid identity. */
33
+ declare const isUnauthorizedError: (error: unknown) => error is Error & {
34
+ code: "UNAUTHORIZED";
35
+ };
36
+ /**
37
+ * Whether a rejection is a rate-limit denial (`TOO_MANY_REQUESTS`, HTTP 429).
38
+ * The retry hint (if the server sent one) is read with {@link getRetryAfterMs}.
39
+ */
40
+ declare const isRateLimitedError: (error: unknown) => error is Error & {
41
+ code: "TOO_MANY_REQUESTS";
42
+ };
43
+ /**
44
+ * Read the server's machine-readable `code` off a rejection, narrowed to the
45
+ * known {@link LunoraErrorCode} union. Returns `undefined` for a non-`Error`, a
46
+ * missing code, or an unrecognized code string (forward-compat server codes read
47
+ * as `undefined` here rather than being falsely narrowed).
48
+ */
49
+ declare const getErrorCode: (error: unknown) => LunoraErrorCode | undefined;
50
+ /**
51
+ * Read the rate-limit retry hint (`data.retryAfterMs`) off a
52
+ * `TOO_MANY_REQUESTS` rejection without hand-casting the `unknown` `data`
53
+ * payload. Returns the finite millisecond value the server sent, or `undefined`
54
+ * when absent/non-numeric. Pair with {@link isRateLimitedError}.
55
+ */
56
+ declare const getRetryAfterMs: (error: unknown) => number | undefined;
2
57
  /** The registered function kinds a {@link FunctionReference} can describe. `stream` is a query that yields multiple frames over the WS. */
3
58
  type FunctionKind = "action" | "mutation" | "query" | "stream";
4
59
  /**
@@ -1152,10 +1207,20 @@ interface SyncWatermark {
1152
1207
  checkpoint?: number;
1153
1208
  mutationId?: number;
1154
1209
  }
1155
- /** An `Error` carrying the server's machine-readable `code` and (for a `LunoraError`) structured `data`. The client's public error contract for RPC/batch failures. */
1210
+ /**
1211
+ * An `Error` carrying the server's machine-readable `code` and (for a
1212
+ * `LunoraError`) structured `data`, plus an optional actionable `hint` (Markdown)
1213
+ * and `docsUrl` resolved from the central error catalog. The client's public
1214
+ * error contract for RPC/batch failures — a UI can render `hint`/`docsUrl` to
1215
+ * tell the user how to fix the error. The `(string & {})` arm keeps
1216
+ * forward-compat/unknown server codes assignable without losing autocomplete on
1217
+ * the known {@link LunoraErrorCode} union.
1218
+ */
1156
1219
  type LunoraClientError = Error & {
1157
- code?: string;
1220
+ code?: LunoraErrorCode | (string & {});
1158
1221
  data?: unknown;
1222
+ docsUrl?: string;
1223
+ hint?: string | string[];
1159
1224
  };
1160
1225
  /** One demuxed result slot of a {@link LunoraClient.batch} call (plan 088). */
1161
1226
  type BatchSlot = {
@@ -2357,4 +2422,4 @@ declare class LunoraClient {
2357
2422
  */
2358
2423
  private settleReplayBatchSlots;
2359
2424
  }
2360
- export { SubscriptionCallback as $, ArgsOf as A, BookmarkStorage as B, CachedQuery as C, DEFAULT_MAX_BUFFER as D, ScheduleRecord as E, FunctionReference as F, GlobalFacetResult as G, SchedulerPoolStatus as H, SchedulerStatus as I, ServerMessage as J, ServerPokeEndMessage as K, LunoraClient as L, MutationCallOptions as M, ServerPokePartMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeStartMessage as T, User as U, ShardTrafficEntry as V, ShardTrafficResult as W, StorageListPage as X, StorageObject as Y, StreamHandle as Z, StreamIterable as _, Unsubscribe as a, SubscriptionRegistry as a0, SubscriptionState as a1, SyncWatermark as a2, WorkflowInstanceAction as a3, WorkflowInstanceDetail as a4, WorkflowInstancePage as a5, WorkflowInstanceStatus as a6, WorkflowInstanceSummary as a7, WorkflowStepDetail as a8, createLocalStore as a9, createStream as aa, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, ClientMessage as f, ClientShapeSubscribeMessage as g, ClientShapeUnsubscribeMessage as h, ConnectionStatus as i, FunctionArgumentDescriptor as j, FunctionDescriptor as k, GlobalFacetValue as l, GlobalFilterClause as m, GlobalTableInfo as n, GlobalTablePage as o, LunoraClientError as p, LunoraClientOptions as q, MutationSettledEvent as r, OptimisticLocalStore as s, OptimisticUpdate as t, OutboxMutation as u, OutboxSink as v, PersistedMutation as w, RowOp as x, RpcEnvelope as y, RpcResponseBody as z };
2425
+ export { StreamHandle as $, ArgsOf as A, BookmarkStorage as B, CONFLICT_ERROR_CODE as C, DEFAULT_MAX_BUFFER as D, RpcEnvelope as E, FunctionReference as F, GlobalFacetResult as G, RpcResponseBody as H, ScheduleRecord as I, SchedulerPoolStatus as J, SchedulerStatus as K, LunoraClient as L, MutationCallOptions as M, ServerMessage as N, OfflineQueueOptions as O, Preloaded as P, QueryCacheAdapter as Q, ReturnOf as R, SubscriptionError as S, ServerPokeEndMessage as T, User as U, ServerPokePartMessage as V, ServerPokeStartMessage as W, ShardTrafficEntry as X, ShardTrafficResult as Y, StorageListPage as Z, StorageObject as _, Unsubscribe as a, StreamIterable as a0, SubscriptionCallback as a1, SubscriptionRegistry as a2, SubscriptionState as a3, SyncWatermark as a4, WorkflowInstanceAction as a5, WorkflowInstanceDetail as a6, WorkflowInstancePage as a7, WorkflowInstanceStatus as a8, WorkflowInstanceSummary as a9, WorkflowStepDetail as aa, createLocalStore as ab, createStream as ac, getErrorCode as ad, getRetryAfterMs as ae, isConflictError as af, isForbiddenError as ag, isRateLimitedError as ah, isUnauthorizedError as ai, SubscriptionErrorCallback as b, PersistenceAdapter as c, ReconnectOptions as d, BatchSlot as e, CachedQuery as f, ClientMessage as g, ClientShapeSubscribeMessage as h, ClientShapeUnsubscribeMessage as i, ConnectionStatus as j, FunctionArgumentDescriptor as k, FunctionDescriptor as l, GlobalFacetValue as m, GlobalFilterClause as n, GlobalTableInfo as o, GlobalTablePage as p, LunoraClientError as q, LunoraClientOptions as r, LunoraErrorCode as s, MutationSettledEvent as t, OptimisticLocalStore as u, OptimisticUpdate as v, OutboxMutation as w, OutboxSink as x, PersistedMutation as y, RowOp as z };
@@ -1,4 +1,4 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-CtSRWJJ7.mjs";
1
+ import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DPLSlPiP.mjs";
2
2
  /**
3
3
  * Run a query once on the server (during SSR) and capture its result in a
4
4
  * serializable {@link Preloaded} token. Embed the token in the rendered HTML and
@@ -1,4 +1,4 @@
1
- import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-CtSRWJJ7.js";
1
+ import { F as FunctionReference, L as LunoraClient, A as ArgsOf, R as ReturnOf, P as Preloaded } from "./lunora-client.d-DPLSlPiP.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,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-CtSRWJJ7.mjs";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-CtSRWJJ7.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-DPLSlPiP.mjs";
2
+ export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DPLSlPiP.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-CtSRWJJ7.js";
2
- export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-CtSRWJJ7.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-DPLSlPiP.js";
2
+ export type { b as SubscriptionErrorCallback } from "../packem_shared/lunora-client.d-DPLSlPiP.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-CtSRWJJ7.mjs";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-CtSRWJJ7.mjs";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-GjXaOwY9.mjs";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DPLSlPiP.mjs";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DPLSlPiP.mjs";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-Bpi7xweC.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-CtSRWJJ7.js";
2
- export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-CtSRWJJ7.js";
3
- export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-NMFbch9j.js";
1
+ import { P as Preloaded, L as LunoraClient } from "../packem_shared/lunora-client.d-DPLSlPiP.js";
2
+ export type { A as ArgsOf, F as FunctionReference, R as ReturnOf } from "../packem_shared/lunora-client.d-DPLSlPiP.js";
3
+ export { p as preloadQuery, a as preloadedQueryResult } from "../packem_shared/preload.d-CmFdZFQi.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-BUEYFHjp.mjs';
3
+ export { createServerClient } from '../packem_shared/createServerClient-Blht8tLm.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.15",
3
+ "version": "1.0.0-alpha.17",
4
4
  "description": "Lunora browser SDK: WebSocket transport, optimistic updates, and an offline mutation queue",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -61,6 +61,9 @@
61
61
  "publishConfig": {
62
62
  "access": "public"
63
63
  },
64
+ "dependencies": {
65
+ "@lunora/errors": "1.0.0-alpha.1"
66
+ },
64
67
  "engines": {
65
68
  "node": "^22.15.0 || >=24.11.0"
66
69
  }
@@ -1,4 +0,0 @@
1
- const CONFLICT_ERROR_CODE = "CONFLICT";
2
- const isConflictError = (error) => error instanceof Error && error.code === CONFLICT_ERROR_CODE;
3
-
4
- export { CONFLICT_ERROR_CODE, isConflictError };