@hanzo/base 0.2.0 → 0.2.1

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.
@@ -309,9 +309,9 @@ var RealtimeService = class {
309
309
  if (this._eventSource) return;
310
310
  this._intentionalDisconnect = false;
311
311
  this._setState("connecting");
312
- const url = `${this._baseUrl}/api/realtime`;
312
+ const url = `${this._baseUrl}/v1/realtime`;
313
313
  this._eventSource = new EventSource(url);
314
- this._eventSource.addEventListener("PB_CONNECT", (e) => {
314
+ this._eventSource.addEventListener("CONNECT", (e) => {
315
315
  try {
316
316
  const data = JSON.parse(e.data);
317
317
  this._clientId = data.clientId;
@@ -373,7 +373,7 @@ var RealtimeService = class {
373
373
  }
374
374
  const token = this._getToken();
375
375
  try {
376
- await fetch(`${this._baseUrl}/api/realtime`, {
376
+ await fetch(`${this._baseUrl}/v1/realtime`, {
377
377
  method: "POST",
378
378
  headers: {
379
379
  "Content-Type": "application/json",
@@ -655,7 +655,7 @@ var CollectionService = class {
655
655
  }
656
656
  // ---- Internal -----------------------------------------------------------
657
657
  _collectionPath() {
658
- return `/api/collections/${encodeURIComponent(this.collectionIdOrName)}`;
658
+ return `/v1/collections/${encodeURIComponent(this.collectionIdOrName)}`;
659
659
  }
660
660
  _applyOptions(params, options) {
661
661
  if (!options) return;
@@ -774,14 +774,14 @@ var FileService = class {
774
774
  }
775
775
  /**
776
776
  * Build a full URL to a record file.
777
- * Compatible with PocketBase's pb.files.getURL().
777
+ * Compatible with Base's files.getURL().
778
778
  */
779
779
  getURL(record, filename, options) {
780
780
  if (!filename || !record.id) return "";
781
781
  const collectionId = record.collectionId ?? record.collectionName ?? "";
782
782
  const parts = [
783
783
  this._baseUrl,
784
- "api",
784
+ "v1",
785
785
  "files",
786
786
  encodeURIComponent(collectionId),
787
787
  encodeURIComponent(record.id),
@@ -819,7 +819,7 @@ var BaseClient = class {
819
819
  );
820
820
  });
821
821
  }
822
- // ---- PocketBase-compatible collection() API -----------------------------
822
+ // ---- Base-compatible collection() API ------------------------------------
823
823
  /** Get or create a CollectionService for the given name/id. */
824
824
  collection(nameOrId) {
825
825
  let svc = this._collections.get(nameOrId);
@@ -877,7 +877,7 @@ var BaseClient = class {
877
877
  if (options?.page) params.set("page", String(options.page));
878
878
  if (options?.perPage) params.set("perPage", String(options.perPage));
879
879
  const qs = params.toString();
880
- const path = `/api/collections/${encodeURIComponent(collection)}/records${qs ? "?" + qs : ""}`;
880
+ const path = `/v1/collections/${encodeURIComponent(collection)}/records${qs ? "?" + qs : ""}`;
881
881
  const result = await this._request("GET", path);
882
882
  this.store.setQuery(collection, options?.filter ?? "", result.items);
883
883
  return result;
@@ -887,29 +887,29 @@ var BaseClient = class {
887
887
  if (options?.expand) params.set("expand", options.expand);
888
888
  if (options?.fields) params.set("fields", options.fields);
889
889
  const qs = params.toString();
890
- const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}${qs ? "?" + qs : ""}`;
890
+ const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}${qs ? "?" + qs : ""}`;
891
891
  return this._request("GET", path);
892
892
  }
893
893
  async create(collection, data) {
894
- const path = `/api/collections/${encodeURIComponent(collection)}/records`;
894
+ const path = `/v1/collections/${encodeURIComponent(collection)}/records`;
895
895
  const record = await this._request("POST", path, data);
896
896
  this.store.applyServerUpdate(collection, "create", record);
897
897
  return record;
898
898
  }
899
899
  async update(collection, id, data) {
900
- const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`;
900
+ const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`;
901
901
  const record = await this._request("PATCH", path, data);
902
902
  this.store.applyServerUpdate(collection, "update", record);
903
903
  return record;
904
904
  }
905
905
  async delete(collection, id) {
906
- const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`;
906
+ const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`;
907
907
  await this._request("DELETE", path);
908
908
  this.store.applyServerUpdate(collection, "delete", { id });
909
909
  }
910
910
  // ---- Auth (direct convenience) ------------------------------------------
911
911
  async signInWithPassword(collection, identity, password) {
912
- const path = `/api/collections/${encodeURIComponent(collection)}/auth-with-password`;
912
+ const path = `/v1/collections/${encodeURIComponent(collection)}/auth-with-password`;
913
913
  const result = await this._request("POST", path, {
914
914
  identity,
915
915
  password
@@ -921,7 +921,7 @@ var BaseClient = class {
921
921
  return this.create(collection, data);
922
922
  }
923
923
  async refreshAuth(collection) {
924
- const path = `/api/collections/${encodeURIComponent(collection)}/auth-refresh`;
924
+ const path = `/v1/collections/${encodeURIComponent(collection)}/auth-refresh`;
925
925
  const result = await this._request("POST", path);
926
926
  this.authStore.save(result.token, result.record);
927
927
  return result;
@@ -963,7 +963,7 @@ var BaseClient = class {
963
963
  }
964
964
  // ---- Health check -------------------------------------------------------
965
965
  async health() {
966
- return this.send("/api/health");
966
+ return this.send("/v1/health");
967
967
  }
968
968
  // ---- Realtime convenience -----------------------------------------------
969
969
  /**
@@ -992,5 +992,5 @@ var BaseClientError = class extends Error {
992
992
  };
993
993
 
994
994
  export { BaseClient, BaseClientError, ClientResponseError, CollectionService, FileService, MemoryAuthStore, QueryStore, RealtimeService, VersionTracker };
995
- //# sourceMappingURL=chunk-LBAV5X5P.js.map
996
- //# sourceMappingURL=chunk-LBAV5X5P.js.map
995
+ //# sourceMappingURL=chunk-3WOGNODW.js.map
996
+ //# sourceMappingURL=chunk-3WOGNODW.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/state.ts","../src/core/store.ts","../src/core/realtime.ts","../src/core/collection.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"chunk-LBAV5X5P.js","sourcesContent":["/**\n * State version tracking (Convex-inspired).\n *\n * Each query result is tagged with a StateVersion so the client can\n * detect ordering, replay transitions, and drive optimistic rollbacks.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface StateVersion {\n /** Monotonically increasing counter bumped on every query-set change. */\n querySet: number\n /** Server timestamp (microseconds since epoch) of the latest known event. */\n ts: bigint\n /** Identity hash -- changes when the authenticated user changes. */\n identity: number\n}\n\nexport type Modification =\n | { type: 'QueryUpdated'; collection: string; record: BaseRecord }\n | { type: 'QueryRemoved'; collection: string; id: string }\n | { type: 'QueryFailed'; collection: string; error: string }\n\nexport interface Transition {\n startVersion: StateVersion\n endVersion: StateVersion\n modifications: Modification[]\n}\n\n/** Minimal record shape that every Base record satisfies. */\nexport interface BaseRecord {\n id: string\n collectionId?: string\n collectionName?: string\n created?: string\n updated?: string\n [key: string]: unknown\n}\n\n// ---------------------------------------------------------------------------\n// VersionTracker\n// ---------------------------------------------------------------------------\n\nexport class VersionTracker {\n private _version: StateVersion\n private _history: Transition[] = []\n private readonly _maxHistory: number\n\n constructor(maxHistory = 128) {\n this._version = { querySet: 0, ts: 0n, identity: 0 }\n this._maxHistory = maxHistory\n }\n\n get current(): Readonly<StateVersion> {\n return { ...this._version }\n }\n\n get history(): readonly Transition[] {\n return this._history\n }\n\n /**\n * Advance the version and record a transition.\n * Returns the new version.\n */\n advance(modifications: Modification[], serverTs?: bigint): StateVersion {\n const start = { ...this._version }\n\n this._version = {\n querySet: this._version.querySet + 1,\n ts: serverTs ?? this._version.ts,\n identity: this._version.identity,\n }\n\n const transition: Transition = {\n startVersion: start,\n endVersion: { ...this._version },\n modifications,\n }\n\n this._history.push(transition)\n if (this._history.length > this._maxHistory) {\n this._history.shift()\n }\n\n return { ...this._version }\n }\n\n /** Update identity hash (e.g. on auth change). */\n setIdentity(identity: number): void {\n this._version = { ...this._version, identity }\n }\n\n /** Update the high-water timestamp without bumping querySet. */\n updateTimestamp(ts: bigint): void {\n if (ts > this._version.ts) {\n this._version = { ...this._version, ts }\n }\n }\n\n /** Simple FNV-1a-like hash for identity derivation. */\n static hashIdentity(token: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < token.length; i++) {\n h ^= token.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n }\n}\n","/**\n * QueryStore -- manages server state + optimistic overlay.\n *\n * Subscribers are notified whenever the effective (server + optimistic)\n * state for their query changes. Optimistic mutations are tracked by\n * mutationId so they can be rolled back individually.\n */\n\nimport type { BaseRecord, Modification } from './state.js'\nimport { VersionTracker } from './state.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface QueryKey {\n collection: string\n filter: string\n}\n\nexport type StoreCallback = (records: BaseRecord[]) => void\n\ninterface OptimisticEntry {\n mutationId: string\n collection: string\n /** null means \"delete this id\" */\n record: BaseRecord | null\n deletedId?: string\n createdAt: number\n}\n\ninterface QuerySlot {\n key: QueryKey\n serverRecords: BaseRecord[]\n listeners: Set<StoreCallback>\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction queryHash(collection: string, filter: string): string {\n return `${collection}::${filter}`\n}\n\nfunction mergeOptimistic(\n server: BaseRecord[],\n optimistic: OptimisticEntry[],\n collection: string,\n): BaseRecord[] {\n // Start with a mutable copy keyed by id.\n const map = new Map<string, BaseRecord>()\n for (const r of server) {\n map.set(r.id, r)\n }\n\n for (const entry of optimistic) {\n if (entry.collection !== collection) continue\n if (entry.record === null && entry.deletedId) {\n map.delete(entry.deletedId)\n } else if (entry.record) {\n map.set(entry.record.id, entry.record)\n }\n }\n\n return Array.from(map.values())\n}\n\n// ---------------------------------------------------------------------------\n// QueryStore\n// ---------------------------------------------------------------------------\n\nexport class QueryStore {\n private readonly _slots = new Map<string, QuerySlot>()\n private readonly _optimistic: OptimisticEntry[] = []\n private readonly _version = new VersionTracker()\n\n get version() {\n return this._version.current\n }\n\n // ---- Query cache --------------------------------------------------------\n\n /** Return cached effective (server+optimistic) result or undefined. */\n getQuery(collection: string, filter = ''): BaseRecord[] | undefined {\n const slot = this._slots.get(queryHash(collection, filter))\n if (!slot) return undefined\n return mergeOptimistic(slot.serverRecords, this._optimistic, collection)\n }\n\n /** Overwrite the server-truth cache for a query and notify. */\n setQuery(collection: string, filter: string, data: BaseRecord[]): void {\n const hash = queryHash(collection, filter)\n let slot = this._slots.get(hash)\n if (!slot) {\n slot = { key: { collection, filter }, serverRecords: [], listeners: new Set() }\n this._slots.set(hash, slot)\n }\n slot.serverRecords = data\n\n this._version.advance(\n data.map((r) => ({ type: 'QueryUpdated' as const, collection, record: r })),\n )\n\n this._notify(slot)\n }\n\n // ---- Optimistic mutations -----------------------------------------------\n\n /** Apply an optimistic create/update. Returns a mutationId for rollback. */\n optimisticSet(collection: string, record: BaseRecord): string {\n const mutationId = `opt_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`\n this._optimistic.push({\n mutationId,\n collection,\n record,\n createdAt: Date.now(),\n })\n this._notifyCollection(collection)\n return mutationId\n }\n\n /** Apply an optimistic delete. */\n optimisticDelete(collection: string, id: string): string {\n const mutationId = `opt_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`\n this._optimistic.push({\n mutationId,\n collection,\n record: null,\n deletedId: id,\n createdAt: Date.now(),\n })\n this._notifyCollection(collection)\n return mutationId\n }\n\n /** Remove a single optimistic mutation and re-derive. */\n rollbackOptimistic(mutationId: string): void {\n const idx = this._optimistic.findIndex((e) => e.mutationId === mutationId)\n if (idx === -1) return\n const entry = this._optimistic[idx]\n this._optimistic.splice(idx, 1)\n this._notifyCollection(entry.collection)\n }\n\n /** Drop all optimistic entries for a collection. */\n clearOptimistic(collection: string): void {\n for (let i = this._optimistic.length - 1; i >= 0; i--) {\n if (this._optimistic[i].collection === collection) {\n this._optimistic.splice(i, 1)\n }\n }\n this._notifyCollection(collection)\n }\n\n // ---- Server event ingestion ---------------------------------------------\n\n /**\n * Apply a realtime SSE event from the server.\n * `action` is one of \"create\", \"update\", \"delete\".\n */\n applyServerUpdate(\n collection: string,\n action: 'create' | 'update' | 'delete',\n record: BaseRecord,\n ): void {\n const mods: Modification[] = []\n\n for (const slot of this._slots.values()) {\n if (slot.key.collection !== collection) continue\n\n if (action === 'delete') {\n const before = slot.serverRecords.length\n slot.serverRecords = slot.serverRecords.filter((r) => r.id !== record.id)\n if (slot.serverRecords.length !== before) {\n mods.push({ type: 'QueryRemoved', collection, id: record.id })\n }\n } else {\n // create or update -- upsert\n const idx = slot.serverRecords.findIndex((r) => r.id === record.id)\n if (idx >= 0) {\n slot.serverRecords[idx] = record\n } else {\n slot.serverRecords.push(record)\n }\n mods.push({ type: 'QueryUpdated', collection, record })\n }\n }\n\n if (mods.length > 0) {\n const ts = record.updated\n ? BigInt(new Date(record.updated).getTime()) * 1000n\n : undefined\n this._version.advance(mods, ts)\n }\n\n this._notifyCollection(collection)\n }\n\n // ---- Subscriptions ------------------------------------------------------\n\n /** Subscribe to effective-state changes for a query. Returns unsubscribe. */\n subscribe(collection: string, filter: string, callback: StoreCallback): () => void {\n const hash = queryHash(collection, filter)\n let slot = this._slots.get(hash)\n if (!slot) {\n slot = { key: { collection, filter }, serverRecords: [], listeners: new Set() }\n this._slots.set(hash, slot)\n }\n slot.listeners.add(callback)\n return () => {\n slot!.listeners.delete(callback)\n // GC empty slots\n if (slot!.listeners.size === 0 && slot!.serverRecords.length === 0) {\n this._slots.delete(hash)\n }\n }\n }\n\n // ---- Internal -----------------------------------------------------------\n\n private _notify(slot: QuerySlot): void {\n if (slot.listeners.size === 0) return\n const effective = mergeOptimistic(slot.serverRecords, this._optimistic, slot.key.collection)\n for (const cb of slot.listeners) {\n try {\n cb(effective)\n } catch {\n // listener errors must not break the store\n }\n }\n }\n\n private _notifyCollection(collection: string): void {\n for (const slot of this._slots.values()) {\n if (slot.key.collection === collection) {\n this._notify(slot)\n }\n }\n }\n}\n","/**\n * RealtimeService -- SSE-based subscription manager.\n *\n * Features:\n * - Query deduplication via hash(collection+topic) with reference counting\n * - Auto-reconnect with exponential backoff\n * - Max observed timestamp tracking\n * - Connection state notifications\n */\n\nimport type { BaseRecord } from './state.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected'\n\nexport interface RealtimeEvent {\n action: 'create' | 'update' | 'delete'\n record: BaseRecord\n}\n\nexport type RealtimeCallback = (event: RealtimeEvent) => void\nexport type ConnectionCallback = (state: ConnectionState) => void\n\ninterface Subscription {\n collection: string\n topic: string\n callbacks: Set<RealtimeCallback>\n}\n\n// ---------------------------------------------------------------------------\n// RealtimeService\n// ---------------------------------------------------------------------------\n\nexport class RealtimeService {\n private readonly _baseUrl: string\n private readonly _getToken: () => string\n\n private _eventSource: EventSource | null = null\n private _state: ConnectionState = 'disconnected'\n private _connectionListeners = new Set<ConnectionCallback>()\n\n /** Dedup map: hash -> Subscription. */\n private _subscriptions = new Map<string, Subscription>()\n\n /** SSE client id assigned by the server on connect. */\n private _clientId: string | null = null\n\n /** Reconnect state. */\n private _reconnectAttempts = 0\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private _maxReconnectDelay = 30_000\n private _baseReconnectDelay = 500\n\n /** High-water mark of observed server timestamps. */\n private _maxTimestamp = 0n\n\n /** Set to true when disconnect() is called explicitly. */\n private _intentionalDisconnect = false\n\n constructor(baseUrl: string, getToken: () => string) {\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n this._getToken = getToken\n }\n\n // ---- Public API ---------------------------------------------------------\n\n get state(): ConnectionState {\n return this._state\n }\n\n get maxTimestamp(): bigint {\n return this._maxTimestamp\n }\n\n /**\n * Subscribe to realtime events for a collection topic.\n *\n * Topic is usually \"*\" (all changes) or a record id.\n * Returns an unsubscribe function.\n */\n subscribe(\n collection: string,\n topic: string,\n callback: RealtimeCallback,\n ): () => void {\n const hash = this._hash(collection, topic)\n let sub = this._subscriptions.get(hash)\n\n if (!sub) {\n sub = { collection, topic, callbacks: new Set() }\n this._subscriptions.set(hash, sub)\n }\n sub.callbacks.add(callback)\n\n // If this is the first subscription, connect.\n if (this._subscriptions.size === 1 && !this._eventSource) {\n this._connect()\n } else if (this._clientId) {\n // Already connected -- submit this subscription to the server.\n this._submitSubscriptions()\n }\n\n return () => {\n sub!.callbacks.delete(callback)\n if (sub!.callbacks.size === 0) {\n this._subscriptions.delete(hash)\n if (this._clientId) {\n this._submitSubscriptions()\n }\n }\n // If no subscriptions remain, disconnect.\n if (this._subscriptions.size === 0) {\n this.disconnect()\n }\n }\n }\n\n /** Remove all subscribers for a topic, or all topics if none specified. */\n unsubscribe(topic?: string): void {\n if (topic) {\n this._subscriptions.delete(topic)\n } else {\n this._subscriptions.clear()\n }\n if (this._subscriptions.size === 0) {\n this.disconnect()\n }\n }\n\n /** Register a connection-state listener. Returns unsubscribe. */\n onConnectionChange(callback: ConnectionCallback): () => void {\n this._connectionListeners.add(callback)\n return () => {\n this._connectionListeners.delete(callback)\n }\n }\n\n /** Explicitly disconnect. */\n disconnect(): void {\n this._intentionalDisconnect = true\n this._clearReconnect()\n if (this._eventSource) {\n this._eventSource.close()\n this._eventSource = null\n }\n this._clientId = null\n this._setState('disconnected')\n }\n\n // ---- Connection ---------------------------------------------------------\n\n private _connect(): void {\n if (this._eventSource) return\n this._intentionalDisconnect = false\n this._setState('connecting')\n\n const url = `${this._baseUrl}/api/realtime`\n this._eventSource = new EventSource(url)\n\n this._eventSource.addEventListener('PB_CONNECT', (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data) as { clientId: string }\n this._clientId = data.clientId\n this._reconnectAttempts = 0\n this._setState('connected')\n this._submitSubscriptions()\n } catch {\n // malformed connect event\n }\n })\n\n // Listen for all SSE events. The server sends events named after\n // the collection, e.g. event: \"posts\".\n this._eventSource.onmessage = (e: MessageEvent) => {\n this._handleMessage(e)\n }\n\n // The server sends named events for each collection.\n // We use the generic handler plus specific ones registered dynamically.\n this._eventSource.onerror = () => {\n this._eventSource?.close()\n this._eventSource = null\n this._clientId = null\n this._setState('disconnected')\n\n if (!this._intentionalDisconnect) {\n this._scheduleReconnect()\n }\n }\n }\n\n private _handleMessage(e: MessageEvent): void {\n let payload: { action: string; record: BaseRecord }\n try {\n payload = JSON.parse(e.data)\n } catch {\n return\n }\n\n const action = payload.action as RealtimeEvent['action']\n const record = payload.record\n if (!record?.id) return\n\n // Track timestamp high-water mark.\n const ts = record.updated ?? record.created\n if (ts) {\n const n = BigInt(new Date(ts).getTime()) * 1000n\n if (n > this._maxTimestamp) {\n this._maxTimestamp = n\n }\n }\n\n // Fan out to matching subscriptions.\n const collectionName = record.collectionName ?? ''\n for (const sub of this._subscriptions.values()) {\n if (sub.collection !== collectionName) continue\n if (sub.topic !== '*' && sub.topic !== record.id) continue\n const event: RealtimeEvent = { action, record }\n for (const cb of sub.callbacks) {\n try {\n cb(event)\n } catch {\n // subscriber errors must not break fanout\n }\n }\n }\n }\n\n /** Submit current subscription set to the server via POST. */\n private async _submitSubscriptions(): Promise<void> {\n if (!this._clientId) return\n\n const topics: string[] = []\n for (const sub of this._subscriptions.values()) {\n topics.push(`${sub.collection}/${sub.topic}`)\n }\n\n const token = this._getToken()\n try {\n await fetch(`${this._baseUrl}/api/realtime`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: token } : {}),\n },\n body: JSON.stringify({\n clientId: this._clientId,\n subscriptions: topics,\n }),\n })\n } catch {\n // will retry on next reconnect\n }\n }\n\n // ---- Reconnect ----------------------------------------------------------\n\n private _scheduleReconnect(): void {\n this._clearReconnect()\n const delay = Math.min(\n this._baseReconnectDelay * Math.pow(2, this._reconnectAttempts),\n this._maxReconnectDelay,\n )\n // Add jitter: +/- 25%\n const jitter = delay * (0.75 + Math.random() * 0.5)\n this._reconnectAttempts++\n\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null\n this._connect()\n }, jitter)\n }\n\n private _clearReconnect(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer)\n this._reconnectTimer = null\n }\n }\n\n // ---- State --------------------------------------------------------------\n\n private _setState(state: ConnectionState): void {\n if (this._state === state) return\n this._state = state\n for (const cb of this._connectionListeners) {\n try {\n cb(state)\n } catch {\n // listener errors must not break notification\n }\n }\n }\n\n // ---- Helpers ------------------------------------------------------------\n\n private _hash(collection: string, topic: string): string {\n return `${collection}::${topic}`\n }\n}\n","/**\n * CollectionService -- typed CRUD + auth + realtime for a single collection.\n *\n * API-compatible with PocketBase JS SDK's RecordService, extended with\n * reactive features (subscribe/unsubscribe, optimistic writes).\n */\n\nimport type { BaseRecord } from './state.js'\nimport type { QueryStore } from './store.js'\nimport type { RealtimeService, RealtimeCallback } from './realtime.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ListResult<T = BaseRecord> {\n page: number\n perPage: number\n totalItems: number\n totalPages: number\n items: T[]\n}\n\nexport interface RecordQueryOptions {\n filter?: string\n sort?: string\n expand?: string\n fields?: string\n headers?: Record<string, string>\n /** Extra query params merged into the URL. */\n query?: Record<string, string>\n /** Request-scoped AbortSignal. */\n signal?: AbortSignal\n}\n\nexport interface RecordFullListOptions extends RecordQueryOptions {\n /** Batch size for pagination (default 200). */\n batch?: number\n}\n\nexport interface FileOptions {\n thumb?: string\n token?: string\n}\n\nexport interface AuthResponse<T = BaseRecord> {\n token: string\n record: T\n}\n\nexport interface OAuth2Options {\n provider: string\n code: string\n codeVerifier: string\n redirectUrl: string\n createData?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// CollectionService\n// ---------------------------------------------------------------------------\n\nexport class CollectionService {\n readonly collectionIdOrName: string\n\n private readonly _baseUrl: string\n private readonly _getToken: () => string\n private readonly _setAuth: (token: string, record: BaseRecord) => void\n private readonly _store: QueryStore\n private readonly _realtime: RealtimeService\n\n constructor(\n collectionIdOrName: string,\n baseUrl: string,\n getToken: () => string,\n setAuth: (token: string, record: BaseRecord) => void,\n store: QueryStore,\n realtime: RealtimeService,\n ) {\n this.collectionIdOrName = collectionIdOrName\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n this._getToken = getToken\n this._setAuth = setAuth\n this._store = store\n this._realtime = realtime\n }\n\n // ---- CRUD ---------------------------------------------------------------\n\n async getList<T extends BaseRecord = BaseRecord>(\n page = 1,\n perPage = 30,\n options?: RecordQueryOptions,\n ): Promise<ListResult<T>> {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('perPage', String(perPage))\n this._applyOptions(params, options)\n\n const result = await this._request<ListResult<T>>(\n 'GET',\n `${this._collectionPath()}/records?${params}`,\n undefined,\n options,\n )\n\n // Cache in store.\n const cacheFilter = options?.filter ?? ''\n this._store.setQuery(\n this.collectionIdOrName,\n cacheFilter,\n result.items as unknown as BaseRecord[],\n )\n\n return result\n }\n\n async getFullList<T extends BaseRecord = BaseRecord>(\n options?: RecordFullListOptions,\n ): Promise<T[]> {\n const batch = options?.batch ?? 200\n let page = 1\n let all: T[] = []\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const result = await this.getList<T>(page, batch, options)\n all = all.concat(result.items)\n if (all.length >= result.totalItems || result.items.length < batch) {\n break\n }\n page++\n }\n\n return all\n }\n\n async getOne<T extends BaseRecord = BaseRecord>(\n id: string,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n return this._request<T>('GET', path, undefined, options)\n }\n\n async getFirstListItem<T extends BaseRecord = BaseRecord>(\n filter: string,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const opts = { ...options, filter }\n const result = await this.getList<T>(1, 1, opts)\n if (result.items.length === 0) {\n throw new ClientResponseError({\n url: this._baseUrl,\n status: 404,\n data: { message: 'The requested resource wasn\\'t found.' },\n })\n }\n return result.items[0]\n }\n\n async create<T extends BaseRecord = BaseRecord>(\n data: Record<string, unknown> | FormData,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records${qs ? '?' + qs : ''}`\n\n // Optimistic: generate temp id.\n let mutationId: string | undefined\n if (!(data instanceof FormData) && typeof data === 'object') {\n const tempId = `__temp_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`\n const optimistic: BaseRecord = {\n id: tempId,\n collectionName: this.collectionIdOrName,\n ...(data as Record<string, unknown>),\n }\n mutationId = this._store.optimisticSet(this.collectionIdOrName, optimistic)\n }\n\n try {\n const body = data instanceof FormData ? data : JSON.stringify(data)\n const contentType = data instanceof FormData ? undefined : 'application/json'\n const record = await this._request<T>('POST', path, body, options, contentType)\n\n // Replace optimistic entry with real server record.\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n this._store.applyServerUpdate(this.collectionIdOrName, 'create', record as unknown as BaseRecord)\n return record\n } catch (err) {\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n throw err\n }\n }\n\n async update<T extends BaseRecord = BaseRecord>(\n id: string,\n data: Record<string, unknown> | FormData,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n\n // Optimistic update.\n let mutationId: string | undefined\n if (!(data instanceof FormData) && typeof data === 'object') {\n const optimistic: BaseRecord = {\n id,\n collectionName: this.collectionIdOrName,\n ...(data as Record<string, unknown>),\n }\n mutationId = this._store.optimisticSet(this.collectionIdOrName, optimistic)\n }\n\n try {\n const body = data instanceof FormData ? data : JSON.stringify(data)\n const contentType = data instanceof FormData ? undefined : 'application/json'\n const record = await this._request<T>('PATCH', path, body, options, contentType)\n\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n this._store.applyServerUpdate(this.collectionIdOrName, 'update', record as unknown as BaseRecord)\n return record\n } catch (err) {\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n throw err\n }\n }\n\n async delete(id: string, options?: RecordQueryOptions): Promise<boolean> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n\n // Optimistic delete.\n const mutationId = this._store.optimisticDelete(this.collectionIdOrName, id)\n\n try {\n await this._request<void>('DELETE', path, undefined, options)\n this._store.rollbackOptimistic(mutationId)\n this._store.applyServerUpdate(this.collectionIdOrName, 'delete', { id } as BaseRecord)\n return true\n } catch (err) {\n this._store.rollbackOptimistic(mutationId)\n throw err\n }\n }\n\n // ---- Realtime -----------------------------------------------------------\n\n /**\n * Subscribe to realtime events for this collection.\n * `topic` is \"*\" for all changes or a specific record id.\n */\n subscribe(topic: string, callback: RealtimeCallback): () => void {\n return this._realtime.subscribe(this.collectionIdOrName, topic, callback)\n }\n\n /** Unsubscribe from a specific topic or all topics for this collection. */\n unsubscribe(topic?: string): void {\n this._realtime.unsubscribe(\n topic ? `${this.collectionIdOrName}/${topic}` : this.collectionIdOrName,\n )\n }\n\n // ---- Auth methods (for auth collections) --------------------------------\n\n async authWithPassword<T extends BaseRecord = BaseRecord>(\n identity: string,\n password: string,\n options?: RecordQueryOptions,\n ): Promise<AuthResponse<T>> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/auth-with-password${qs ? '?' + qs : ''}`\n\n const result = await this._request<AuthResponse<T>>(\n 'POST',\n path,\n JSON.stringify({ identity, password }),\n options,\n 'application/json',\n )\n\n this._setAuth(result.token, result.record as unknown as BaseRecord)\n return result\n }\n\n async authWithOAuth2<T extends BaseRecord = BaseRecord>(\n oauthOptions: OAuth2Options,\n options?: RecordQueryOptions,\n ): Promise<AuthResponse<T>> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/auth-with-oauth2${qs ? '?' + qs : ''}`\n\n const result = await this._request<AuthResponse<T>>(\n 'POST',\n path,\n JSON.stringify(oauthOptions),\n options,\n 'application/json',\n )\n\n this._setAuth(result.token, result.record as unknown as BaseRecord)\n return result\n }\n\n async requestVerification(email: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/request-verification`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ email }),\n options,\n 'application/json',\n )\n return true\n }\n\n async confirmVerification(token: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/confirm-verification`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ token }),\n options,\n 'application/json',\n )\n return true\n }\n\n async requestPasswordReset(email: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/request-password-reset`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ email }),\n options,\n 'application/json',\n )\n return true\n }\n\n async confirmPasswordReset(\n token: string,\n password: string,\n passwordConfirm: string,\n options?: RecordQueryOptions,\n ): Promise<boolean> {\n const path = `${this._collectionPath()}/confirm-password-reset`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ token, password, passwordConfirm }),\n options,\n 'application/json',\n )\n return true\n }\n\n // ---- Internal -----------------------------------------------------------\n\n private _collectionPath(): string {\n return `/api/collections/${encodeURIComponent(this.collectionIdOrName)}`\n }\n\n private _applyOptions(params: URLSearchParams, options?: RecordQueryOptions): void {\n if (!options) return\n if (options.filter) params.set('filter', options.filter)\n if (options.sort) params.set('sort', options.sort)\n if (options.expand) params.set('expand', options.expand)\n if (options.fields) params.set('fields', options.fields)\n if (options.query) {\n for (const [k, v] of Object.entries(options.query)) {\n params.set(k, v)\n }\n }\n }\n\n private async _request<T>(\n method: string,\n path: string,\n body?: string | FormData,\n options?: RecordQueryOptions,\n contentType?: string,\n ): Promise<T> {\n const url = `${this._baseUrl}${path}`\n const token = this._getToken()\n\n const headers: Record<string, string> = {\n ...(options?.headers ?? {}),\n }\n if (token) {\n headers['Authorization'] = token\n }\n if (contentType) {\n headers['Content-Type'] = contentType\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ?? undefined,\n signal: options?.signal,\n })\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}))\n throw new ClientResponseError({\n url,\n status: response.status,\n data,\n })\n }\n\n // DELETE returns 204 with no body.\n if (response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientResponseError\n// ---------------------------------------------------------------------------\n\nexport interface ClientResponseErrorData {\n url: string\n status: number\n data: Record<string, unknown>\n}\n\nexport class ClientResponseError extends Error {\n url: string\n status: number\n data: Record<string, unknown>\n isAbort: boolean\n\n constructor(errorData: ClientResponseErrorData) {\n const message =\n (errorData.data?.message as string) ??\n `ClientResponseError ${errorData.status}`\n super(message)\n this.name = 'ClientResponseError'\n this.url = errorData.url\n this.status = errorData.status\n this.data = errorData.data\n this.isAbort = errorData.status === 0\n }\n\n toJSON(): ClientResponseErrorData {\n return { url: this.url, status: this.status, data: this.data }\n }\n}\n","/**\n * BaseClient -- main entry point for @hanzoai/base.\n *\n * Two API surfaces:\n *\n * 1. PocketBase-compatible: client.collection('posts').getList(...)\n * 2. Direct (convenience): client.list('posts', { filter: '...' })\n *\n * Both share the same QueryStore, RealtimeService, and AuthStore.\n */\n\nimport type { BaseRecord } from './state.js'\nimport { VersionTracker } from './state.js'\nimport { QueryStore } from './store.js'\nimport { RealtimeService, type RealtimeEvent } from './realtime.js'\nimport { CollectionService, type FileOptions } from './collection.js'\n\n// ---------------------------------------------------------------------------\n// AuthStore\n// ---------------------------------------------------------------------------\n\nexport interface AuthStore {\n token: string\n record: BaseRecord | null\n onChange(callback: (token: string, record: BaseRecord | null) => void): () => void\n save(token: string, record: BaseRecord | null): void\n clear(): void\n readonly isValid: boolean\n}\n\nexport type AuthChangeCallback = (token: string, record: BaseRecord | null) => void\n\n/**\n * Default in-memory auth store.\n * Validates JWT exp claim without external dependencies.\n */\nexport class MemoryAuthStore implements AuthStore {\n private _token = ''\n private _record: BaseRecord | null = null\n private _listeners = new Set<AuthChangeCallback>()\n\n get token(): string {\n return this._token\n }\n\n get record(): BaseRecord | null {\n return this._record\n }\n\n get isValid(): boolean {\n if (!this._token) return false\n try {\n const parts = this._token.split('.')\n if (parts.length !== 3) return false\n const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')))\n if (typeof payload.exp === 'number') {\n return payload.exp > Date.now() / 1000\n }\n return true\n } catch {\n return false\n }\n }\n\n save(token: string, record: BaseRecord | null): void {\n this._token = token\n this._record = record\n this._notify()\n }\n\n clear(): void {\n this._token = ''\n this._record = null\n this._notify()\n }\n\n onChange(callback: AuthChangeCallback): () => void {\n this._listeners.add(callback)\n return () => {\n this._listeners.delete(callback)\n }\n }\n\n private _notify(): void {\n for (const cb of this._listeners) {\n try {\n cb(this._token, this._record)\n } catch {\n // listener errors must not break notification\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// FileService\n// ---------------------------------------------------------------------------\n\nexport class FileService {\n private readonly _baseUrl: string\n\n constructor(baseUrl: string) {\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n }\n\n /**\n * Build a full URL to a record file.\n * Compatible with PocketBase's pb.files.getURL().\n */\n getURL(record: BaseRecord, filename: string, options?: FileOptions): string {\n if (!filename || !record.id) return ''\n\n const collectionId = (record.collectionId ?? record.collectionName ?? '') as string\n const parts = [\n this._baseUrl,\n 'api',\n 'files',\n encodeURIComponent(collectionId),\n encodeURIComponent(record.id),\n encodeURIComponent(filename),\n ]\n\n let url = parts.join('/')\n\n const params = new URLSearchParams()\n if (options?.thumb) params.set('thumb', options.thumb)\n if (options?.token) params.set('token', options.token)\n const qs = params.toString()\n if (qs) url += '?' + qs\n\n return url\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientConfig\n// ---------------------------------------------------------------------------\n\nexport interface ClientConfig {\n /** Base URL of the Hanzo Base instance (e.g. \"https://myapp.hanzo.ai\"). */\n url: string\n /** Optional external auth store. Defaults to in-memory store. */\n authStore?: AuthStore\n}\n\nexport interface ListOptions {\n filter?: string\n sort?: string\n expand?: string\n fields?: string\n page?: number\n perPage?: number\n}\n\nexport interface ListResult<T = BaseRecord> {\n page: number\n perPage: number\n totalItems: number\n totalPages: number\n items: T[]\n}\n\n// ---------------------------------------------------------------------------\n// BaseClient\n// ---------------------------------------------------------------------------\n\nexport class BaseClient {\n readonly url: string\n readonly authStore: AuthStore\n readonly store: QueryStore\n readonly realtime: RealtimeService\n readonly files: FileService\n\n private readonly _versionTracker: VersionTracker\n private readonly _collections = new Map<string, CollectionService>()\n\n /**\n * Create a BaseClient.\n *\n * Accepts either a config object or a plain URL string for convenience:\n * new BaseClient('https://myapp.hanzo.ai')\n * new BaseClient({ url: 'https://myapp.hanzo.ai' })\n */\n constructor(configOrUrl: ClientConfig | string) {\n const config: ClientConfig =\n typeof configOrUrl === 'string' ? { url: configOrUrl } : configOrUrl\n\n this.url = config.url.replace(/\\/$/, '')\n this.authStore = config.authStore ?? new MemoryAuthStore()\n this.store = new QueryStore()\n this.realtime = new RealtimeService(this.url, () => this.authStore.token)\n this.files = new FileService(this.url)\n this._versionTracker = new VersionTracker()\n\n // Sync identity hash when auth changes.\n this.authStore.onChange((token) => {\n this._versionTracker.setIdentity(\n token ? VersionTracker.hashIdentity(token) : 0,\n )\n })\n }\n\n // ---- PocketBase-compatible collection() API -----------------------------\n\n /** Get or create a CollectionService for the given name/id. */\n collection(nameOrId: string): CollectionService {\n let svc = this._collections.get(nameOrId)\n if (!svc) {\n svc = new CollectionService(\n nameOrId,\n this.url,\n () => this.authStore.token,\n (token, record) => this.authStore.save(token, record),\n this.store,\n this.realtime,\n )\n this._collections.set(nameOrId, svc)\n }\n return svc\n }\n\n // ---- State version ------------------------------------------------------\n\n /** Current state version from the QueryStore's internal tracker. */\n get version() {\n return this.store.version\n }\n\n // ---- Direct convenience API (kept for backwards compatibility) ----------\n\n private _headers(): Record<string, string> {\n const h: Record<string, string> = { 'Content-Type': 'application/json' }\n if (this.authStore.token) {\n h['Authorization'] = this.authStore.token\n }\n return h\n }\n\n private async _request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.url}${path}`, {\n method,\n headers: this._headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text()\n let detail: unknown\n try {\n detail = JSON.parse(text)\n } catch {\n detail = text\n }\n throw new BaseClientError(res.status, detail)\n }\n\n if (res.status === 204) return undefined as T\n\n return res.json() as Promise<T>\n }\n\n async list(collection: string, options?: ListOptions): Promise<ListResult> {\n const params = new URLSearchParams()\n if (options?.filter) params.set('filter', options.filter)\n if (options?.sort) params.set('sort', options.sort)\n if (options?.expand) params.set('expand', options.expand)\n if (options?.fields) params.set('fields', options.fields)\n if (options?.page) params.set('page', String(options.page))\n if (options?.perPage) params.set('perPage', String(options.perPage))\n\n const qs = params.toString()\n const path = `/api/collections/${encodeURIComponent(collection)}/records${qs ? '?' + qs : ''}`\n const result = await this._request<ListResult>('GET', path)\n\n this.store.setQuery(collection, options?.filter ?? '', result.items)\n return result\n }\n\n async getOne(collection: string, id: string, options?: Pick<ListOptions, 'expand' | 'fields'>): Promise<BaseRecord> {\n const params = new URLSearchParams()\n if (options?.expand) params.set('expand', options.expand)\n if (options?.fields) params.set('fields', options.fields)\n const qs = params.toString()\n const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n return this._request<BaseRecord>('GET', path)\n }\n\n async create(collection: string, data: Record<string, unknown>): Promise<BaseRecord> {\n const path = `/api/collections/${encodeURIComponent(collection)}/records`\n const record = await this._request<BaseRecord>('POST', path, data)\n this.store.applyServerUpdate(collection, 'create', record)\n return record\n }\n\n async update(collection: string, id: string, data: Record<string, unknown>): Promise<BaseRecord> {\n const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`\n const record = await this._request<BaseRecord>('PATCH', path, data)\n this.store.applyServerUpdate(collection, 'update', record)\n return record\n }\n\n async delete(collection: string, id: string): Promise<void> {\n const path = `/api/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`\n await this._request<void>('DELETE', path)\n this.store.applyServerUpdate(collection, 'delete', { id } as BaseRecord)\n }\n\n // ---- Auth (direct convenience) ------------------------------------------\n\n async signInWithPassword(\n collection: string,\n identity: string,\n password: string,\n ): Promise<{ token: string; record: BaseRecord }> {\n const path = `/api/collections/${encodeURIComponent(collection)}/auth-with-password`\n const result = await this._request<{ token: string; record: BaseRecord }>('POST', path, {\n identity,\n password,\n })\n this.authStore.save(result.token, result.record)\n return result\n }\n\n async signUp(\n collection: string,\n data: Record<string, unknown>,\n ): Promise<BaseRecord> {\n return this.create(collection, data)\n }\n\n async refreshAuth(collection: string): Promise<{ token: string; record: BaseRecord }> {\n const path = `/api/collections/${encodeURIComponent(collection)}/auth-refresh`\n const result = await this._request<{ token: string; record: BaseRecord }>('POST', path)\n this.authStore.save(result.token, result.record)\n return result\n }\n\n signOut(): void {\n this.authStore.clear()\n }\n\n // ---- Raw request --------------------------------------------------------\n\n /**\n * Send a raw request to the Base API.\n * Convenience for endpoints not covered by CollectionService.\n */\n async send<T = unknown>(\n path: string,\n options: {\n method?: string\n headers?: Record<string, string>\n body?: string | FormData\n query?: Record<string, string>\n signal?: AbortSignal\n } = {},\n ): Promise<T> {\n const method = options.method ?? 'GET'\n let url = `${this.url}${path}`\n\n if (options.query) {\n const params = new URLSearchParams(options.query)\n url += '?' + params.toString()\n }\n\n const headers: Record<string, string> = { ...options.headers }\n if (this.authStore.token) {\n headers['Authorization'] = this.authStore.token\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: options.body,\n signal: options.signal,\n })\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}))\n throw new BaseClientError(\n response.status,\n data,\n )\n }\n\n if (response.status === 204) return undefined as T\n\n return response.json() as Promise<T>\n }\n\n // ---- Health check -------------------------------------------------------\n\n async health(): Promise<{ code: number; message: string }> {\n return this.send('/api/health')\n }\n\n // ---- Realtime convenience -----------------------------------------------\n\n /**\n * Subscribe to realtime events for a collection topic.\n * Also wires events into the QueryStore automatically.\n */\n subscribeAndSync(collection: string, topic = '*', callback?: (e: RealtimeEvent) => void): () => void {\n return this.realtime.subscribe(collection, topic, (event) => {\n this.store.applyServerUpdate(collection, event.action, event.record)\n callback?.(event)\n })\n }\n\n // ---- Cleanup ------------------------------------------------------------\n\n /** Disconnect realtime and clear caches. */\n disconnect(): void {\n this.realtime.disconnect()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class BaseClientError extends Error {\n readonly status: number\n readonly detail: unknown\n\n constructor(status: number, detail: unknown) {\n super(`BaseClient error ${status}`)\n this.name = 'BaseClientError'\n this.status = status\n this.detail = detail\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/core/state.ts","../src/core/store.ts","../src/core/realtime.ts","../src/core/collection.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"chunk-3WOGNODW.js","sourcesContent":["/**\n * State version tracking (Convex-inspired).\n *\n * Each query result is tagged with a StateVersion so the client can\n * detect ordering, replay transitions, and drive optimistic rollbacks.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface StateVersion {\n /** Monotonically increasing counter bumped on every query-set change. */\n querySet: number\n /** Server timestamp (microseconds since epoch) of the latest known event. */\n ts: bigint\n /** Identity hash -- changes when the authenticated user changes. */\n identity: number\n}\n\nexport type Modification =\n | { type: 'QueryUpdated'; collection: string; record: BaseRecord }\n | { type: 'QueryRemoved'; collection: string; id: string }\n | { type: 'QueryFailed'; collection: string; error: string }\n\nexport interface Transition {\n startVersion: StateVersion\n endVersion: StateVersion\n modifications: Modification[]\n}\n\n/** Minimal record shape that every Base record satisfies. */\nexport interface BaseRecord {\n id: string\n collectionId?: string\n collectionName?: string\n created?: string\n updated?: string\n [key: string]: unknown\n}\n\n// ---------------------------------------------------------------------------\n// VersionTracker\n// ---------------------------------------------------------------------------\n\nexport class VersionTracker {\n private _version: StateVersion\n private _history: Transition[] = []\n private readonly _maxHistory: number\n\n constructor(maxHistory = 128) {\n this._version = { querySet: 0, ts: 0n, identity: 0 }\n this._maxHistory = maxHistory\n }\n\n get current(): Readonly<StateVersion> {\n return { ...this._version }\n }\n\n get history(): readonly Transition[] {\n return this._history\n }\n\n /**\n * Advance the version and record a transition.\n * Returns the new version.\n */\n advance(modifications: Modification[], serverTs?: bigint): StateVersion {\n const start = { ...this._version }\n\n this._version = {\n querySet: this._version.querySet + 1,\n ts: serverTs ?? this._version.ts,\n identity: this._version.identity,\n }\n\n const transition: Transition = {\n startVersion: start,\n endVersion: { ...this._version },\n modifications,\n }\n\n this._history.push(transition)\n if (this._history.length > this._maxHistory) {\n this._history.shift()\n }\n\n return { ...this._version }\n }\n\n /** Update identity hash (e.g. on auth change). */\n setIdentity(identity: number): void {\n this._version = { ...this._version, identity }\n }\n\n /** Update the high-water timestamp without bumping querySet. */\n updateTimestamp(ts: bigint): void {\n if (ts > this._version.ts) {\n this._version = { ...this._version, ts }\n }\n }\n\n /** Simple FNV-1a-like hash for identity derivation. */\n static hashIdentity(token: string): number {\n let h = 0x811c9dc5\n for (let i = 0; i < token.length; i++) {\n h ^= token.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return h >>> 0\n }\n}\n","/**\n * QueryStore -- manages server state + optimistic overlay.\n *\n * Subscribers are notified whenever the effective (server + optimistic)\n * state for their query changes. Optimistic mutations are tracked by\n * mutationId so they can be rolled back individually.\n */\n\nimport type { BaseRecord, Modification } from './state.js'\nimport { VersionTracker } from './state.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface QueryKey {\n collection: string\n filter: string\n}\n\nexport type StoreCallback = (records: BaseRecord[]) => void\n\ninterface OptimisticEntry {\n mutationId: string\n collection: string\n /** null means \"delete this id\" */\n record: BaseRecord | null\n deletedId?: string\n createdAt: number\n}\n\ninterface QuerySlot {\n key: QueryKey\n serverRecords: BaseRecord[]\n listeners: Set<StoreCallback>\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction queryHash(collection: string, filter: string): string {\n return `${collection}::${filter}`\n}\n\nfunction mergeOptimistic(\n server: BaseRecord[],\n optimistic: OptimisticEntry[],\n collection: string,\n): BaseRecord[] {\n // Start with a mutable copy keyed by id.\n const map = new Map<string, BaseRecord>()\n for (const r of server) {\n map.set(r.id, r)\n }\n\n for (const entry of optimistic) {\n if (entry.collection !== collection) continue\n if (entry.record === null && entry.deletedId) {\n map.delete(entry.deletedId)\n } else if (entry.record) {\n map.set(entry.record.id, entry.record)\n }\n }\n\n return Array.from(map.values())\n}\n\n// ---------------------------------------------------------------------------\n// QueryStore\n// ---------------------------------------------------------------------------\n\nexport class QueryStore {\n private readonly _slots = new Map<string, QuerySlot>()\n private readonly _optimistic: OptimisticEntry[] = []\n private readonly _version = new VersionTracker()\n\n get version() {\n return this._version.current\n }\n\n // ---- Query cache --------------------------------------------------------\n\n /** Return cached effective (server+optimistic) result or undefined. */\n getQuery(collection: string, filter = ''): BaseRecord[] | undefined {\n const slot = this._slots.get(queryHash(collection, filter))\n if (!slot) return undefined\n return mergeOptimistic(slot.serverRecords, this._optimistic, collection)\n }\n\n /** Overwrite the server-truth cache for a query and notify. */\n setQuery(collection: string, filter: string, data: BaseRecord[]): void {\n const hash = queryHash(collection, filter)\n let slot = this._slots.get(hash)\n if (!slot) {\n slot = { key: { collection, filter }, serverRecords: [], listeners: new Set() }\n this._slots.set(hash, slot)\n }\n slot.serverRecords = data\n\n this._version.advance(\n data.map((r) => ({ type: 'QueryUpdated' as const, collection, record: r })),\n )\n\n this._notify(slot)\n }\n\n // ---- Optimistic mutations -----------------------------------------------\n\n /** Apply an optimistic create/update. Returns a mutationId for rollback. */\n optimisticSet(collection: string, record: BaseRecord): string {\n const mutationId = `opt_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`\n this._optimistic.push({\n mutationId,\n collection,\n record,\n createdAt: Date.now(),\n })\n this._notifyCollection(collection)\n return mutationId\n }\n\n /** Apply an optimistic delete. */\n optimisticDelete(collection: string, id: string): string {\n const mutationId = `opt_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`\n this._optimistic.push({\n mutationId,\n collection,\n record: null,\n deletedId: id,\n createdAt: Date.now(),\n })\n this._notifyCollection(collection)\n return mutationId\n }\n\n /** Remove a single optimistic mutation and re-derive. */\n rollbackOptimistic(mutationId: string): void {\n const idx = this._optimistic.findIndex((e) => e.mutationId === mutationId)\n if (idx === -1) return\n const entry = this._optimistic[idx]\n this._optimistic.splice(idx, 1)\n this._notifyCollection(entry.collection)\n }\n\n /** Drop all optimistic entries for a collection. */\n clearOptimistic(collection: string): void {\n for (let i = this._optimistic.length - 1; i >= 0; i--) {\n if (this._optimistic[i].collection === collection) {\n this._optimistic.splice(i, 1)\n }\n }\n this._notifyCollection(collection)\n }\n\n // ---- Server event ingestion ---------------------------------------------\n\n /**\n * Apply a realtime SSE event from the server.\n * `action` is one of \"create\", \"update\", \"delete\".\n */\n applyServerUpdate(\n collection: string,\n action: 'create' | 'update' | 'delete',\n record: BaseRecord,\n ): void {\n const mods: Modification[] = []\n\n for (const slot of this._slots.values()) {\n if (slot.key.collection !== collection) continue\n\n if (action === 'delete') {\n const before = slot.serverRecords.length\n slot.serverRecords = slot.serverRecords.filter((r) => r.id !== record.id)\n if (slot.serverRecords.length !== before) {\n mods.push({ type: 'QueryRemoved', collection, id: record.id })\n }\n } else {\n // create or update -- upsert\n const idx = slot.serverRecords.findIndex((r) => r.id === record.id)\n if (idx >= 0) {\n slot.serverRecords[idx] = record\n } else {\n slot.serverRecords.push(record)\n }\n mods.push({ type: 'QueryUpdated', collection, record })\n }\n }\n\n if (mods.length > 0) {\n const ts = record.updated\n ? BigInt(new Date(record.updated).getTime()) * 1000n\n : undefined\n this._version.advance(mods, ts)\n }\n\n this._notifyCollection(collection)\n }\n\n // ---- Subscriptions ------------------------------------------------------\n\n /** Subscribe to effective-state changes for a query. Returns unsubscribe. */\n subscribe(collection: string, filter: string, callback: StoreCallback): () => void {\n const hash = queryHash(collection, filter)\n let slot = this._slots.get(hash)\n if (!slot) {\n slot = { key: { collection, filter }, serverRecords: [], listeners: new Set() }\n this._slots.set(hash, slot)\n }\n slot.listeners.add(callback)\n return () => {\n slot!.listeners.delete(callback)\n // GC empty slots\n if (slot!.listeners.size === 0 && slot!.serverRecords.length === 0) {\n this._slots.delete(hash)\n }\n }\n }\n\n // ---- Internal -----------------------------------------------------------\n\n private _notify(slot: QuerySlot): void {\n if (slot.listeners.size === 0) return\n const effective = mergeOptimistic(slot.serverRecords, this._optimistic, slot.key.collection)\n for (const cb of slot.listeners) {\n try {\n cb(effective)\n } catch {\n // listener errors must not break the store\n }\n }\n }\n\n private _notifyCollection(collection: string): void {\n for (const slot of this._slots.values()) {\n if (slot.key.collection === collection) {\n this._notify(slot)\n }\n }\n }\n}\n","/**\n * RealtimeService -- SSE-based subscription manager.\n *\n * Features:\n * - Query deduplication via hash(collection+topic) with reference counting\n * - Auto-reconnect with exponential backoff\n * - Max observed timestamp tracking\n * - Connection state notifications\n */\n\nimport type { BaseRecord } from './state.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ConnectionState = 'disconnected' | 'connecting' | 'connected'\n\nexport interface RealtimeEvent {\n action: 'create' | 'update' | 'delete'\n record: BaseRecord\n}\n\nexport type RealtimeCallback = (event: RealtimeEvent) => void\nexport type ConnectionCallback = (state: ConnectionState) => void\n\ninterface Subscription {\n collection: string\n topic: string\n callbacks: Set<RealtimeCallback>\n}\n\n// ---------------------------------------------------------------------------\n// RealtimeService\n// ---------------------------------------------------------------------------\n\nexport class RealtimeService {\n private readonly _baseUrl: string\n private readonly _getToken: () => string\n\n private _eventSource: EventSource | null = null\n private _state: ConnectionState = 'disconnected'\n private _connectionListeners = new Set<ConnectionCallback>()\n\n /** Dedup map: hash -> Subscription. */\n private _subscriptions = new Map<string, Subscription>()\n\n /** SSE client id assigned by the server on connect. */\n private _clientId: string | null = null\n\n /** Reconnect state. */\n private _reconnectAttempts = 0\n private _reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private _maxReconnectDelay = 30_000\n private _baseReconnectDelay = 500\n\n /** High-water mark of observed server timestamps. */\n private _maxTimestamp = 0n\n\n /** Set to true when disconnect() is called explicitly. */\n private _intentionalDisconnect = false\n\n constructor(baseUrl: string, getToken: () => string) {\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n this._getToken = getToken\n }\n\n // ---- Public API ---------------------------------------------------------\n\n get state(): ConnectionState {\n return this._state\n }\n\n get maxTimestamp(): bigint {\n return this._maxTimestamp\n }\n\n /**\n * Subscribe to realtime events for a collection topic.\n *\n * Topic is usually \"*\" (all changes) or a record id.\n * Returns an unsubscribe function.\n */\n subscribe(\n collection: string,\n topic: string,\n callback: RealtimeCallback,\n ): () => void {\n const hash = this._hash(collection, topic)\n let sub = this._subscriptions.get(hash)\n\n if (!sub) {\n sub = { collection, topic, callbacks: new Set() }\n this._subscriptions.set(hash, sub)\n }\n sub.callbacks.add(callback)\n\n // If this is the first subscription, connect.\n if (this._subscriptions.size === 1 && !this._eventSource) {\n this._connect()\n } else if (this._clientId) {\n // Already connected -- submit this subscription to the server.\n this._submitSubscriptions()\n }\n\n return () => {\n sub!.callbacks.delete(callback)\n if (sub!.callbacks.size === 0) {\n this._subscriptions.delete(hash)\n if (this._clientId) {\n this._submitSubscriptions()\n }\n }\n // If no subscriptions remain, disconnect.\n if (this._subscriptions.size === 0) {\n this.disconnect()\n }\n }\n }\n\n /** Remove all subscribers for a topic, or all topics if none specified. */\n unsubscribe(topic?: string): void {\n if (topic) {\n this._subscriptions.delete(topic)\n } else {\n this._subscriptions.clear()\n }\n if (this._subscriptions.size === 0) {\n this.disconnect()\n }\n }\n\n /** Register a connection-state listener. Returns unsubscribe. */\n onConnectionChange(callback: ConnectionCallback): () => void {\n this._connectionListeners.add(callback)\n return () => {\n this._connectionListeners.delete(callback)\n }\n }\n\n /** Explicitly disconnect. */\n disconnect(): void {\n this._intentionalDisconnect = true\n this._clearReconnect()\n if (this._eventSource) {\n this._eventSource.close()\n this._eventSource = null\n }\n this._clientId = null\n this._setState('disconnected')\n }\n\n // ---- Connection ---------------------------------------------------------\n\n private _connect(): void {\n if (this._eventSource) return\n this._intentionalDisconnect = false\n this._setState('connecting')\n\n const url = `${this._baseUrl}/v1/realtime`\n this._eventSource = new EventSource(url)\n\n this._eventSource.addEventListener('CONNECT', (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data) as { clientId: string }\n this._clientId = data.clientId\n this._reconnectAttempts = 0\n this._setState('connected')\n this._submitSubscriptions()\n } catch {\n // malformed connect event\n }\n })\n\n // Listen for all SSE events. The server sends events named after\n // the collection, e.g. event: \"posts\".\n this._eventSource.onmessage = (e: MessageEvent) => {\n this._handleMessage(e)\n }\n\n // The server sends named events for each collection.\n // We use the generic handler plus specific ones registered dynamically.\n this._eventSource.onerror = () => {\n this._eventSource?.close()\n this._eventSource = null\n this._clientId = null\n this._setState('disconnected')\n\n if (!this._intentionalDisconnect) {\n this._scheduleReconnect()\n }\n }\n }\n\n private _handleMessage(e: MessageEvent): void {\n let payload: { action: string; record: BaseRecord }\n try {\n payload = JSON.parse(e.data)\n } catch {\n return\n }\n\n const action = payload.action as RealtimeEvent['action']\n const record = payload.record\n if (!record?.id) return\n\n // Track timestamp high-water mark.\n const ts = record.updated ?? record.created\n if (ts) {\n const n = BigInt(new Date(ts).getTime()) * 1000n\n if (n > this._maxTimestamp) {\n this._maxTimestamp = n\n }\n }\n\n // Fan out to matching subscriptions.\n const collectionName = record.collectionName ?? ''\n for (const sub of this._subscriptions.values()) {\n if (sub.collection !== collectionName) continue\n if (sub.topic !== '*' && sub.topic !== record.id) continue\n const event: RealtimeEvent = { action, record }\n for (const cb of sub.callbacks) {\n try {\n cb(event)\n } catch {\n // subscriber errors must not break fanout\n }\n }\n }\n }\n\n /** Submit current subscription set to the server via POST. */\n private async _submitSubscriptions(): Promise<void> {\n if (!this._clientId) return\n\n const topics: string[] = []\n for (const sub of this._subscriptions.values()) {\n topics.push(`${sub.collection}/${sub.topic}`)\n }\n\n const token = this._getToken()\n try {\n await fetch(`${this._baseUrl}/v1/realtime`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: token } : {}),\n },\n body: JSON.stringify({\n clientId: this._clientId,\n subscriptions: topics,\n }),\n })\n } catch {\n // will retry on next reconnect\n }\n }\n\n // ---- Reconnect ----------------------------------------------------------\n\n private _scheduleReconnect(): void {\n this._clearReconnect()\n const delay = Math.min(\n this._baseReconnectDelay * Math.pow(2, this._reconnectAttempts),\n this._maxReconnectDelay,\n )\n // Add jitter: +/- 25%\n const jitter = delay * (0.75 + Math.random() * 0.5)\n this._reconnectAttempts++\n\n this._reconnectTimer = setTimeout(() => {\n this._reconnectTimer = null\n this._connect()\n }, jitter)\n }\n\n private _clearReconnect(): void {\n if (this._reconnectTimer !== null) {\n clearTimeout(this._reconnectTimer)\n this._reconnectTimer = null\n }\n }\n\n // ---- State --------------------------------------------------------------\n\n private _setState(state: ConnectionState): void {\n if (this._state === state) return\n this._state = state\n for (const cb of this._connectionListeners) {\n try {\n cb(state)\n } catch {\n // listener errors must not break notification\n }\n }\n }\n\n // ---- Helpers ------------------------------------------------------------\n\n private _hash(collection: string, topic: string): string {\n return `${collection}::${topic}`\n }\n}\n","/**\n * CollectionService -- typed CRUD + auth + realtime for a single collection.\n *\n * API-compatible with the upstream RecordService interface, extended with\n * reactive features (subscribe/unsubscribe, optimistic writes).\n */\n\nimport type { BaseRecord } from './state.js'\nimport type { QueryStore } from './store.js'\nimport type { RealtimeService, RealtimeCallback } from './realtime.js'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface ListResult<T = BaseRecord> {\n page: number\n perPage: number\n totalItems: number\n totalPages: number\n items: T[]\n}\n\nexport interface RecordQueryOptions {\n filter?: string\n sort?: string\n expand?: string\n fields?: string\n headers?: Record<string, string>\n /** Extra query params merged into the URL. */\n query?: Record<string, string>\n /** Request-scoped AbortSignal. */\n signal?: AbortSignal\n}\n\nexport interface RecordFullListOptions extends RecordQueryOptions {\n /** Batch size for pagination (default 200). */\n batch?: number\n}\n\nexport interface FileOptions {\n thumb?: string\n token?: string\n}\n\nexport interface AuthResponse<T = BaseRecord> {\n token: string\n record: T\n}\n\nexport interface OAuth2Options {\n provider: string\n code: string\n codeVerifier: string\n redirectUrl: string\n createData?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// CollectionService\n// ---------------------------------------------------------------------------\n\nexport class CollectionService {\n readonly collectionIdOrName: string\n\n private readonly _baseUrl: string\n private readonly _getToken: () => string\n private readonly _setAuth: (token: string, record: BaseRecord) => void\n private readonly _store: QueryStore\n private readonly _realtime: RealtimeService\n\n constructor(\n collectionIdOrName: string,\n baseUrl: string,\n getToken: () => string,\n setAuth: (token: string, record: BaseRecord) => void,\n store: QueryStore,\n realtime: RealtimeService,\n ) {\n this.collectionIdOrName = collectionIdOrName\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n this._getToken = getToken\n this._setAuth = setAuth\n this._store = store\n this._realtime = realtime\n }\n\n // ---- CRUD ---------------------------------------------------------------\n\n async getList<T extends BaseRecord = BaseRecord>(\n page = 1,\n perPage = 30,\n options?: RecordQueryOptions,\n ): Promise<ListResult<T>> {\n const params = new URLSearchParams()\n params.set('page', String(page))\n params.set('perPage', String(perPage))\n this._applyOptions(params, options)\n\n const result = await this._request<ListResult<T>>(\n 'GET',\n `${this._collectionPath()}/records?${params}`,\n undefined,\n options,\n )\n\n // Cache in store.\n const cacheFilter = options?.filter ?? ''\n this._store.setQuery(\n this.collectionIdOrName,\n cacheFilter,\n result.items as unknown as BaseRecord[],\n )\n\n return result\n }\n\n async getFullList<T extends BaseRecord = BaseRecord>(\n options?: RecordFullListOptions,\n ): Promise<T[]> {\n const batch = options?.batch ?? 200\n let page = 1\n let all: T[] = []\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const result = await this.getList<T>(page, batch, options)\n all = all.concat(result.items)\n if (all.length >= result.totalItems || result.items.length < batch) {\n break\n }\n page++\n }\n\n return all\n }\n\n async getOne<T extends BaseRecord = BaseRecord>(\n id: string,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n return this._request<T>('GET', path, undefined, options)\n }\n\n async getFirstListItem<T extends BaseRecord = BaseRecord>(\n filter: string,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const opts = { ...options, filter }\n const result = await this.getList<T>(1, 1, opts)\n if (result.items.length === 0) {\n throw new ClientResponseError({\n url: this._baseUrl,\n status: 404,\n data: { message: 'The requested resource wasn\\'t found.' },\n })\n }\n return result.items[0]\n }\n\n async create<T extends BaseRecord = BaseRecord>(\n data: Record<string, unknown> | FormData,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records${qs ? '?' + qs : ''}`\n\n // Optimistic: generate temp id.\n let mutationId: string | undefined\n if (!(data instanceof FormData) && typeof data === 'object') {\n const tempId = `__temp_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`\n const optimistic: BaseRecord = {\n id: tempId,\n collectionName: this.collectionIdOrName,\n ...(data as Record<string, unknown>),\n }\n mutationId = this._store.optimisticSet(this.collectionIdOrName, optimistic)\n }\n\n try {\n const body = data instanceof FormData ? data : JSON.stringify(data)\n const contentType = data instanceof FormData ? undefined : 'application/json'\n const record = await this._request<T>('POST', path, body, options, contentType)\n\n // Replace optimistic entry with real server record.\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n this._store.applyServerUpdate(this.collectionIdOrName, 'create', record as unknown as BaseRecord)\n return record\n } catch (err) {\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n throw err\n }\n }\n\n async update<T extends BaseRecord = BaseRecord>(\n id: string,\n data: Record<string, unknown> | FormData,\n options?: RecordQueryOptions,\n ): Promise<T> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n\n // Optimistic update.\n let mutationId: string | undefined\n if (!(data instanceof FormData) && typeof data === 'object') {\n const optimistic: BaseRecord = {\n id,\n collectionName: this.collectionIdOrName,\n ...(data as Record<string, unknown>),\n }\n mutationId = this._store.optimisticSet(this.collectionIdOrName, optimistic)\n }\n\n try {\n const body = data instanceof FormData ? data : JSON.stringify(data)\n const contentType = data instanceof FormData ? undefined : 'application/json'\n const record = await this._request<T>('PATCH', path, body, options, contentType)\n\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n this._store.applyServerUpdate(this.collectionIdOrName, 'update', record as unknown as BaseRecord)\n return record\n } catch (err) {\n if (mutationId) {\n this._store.rollbackOptimistic(mutationId)\n }\n throw err\n }\n }\n\n async delete(id: string, options?: RecordQueryOptions): Promise<boolean> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n\n // Optimistic delete.\n const mutationId = this._store.optimisticDelete(this.collectionIdOrName, id)\n\n try {\n await this._request<void>('DELETE', path, undefined, options)\n this._store.rollbackOptimistic(mutationId)\n this._store.applyServerUpdate(this.collectionIdOrName, 'delete', { id } as BaseRecord)\n return true\n } catch (err) {\n this._store.rollbackOptimistic(mutationId)\n throw err\n }\n }\n\n // ---- Realtime -----------------------------------------------------------\n\n /**\n * Subscribe to realtime events for this collection.\n * `topic` is \"*\" for all changes or a specific record id.\n */\n subscribe(topic: string, callback: RealtimeCallback): () => void {\n return this._realtime.subscribe(this.collectionIdOrName, topic, callback)\n }\n\n /** Unsubscribe from a specific topic or all topics for this collection. */\n unsubscribe(topic?: string): void {\n this._realtime.unsubscribe(\n topic ? `${this.collectionIdOrName}/${topic}` : this.collectionIdOrName,\n )\n }\n\n // ---- Auth methods (for auth collections) --------------------------------\n\n async authWithPassword<T extends BaseRecord = BaseRecord>(\n identity: string,\n password: string,\n options?: RecordQueryOptions,\n ): Promise<AuthResponse<T>> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/auth-with-password${qs ? '?' + qs : ''}`\n\n const result = await this._request<AuthResponse<T>>(\n 'POST',\n path,\n JSON.stringify({ identity, password }),\n options,\n 'application/json',\n )\n\n this._setAuth(result.token, result.record as unknown as BaseRecord)\n return result\n }\n\n async authWithOAuth2<T extends BaseRecord = BaseRecord>(\n oauthOptions: OAuth2Options,\n options?: RecordQueryOptions,\n ): Promise<AuthResponse<T>> {\n const params = new URLSearchParams()\n this._applyOptions(params, options)\n const qs = params.toString()\n const path = `${this._collectionPath()}/auth-with-oauth2${qs ? '?' + qs : ''}`\n\n const result = await this._request<AuthResponse<T>>(\n 'POST',\n path,\n JSON.stringify(oauthOptions),\n options,\n 'application/json',\n )\n\n this._setAuth(result.token, result.record as unknown as BaseRecord)\n return result\n }\n\n async requestVerification(email: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/request-verification`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ email }),\n options,\n 'application/json',\n )\n return true\n }\n\n async confirmVerification(token: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/confirm-verification`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ token }),\n options,\n 'application/json',\n )\n return true\n }\n\n async requestPasswordReset(email: string, options?: RecordQueryOptions): Promise<boolean> {\n const path = `${this._collectionPath()}/request-password-reset`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ email }),\n options,\n 'application/json',\n )\n return true\n }\n\n async confirmPasswordReset(\n token: string,\n password: string,\n passwordConfirm: string,\n options?: RecordQueryOptions,\n ): Promise<boolean> {\n const path = `${this._collectionPath()}/confirm-password-reset`\n await this._request<void>(\n 'POST',\n path,\n JSON.stringify({ token, password, passwordConfirm }),\n options,\n 'application/json',\n )\n return true\n }\n\n // ---- Internal -----------------------------------------------------------\n\n private _collectionPath(): string {\n return `/v1/collections/${encodeURIComponent(this.collectionIdOrName)}`\n }\n\n private _applyOptions(params: URLSearchParams, options?: RecordQueryOptions): void {\n if (!options) return\n if (options.filter) params.set('filter', options.filter)\n if (options.sort) params.set('sort', options.sort)\n if (options.expand) params.set('expand', options.expand)\n if (options.fields) params.set('fields', options.fields)\n if (options.query) {\n for (const [k, v] of Object.entries(options.query)) {\n params.set(k, v)\n }\n }\n }\n\n private async _request<T>(\n method: string,\n path: string,\n body?: string | FormData,\n options?: RecordQueryOptions,\n contentType?: string,\n ): Promise<T> {\n const url = `${this._baseUrl}${path}`\n const token = this._getToken()\n\n const headers: Record<string, string> = {\n ...(options?.headers ?? {}),\n }\n if (token) {\n headers['Authorization'] = token\n }\n if (contentType) {\n headers['Content-Type'] = contentType\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ?? undefined,\n signal: options?.signal,\n })\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}))\n throw new ClientResponseError({\n url,\n status: response.status,\n data,\n })\n }\n\n // DELETE returns 204 with no body.\n if (response.status === 204) {\n return undefined as T\n }\n\n return response.json() as Promise<T>\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientResponseError\n// ---------------------------------------------------------------------------\n\nexport interface ClientResponseErrorData {\n url: string\n status: number\n data: Record<string, unknown>\n}\n\nexport class ClientResponseError extends Error {\n url: string\n status: number\n data: Record<string, unknown>\n isAbort: boolean\n\n constructor(errorData: ClientResponseErrorData) {\n const message =\n (errorData.data?.message as string) ??\n `ClientResponseError ${errorData.status}`\n super(message)\n this.name = 'ClientResponseError'\n this.url = errorData.url\n this.status = errorData.status\n this.data = errorData.data\n this.isAbort = errorData.status === 0\n }\n\n toJSON(): ClientResponseErrorData {\n return { url: this.url, status: this.status, data: this.data }\n }\n}\n","/**\n * BaseClient -- main entry point for @hanzoai/base.\n *\n * Two API surfaces:\n *\n * 1. Base-compatible: client.collection('posts').getList(...)\n * 2. Direct (convenience): client.list('posts', { filter: '...' })\n *\n * Both share the same QueryStore, RealtimeService, and AuthStore.\n */\n\nimport type { BaseRecord } from './state.js'\nimport { VersionTracker } from './state.js'\nimport { QueryStore } from './store.js'\nimport { RealtimeService, type RealtimeEvent } from './realtime.js'\nimport { CollectionService, type FileOptions } from './collection.js'\n\n// ---------------------------------------------------------------------------\n// AuthStore\n// ---------------------------------------------------------------------------\n\nexport interface AuthStore {\n token: string\n record: BaseRecord | null\n onChange(callback: (token: string, record: BaseRecord | null) => void): () => void\n save(token: string, record: BaseRecord | null): void\n clear(): void\n readonly isValid: boolean\n}\n\nexport type AuthChangeCallback = (token: string, record: BaseRecord | null) => void\n\n/**\n * Default in-memory auth store.\n * Validates JWT exp claim without external dependencies.\n */\nexport class MemoryAuthStore implements AuthStore {\n private _token = ''\n private _record: BaseRecord | null = null\n private _listeners = new Set<AuthChangeCallback>()\n\n get token(): string {\n return this._token\n }\n\n get record(): BaseRecord | null {\n return this._record\n }\n\n get isValid(): boolean {\n if (!this._token) return false\n try {\n const parts = this._token.split('.')\n if (parts.length !== 3) return false\n const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')))\n if (typeof payload.exp === 'number') {\n return payload.exp > Date.now() / 1000\n }\n return true\n } catch {\n return false\n }\n }\n\n save(token: string, record: BaseRecord | null): void {\n this._token = token\n this._record = record\n this._notify()\n }\n\n clear(): void {\n this._token = ''\n this._record = null\n this._notify()\n }\n\n onChange(callback: AuthChangeCallback): () => void {\n this._listeners.add(callback)\n return () => {\n this._listeners.delete(callback)\n }\n }\n\n private _notify(): void {\n for (const cb of this._listeners) {\n try {\n cb(this._token, this._record)\n } catch {\n // listener errors must not break notification\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// FileService\n// ---------------------------------------------------------------------------\n\nexport class FileService {\n private readonly _baseUrl: string\n\n constructor(baseUrl: string) {\n this._baseUrl = baseUrl.replace(/\\/$/, '')\n }\n\n /**\n * Build a full URL to a record file.\n * Compatible with Base's files.getURL().\n */\n getURL(record: BaseRecord, filename: string, options?: FileOptions): string {\n if (!filename || !record.id) return ''\n\n const collectionId = (record.collectionId ?? record.collectionName ?? '') as string\n const parts = [\n this._baseUrl,\n 'v1',\n 'files',\n encodeURIComponent(collectionId),\n encodeURIComponent(record.id),\n encodeURIComponent(filename),\n ]\n\n let url = parts.join('/')\n\n const params = new URLSearchParams()\n if (options?.thumb) params.set('thumb', options.thumb)\n if (options?.token) params.set('token', options.token)\n const qs = params.toString()\n if (qs) url += '?' + qs\n\n return url\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientConfig\n// ---------------------------------------------------------------------------\n\nexport interface ClientConfig {\n /** Base URL of the Hanzo Base instance (e.g. \"https://myapp.hanzo.ai\"). */\n url: string\n /** Optional external auth store. Defaults to in-memory store. */\n authStore?: AuthStore\n}\n\nexport interface ListOptions {\n filter?: string\n sort?: string\n expand?: string\n fields?: string\n page?: number\n perPage?: number\n}\n\nexport interface ListResult<T = BaseRecord> {\n page: number\n perPage: number\n totalItems: number\n totalPages: number\n items: T[]\n}\n\n// ---------------------------------------------------------------------------\n// BaseClient\n// ---------------------------------------------------------------------------\n\nexport class BaseClient {\n readonly url: string\n readonly authStore: AuthStore\n readonly store: QueryStore\n readonly realtime: RealtimeService\n readonly files: FileService\n\n private readonly _versionTracker: VersionTracker\n private readonly _collections = new Map<string, CollectionService>()\n\n /**\n * Create a BaseClient.\n *\n * Accepts either a config object or a plain URL string for convenience:\n * new BaseClient('https://myapp.hanzo.ai')\n * new BaseClient({ url: 'https://myapp.hanzo.ai' })\n */\n constructor(configOrUrl: ClientConfig | string) {\n const config: ClientConfig =\n typeof configOrUrl === 'string' ? { url: configOrUrl } : configOrUrl\n\n this.url = config.url.replace(/\\/$/, '')\n this.authStore = config.authStore ?? new MemoryAuthStore()\n this.store = new QueryStore()\n this.realtime = new RealtimeService(this.url, () => this.authStore.token)\n this.files = new FileService(this.url)\n this._versionTracker = new VersionTracker()\n\n // Sync identity hash when auth changes.\n this.authStore.onChange((token) => {\n this._versionTracker.setIdentity(\n token ? VersionTracker.hashIdentity(token) : 0,\n )\n })\n }\n\n // ---- Base-compatible collection() API ------------------------------------\n\n /** Get or create a CollectionService for the given name/id. */\n collection(nameOrId: string): CollectionService {\n let svc = this._collections.get(nameOrId)\n if (!svc) {\n svc = new CollectionService(\n nameOrId,\n this.url,\n () => this.authStore.token,\n (token, record) => this.authStore.save(token, record),\n this.store,\n this.realtime,\n )\n this._collections.set(nameOrId, svc)\n }\n return svc\n }\n\n // ---- State version ------------------------------------------------------\n\n /** Current state version from the QueryStore's internal tracker. */\n get version() {\n return this.store.version\n }\n\n // ---- Direct convenience API (kept for backwards compatibility) ----------\n\n private _headers(): Record<string, string> {\n const h: Record<string, string> = { 'Content-Type': 'application/json' }\n if (this.authStore.token) {\n h['Authorization'] = this.authStore.token\n }\n return h\n }\n\n private async _request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.url}${path}`, {\n method,\n headers: this._headers(),\n body: body !== undefined ? JSON.stringify(body) : undefined,\n })\n\n if (!res.ok) {\n const text = await res.text()\n let detail: unknown\n try {\n detail = JSON.parse(text)\n } catch {\n detail = text\n }\n throw new BaseClientError(res.status, detail)\n }\n\n if (res.status === 204) return undefined as T\n\n return res.json() as Promise<T>\n }\n\n async list(collection: string, options?: ListOptions): Promise<ListResult> {\n const params = new URLSearchParams()\n if (options?.filter) params.set('filter', options.filter)\n if (options?.sort) params.set('sort', options.sort)\n if (options?.expand) params.set('expand', options.expand)\n if (options?.fields) params.set('fields', options.fields)\n if (options?.page) params.set('page', String(options.page))\n if (options?.perPage) params.set('perPage', String(options.perPage))\n\n const qs = params.toString()\n const path = `/v1/collections/${encodeURIComponent(collection)}/records${qs ? '?' + qs : ''}`\n const result = await this._request<ListResult>('GET', path)\n\n this.store.setQuery(collection, options?.filter ?? '', result.items)\n return result\n }\n\n async getOne(collection: string, id: string, options?: Pick<ListOptions, 'expand' | 'fields'>): Promise<BaseRecord> {\n const params = new URLSearchParams()\n if (options?.expand) params.set('expand', options.expand)\n if (options?.fields) params.set('fields', options.fields)\n const qs = params.toString()\n const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}${qs ? '?' + qs : ''}`\n return this._request<BaseRecord>('GET', path)\n }\n\n async create(collection: string, data: Record<string, unknown>): Promise<BaseRecord> {\n const path = `/v1/collections/${encodeURIComponent(collection)}/records`\n const record = await this._request<BaseRecord>('POST', path, data)\n this.store.applyServerUpdate(collection, 'create', record)\n return record\n }\n\n async update(collection: string, id: string, data: Record<string, unknown>): Promise<BaseRecord> {\n const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`\n const record = await this._request<BaseRecord>('PATCH', path, data)\n this.store.applyServerUpdate(collection, 'update', record)\n return record\n }\n\n async delete(collection: string, id: string): Promise<void> {\n const path = `/v1/collections/${encodeURIComponent(collection)}/records/${encodeURIComponent(id)}`\n await this._request<void>('DELETE', path)\n this.store.applyServerUpdate(collection, 'delete', { id } as BaseRecord)\n }\n\n // ---- Auth (direct convenience) ------------------------------------------\n\n async signInWithPassword(\n collection: string,\n identity: string,\n password: string,\n ): Promise<{ token: string; record: BaseRecord }> {\n const path = `/v1/collections/${encodeURIComponent(collection)}/auth-with-password`\n const result = await this._request<{ token: string; record: BaseRecord }>('POST', path, {\n identity,\n password,\n })\n this.authStore.save(result.token, result.record)\n return result\n }\n\n async signUp(\n collection: string,\n data: Record<string, unknown>,\n ): Promise<BaseRecord> {\n return this.create(collection, data)\n }\n\n async refreshAuth(collection: string): Promise<{ token: string; record: BaseRecord }> {\n const path = `/v1/collections/${encodeURIComponent(collection)}/auth-refresh`\n const result = await this._request<{ token: string; record: BaseRecord }>('POST', path)\n this.authStore.save(result.token, result.record)\n return result\n }\n\n signOut(): void {\n this.authStore.clear()\n }\n\n // ---- Raw request --------------------------------------------------------\n\n /**\n * Send a raw request to the Base API.\n * Convenience for endpoints not covered by CollectionService.\n */\n async send<T = unknown>(\n path: string,\n options: {\n method?: string\n headers?: Record<string, string>\n body?: string | FormData\n query?: Record<string, string>\n signal?: AbortSignal\n } = {},\n ): Promise<T> {\n const method = options.method ?? 'GET'\n let url = `${this.url}${path}`\n\n if (options.query) {\n const params = new URLSearchParams(options.query)\n url += '?' + params.toString()\n }\n\n const headers: Record<string, string> = { ...options.headers }\n if (this.authStore.token) {\n headers['Authorization'] = this.authStore.token\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: options.body,\n signal: options.signal,\n })\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}))\n throw new BaseClientError(\n response.status,\n data,\n )\n }\n\n if (response.status === 204) return undefined as T\n\n return response.json() as Promise<T>\n }\n\n // ---- Health check -------------------------------------------------------\n\n async health(): Promise<{ code: number; message: string }> {\n return this.send('/v1/health')\n }\n\n // ---- Realtime convenience -----------------------------------------------\n\n /**\n * Subscribe to realtime events for a collection topic.\n * Also wires events into the QueryStore automatically.\n */\n subscribeAndSync(collection: string, topic = '*', callback?: (e: RealtimeEvent) => void): () => void {\n return this.realtime.subscribe(collection, topic, (event) => {\n this.store.applyServerUpdate(collection, event.action, event.record)\n callback?.(event)\n })\n }\n\n // ---- Cleanup ------------------------------------------------------------\n\n /** Disconnect realtime and clear caches. */\n disconnect(): void {\n this.realtime.disconnect()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Error\n// ---------------------------------------------------------------------------\n\nexport class BaseClientError extends Error {\n readonly status: number\n readonly detail: unknown\n\n constructor(status: number, detail: unknown) {\n super(`BaseClient error ${status}`)\n this.name = 'BaseClientError'\n this.status = status\n this.detail = detail\n }\n}\n"]}