@hanzo/base 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-5NHFZRMO.js +1011 -0
- package/dist/chunk-5NHFZRMO.js.map +1 -0
- package/dist/chunk-LBAV5X5P.js +996 -0
- package/dist/chunk-LBAV5X5P.js.map +1 -0
- package/dist/compat/index.d.ts +1 -0
- package/dist/compat/index.js +3 -0
- package/dist/compat/index.js.map +1 -0
- package/dist/core/index.d.ts +368 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/crdt/index.d.ts +372 -0
- package/dist/crdt/index.js +3 -0
- package/dist/crdt/index.js.map +1 -0
- package/dist/react/index.d.ts +144 -0
- package/dist/react/index.js +283 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +71 -0
- package/src/compat/index.ts +24 -0
- package/src/core/client.ts +432 -0
- package/src/core/collection.ts +474 -0
- package/src/core/index.ts +37 -0
- package/src/core/realtime.ts +303 -0
- package/src/core/state.ts +112 -0
- package/src/core/store.ts +241 -0
- package/src/crdt/clock.ts +78 -0
- package/src/crdt/counter.ts +130 -0
- package/src/crdt/document.ts +194 -0
- package/src/crdt/index.ts +56 -0
- package/src/crdt/operations.ts +101 -0
- package/src/crdt/register.ts +106 -0
- package/src/crdt/set.ts +172 -0
- package/src/crdt/sync.ts +412 -0
- package/src/crdt/text.ts +274 -0
- package/src/react/context.tsx +87 -0
- package/src/react/hooks.ts +489 -0
- package/src/react/index.ts +56 -0
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AsyncAuthStore, default as Base, BaseAuthStore, ClientResponseError, LocalAuthStore, default as PocketBase, cookieParse, cookieSerialize, default, getTokenPayload, isTokenExpired, normalizeUnknownQueryParams } from 'pocketbase';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { AsyncAuthStore, default as Base, BaseAuthStore, ClientResponseError, LocalAuthStore, default as PocketBase, cookieParse, cookieSerialize, default, getTokenPayload, isTokenExpired, normalizeUnknownQueryParams } from 'pocketbase';
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State version tracking (Convex-inspired).
|
|
3
|
+
*
|
|
4
|
+
* Each query result is tagged with a StateVersion so the client can
|
|
5
|
+
* detect ordering, replay transitions, and drive optimistic rollbacks.
|
|
6
|
+
*/
|
|
7
|
+
interface StateVersion {
|
|
8
|
+
/** Monotonically increasing counter bumped on every query-set change. */
|
|
9
|
+
querySet: number;
|
|
10
|
+
/** Server timestamp (microseconds since epoch) of the latest known event. */
|
|
11
|
+
ts: bigint;
|
|
12
|
+
/** Identity hash -- changes when the authenticated user changes. */
|
|
13
|
+
identity: number;
|
|
14
|
+
}
|
|
15
|
+
type Modification = {
|
|
16
|
+
type: 'QueryUpdated';
|
|
17
|
+
collection: string;
|
|
18
|
+
record: BaseRecord;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'QueryRemoved';
|
|
21
|
+
collection: string;
|
|
22
|
+
id: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'QueryFailed';
|
|
25
|
+
collection: string;
|
|
26
|
+
error: string;
|
|
27
|
+
};
|
|
28
|
+
interface Transition {
|
|
29
|
+
startVersion: StateVersion;
|
|
30
|
+
endVersion: StateVersion;
|
|
31
|
+
modifications: Modification[];
|
|
32
|
+
}
|
|
33
|
+
/** Minimal record shape that every Base record satisfies. */
|
|
34
|
+
interface BaseRecord {
|
|
35
|
+
id: string;
|
|
36
|
+
collectionId?: string;
|
|
37
|
+
collectionName?: string;
|
|
38
|
+
created?: string;
|
|
39
|
+
updated?: string;
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
declare class VersionTracker {
|
|
43
|
+
private _version;
|
|
44
|
+
private _history;
|
|
45
|
+
private readonly _maxHistory;
|
|
46
|
+
constructor(maxHistory?: number);
|
|
47
|
+
get current(): Readonly<StateVersion>;
|
|
48
|
+
get history(): readonly Transition[];
|
|
49
|
+
/**
|
|
50
|
+
* Advance the version and record a transition.
|
|
51
|
+
* Returns the new version.
|
|
52
|
+
*/
|
|
53
|
+
advance(modifications: Modification[], serverTs?: bigint): StateVersion;
|
|
54
|
+
/** Update identity hash (e.g. on auth change). */
|
|
55
|
+
setIdentity(identity: number): void;
|
|
56
|
+
/** Update the high-water timestamp without bumping querySet. */
|
|
57
|
+
updateTimestamp(ts: bigint): void;
|
|
58
|
+
/** Simple FNV-1a-like hash for identity derivation. */
|
|
59
|
+
static hashIdentity(token: string): number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface QueryKey {
|
|
63
|
+
collection: string;
|
|
64
|
+
filter: string;
|
|
65
|
+
}
|
|
66
|
+
type StoreCallback = (records: BaseRecord[]) => void;
|
|
67
|
+
declare class QueryStore {
|
|
68
|
+
private readonly _slots;
|
|
69
|
+
private readonly _optimistic;
|
|
70
|
+
private readonly _version;
|
|
71
|
+
get version(): Readonly<StateVersion>;
|
|
72
|
+
/** Return cached effective (server+optimistic) result or undefined. */
|
|
73
|
+
getQuery(collection: string, filter?: string): BaseRecord[] | undefined;
|
|
74
|
+
/** Overwrite the server-truth cache for a query and notify. */
|
|
75
|
+
setQuery(collection: string, filter: string, data: BaseRecord[]): void;
|
|
76
|
+
/** Apply an optimistic create/update. Returns a mutationId for rollback. */
|
|
77
|
+
optimisticSet(collection: string, record: BaseRecord): string;
|
|
78
|
+
/** Apply an optimistic delete. */
|
|
79
|
+
optimisticDelete(collection: string, id: string): string;
|
|
80
|
+
/** Remove a single optimistic mutation and re-derive. */
|
|
81
|
+
rollbackOptimistic(mutationId: string): void;
|
|
82
|
+
/** Drop all optimistic entries for a collection. */
|
|
83
|
+
clearOptimistic(collection: string): void;
|
|
84
|
+
/**
|
|
85
|
+
* Apply a realtime SSE event from the server.
|
|
86
|
+
* `action` is one of "create", "update", "delete".
|
|
87
|
+
*/
|
|
88
|
+
applyServerUpdate(collection: string, action: 'create' | 'update' | 'delete', record: BaseRecord): void;
|
|
89
|
+
/** Subscribe to effective-state changes for a query. Returns unsubscribe. */
|
|
90
|
+
subscribe(collection: string, filter: string, callback: StoreCallback): () => void;
|
|
91
|
+
private _notify;
|
|
92
|
+
private _notifyCollection;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* RealtimeService -- SSE-based subscription manager.
|
|
97
|
+
*
|
|
98
|
+
* Features:
|
|
99
|
+
* - Query deduplication via hash(collection+topic) with reference counting
|
|
100
|
+
* - Auto-reconnect with exponential backoff
|
|
101
|
+
* - Max observed timestamp tracking
|
|
102
|
+
* - Connection state notifications
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
type ConnectionState = 'disconnected' | 'connecting' | 'connected';
|
|
106
|
+
interface RealtimeEvent {
|
|
107
|
+
action: 'create' | 'update' | 'delete';
|
|
108
|
+
record: BaseRecord;
|
|
109
|
+
}
|
|
110
|
+
type RealtimeCallback = (event: RealtimeEvent) => void;
|
|
111
|
+
type ConnectionCallback = (state: ConnectionState) => void;
|
|
112
|
+
declare class RealtimeService {
|
|
113
|
+
private readonly _baseUrl;
|
|
114
|
+
private readonly _getToken;
|
|
115
|
+
private _eventSource;
|
|
116
|
+
private _state;
|
|
117
|
+
private _connectionListeners;
|
|
118
|
+
/** Dedup map: hash -> Subscription. */
|
|
119
|
+
private _subscriptions;
|
|
120
|
+
/** SSE client id assigned by the server on connect. */
|
|
121
|
+
private _clientId;
|
|
122
|
+
/** Reconnect state. */
|
|
123
|
+
private _reconnectAttempts;
|
|
124
|
+
private _reconnectTimer;
|
|
125
|
+
private _maxReconnectDelay;
|
|
126
|
+
private _baseReconnectDelay;
|
|
127
|
+
/** High-water mark of observed server timestamps. */
|
|
128
|
+
private _maxTimestamp;
|
|
129
|
+
/** Set to true when disconnect() is called explicitly. */
|
|
130
|
+
private _intentionalDisconnect;
|
|
131
|
+
constructor(baseUrl: string, getToken: () => string);
|
|
132
|
+
get state(): ConnectionState;
|
|
133
|
+
get maxTimestamp(): bigint;
|
|
134
|
+
/**
|
|
135
|
+
* Subscribe to realtime events for a collection topic.
|
|
136
|
+
*
|
|
137
|
+
* Topic is usually "*" (all changes) or a record id.
|
|
138
|
+
* Returns an unsubscribe function.
|
|
139
|
+
*/
|
|
140
|
+
subscribe(collection: string, topic: string, callback: RealtimeCallback): () => void;
|
|
141
|
+
/** Remove all subscribers for a topic, or all topics if none specified. */
|
|
142
|
+
unsubscribe(topic?: string): void;
|
|
143
|
+
/** Register a connection-state listener. Returns unsubscribe. */
|
|
144
|
+
onConnectionChange(callback: ConnectionCallback): () => void;
|
|
145
|
+
/** Explicitly disconnect. */
|
|
146
|
+
disconnect(): void;
|
|
147
|
+
private _connect;
|
|
148
|
+
private _handleMessage;
|
|
149
|
+
/** Submit current subscription set to the server via POST. */
|
|
150
|
+
private _submitSubscriptions;
|
|
151
|
+
private _scheduleReconnect;
|
|
152
|
+
private _clearReconnect;
|
|
153
|
+
private _setState;
|
|
154
|
+
private _hash;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* CollectionService -- typed CRUD + auth + realtime for a single collection.
|
|
159
|
+
*
|
|
160
|
+
* API-compatible with PocketBase JS SDK's RecordService, extended with
|
|
161
|
+
* reactive features (subscribe/unsubscribe, optimistic writes).
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
interface ListResult$1<T = BaseRecord> {
|
|
165
|
+
page: number;
|
|
166
|
+
perPage: number;
|
|
167
|
+
totalItems: number;
|
|
168
|
+
totalPages: number;
|
|
169
|
+
items: T[];
|
|
170
|
+
}
|
|
171
|
+
interface RecordQueryOptions {
|
|
172
|
+
filter?: string;
|
|
173
|
+
sort?: string;
|
|
174
|
+
expand?: string;
|
|
175
|
+
fields?: string;
|
|
176
|
+
headers?: Record<string, string>;
|
|
177
|
+
/** Extra query params merged into the URL. */
|
|
178
|
+
query?: Record<string, string>;
|
|
179
|
+
/** Request-scoped AbortSignal. */
|
|
180
|
+
signal?: AbortSignal;
|
|
181
|
+
}
|
|
182
|
+
interface RecordFullListOptions extends RecordQueryOptions {
|
|
183
|
+
/** Batch size for pagination (default 200). */
|
|
184
|
+
batch?: number;
|
|
185
|
+
}
|
|
186
|
+
interface FileOptions {
|
|
187
|
+
thumb?: string;
|
|
188
|
+
token?: string;
|
|
189
|
+
}
|
|
190
|
+
interface AuthResponse<T = BaseRecord> {
|
|
191
|
+
token: string;
|
|
192
|
+
record: T;
|
|
193
|
+
}
|
|
194
|
+
interface OAuth2Options {
|
|
195
|
+
provider: string;
|
|
196
|
+
code: string;
|
|
197
|
+
codeVerifier: string;
|
|
198
|
+
redirectUrl: string;
|
|
199
|
+
createData?: Record<string, unknown>;
|
|
200
|
+
}
|
|
201
|
+
declare class CollectionService {
|
|
202
|
+
readonly collectionIdOrName: string;
|
|
203
|
+
private readonly _baseUrl;
|
|
204
|
+
private readonly _getToken;
|
|
205
|
+
private readonly _setAuth;
|
|
206
|
+
private readonly _store;
|
|
207
|
+
private readonly _realtime;
|
|
208
|
+
constructor(collectionIdOrName: string, baseUrl: string, getToken: () => string, setAuth: (token: string, record: BaseRecord) => void, store: QueryStore, realtime: RealtimeService);
|
|
209
|
+
getList<T extends BaseRecord = BaseRecord>(page?: number, perPage?: number, options?: RecordQueryOptions): Promise<ListResult$1<T>>;
|
|
210
|
+
getFullList<T extends BaseRecord = BaseRecord>(options?: RecordFullListOptions): Promise<T[]>;
|
|
211
|
+
getOne<T extends BaseRecord = BaseRecord>(id: string, options?: RecordQueryOptions): Promise<T>;
|
|
212
|
+
getFirstListItem<T extends BaseRecord = BaseRecord>(filter: string, options?: RecordQueryOptions): Promise<T>;
|
|
213
|
+
create<T extends BaseRecord = BaseRecord>(data: Record<string, unknown> | FormData, options?: RecordQueryOptions): Promise<T>;
|
|
214
|
+
update<T extends BaseRecord = BaseRecord>(id: string, data: Record<string, unknown> | FormData, options?: RecordQueryOptions): Promise<T>;
|
|
215
|
+
delete(id: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
216
|
+
/**
|
|
217
|
+
* Subscribe to realtime events for this collection.
|
|
218
|
+
* `topic` is "*" for all changes or a specific record id.
|
|
219
|
+
*/
|
|
220
|
+
subscribe(topic: string, callback: RealtimeCallback): () => void;
|
|
221
|
+
/** Unsubscribe from a specific topic or all topics for this collection. */
|
|
222
|
+
unsubscribe(topic?: string): void;
|
|
223
|
+
authWithPassword<T extends BaseRecord = BaseRecord>(identity: string, password: string, options?: RecordQueryOptions): Promise<AuthResponse<T>>;
|
|
224
|
+
authWithOAuth2<T extends BaseRecord = BaseRecord>(oauthOptions: OAuth2Options, options?: RecordQueryOptions): Promise<AuthResponse<T>>;
|
|
225
|
+
requestVerification(email: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
226
|
+
confirmVerification(token: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
227
|
+
requestPasswordReset(email: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
228
|
+
confirmPasswordReset(token: string, password: string, passwordConfirm: string, options?: RecordQueryOptions): Promise<boolean>;
|
|
229
|
+
private _collectionPath;
|
|
230
|
+
private _applyOptions;
|
|
231
|
+
private _request;
|
|
232
|
+
}
|
|
233
|
+
interface ClientResponseErrorData {
|
|
234
|
+
url: string;
|
|
235
|
+
status: number;
|
|
236
|
+
data: Record<string, unknown>;
|
|
237
|
+
}
|
|
238
|
+
declare class ClientResponseError extends Error {
|
|
239
|
+
url: string;
|
|
240
|
+
status: number;
|
|
241
|
+
data: Record<string, unknown>;
|
|
242
|
+
isAbort: boolean;
|
|
243
|
+
constructor(errorData: ClientResponseErrorData);
|
|
244
|
+
toJSON(): ClientResponseErrorData;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
interface AuthStore {
|
|
248
|
+
token: string;
|
|
249
|
+
record: BaseRecord | null;
|
|
250
|
+
onChange(callback: (token: string, record: BaseRecord | null) => void): () => void;
|
|
251
|
+
save(token: string, record: BaseRecord | null): void;
|
|
252
|
+
clear(): void;
|
|
253
|
+
readonly isValid: boolean;
|
|
254
|
+
}
|
|
255
|
+
type AuthChangeCallback = (token: string, record: BaseRecord | null) => void;
|
|
256
|
+
/**
|
|
257
|
+
* Default in-memory auth store.
|
|
258
|
+
* Validates JWT exp claim without external dependencies.
|
|
259
|
+
*/
|
|
260
|
+
declare class MemoryAuthStore implements AuthStore {
|
|
261
|
+
private _token;
|
|
262
|
+
private _record;
|
|
263
|
+
private _listeners;
|
|
264
|
+
get token(): string;
|
|
265
|
+
get record(): BaseRecord | null;
|
|
266
|
+
get isValid(): boolean;
|
|
267
|
+
save(token: string, record: BaseRecord | null): void;
|
|
268
|
+
clear(): void;
|
|
269
|
+
onChange(callback: AuthChangeCallback): () => void;
|
|
270
|
+
private _notify;
|
|
271
|
+
}
|
|
272
|
+
declare class FileService {
|
|
273
|
+
private readonly _baseUrl;
|
|
274
|
+
constructor(baseUrl: string);
|
|
275
|
+
/**
|
|
276
|
+
* Build a full URL to a record file.
|
|
277
|
+
* Compatible with PocketBase's pb.files.getURL().
|
|
278
|
+
*/
|
|
279
|
+
getURL(record: BaseRecord, filename: string, options?: FileOptions): string;
|
|
280
|
+
}
|
|
281
|
+
interface ClientConfig {
|
|
282
|
+
/** Base URL of the Hanzo Base instance (e.g. "https://myapp.hanzo.ai"). */
|
|
283
|
+
url: string;
|
|
284
|
+
/** Optional external auth store. Defaults to in-memory store. */
|
|
285
|
+
authStore?: AuthStore;
|
|
286
|
+
}
|
|
287
|
+
interface ListOptions {
|
|
288
|
+
filter?: string;
|
|
289
|
+
sort?: string;
|
|
290
|
+
expand?: string;
|
|
291
|
+
fields?: string;
|
|
292
|
+
page?: number;
|
|
293
|
+
perPage?: number;
|
|
294
|
+
}
|
|
295
|
+
interface ListResult<T = BaseRecord> {
|
|
296
|
+
page: number;
|
|
297
|
+
perPage: number;
|
|
298
|
+
totalItems: number;
|
|
299
|
+
totalPages: number;
|
|
300
|
+
items: T[];
|
|
301
|
+
}
|
|
302
|
+
declare class BaseClient {
|
|
303
|
+
readonly url: string;
|
|
304
|
+
readonly authStore: AuthStore;
|
|
305
|
+
readonly store: QueryStore;
|
|
306
|
+
readonly realtime: RealtimeService;
|
|
307
|
+
readonly files: FileService;
|
|
308
|
+
private readonly _versionTracker;
|
|
309
|
+
private readonly _collections;
|
|
310
|
+
/**
|
|
311
|
+
* Create a BaseClient.
|
|
312
|
+
*
|
|
313
|
+
* Accepts either a config object or a plain URL string for convenience:
|
|
314
|
+
* new BaseClient('https://myapp.hanzo.ai')
|
|
315
|
+
* new BaseClient({ url: 'https://myapp.hanzo.ai' })
|
|
316
|
+
*/
|
|
317
|
+
constructor(configOrUrl: ClientConfig | string);
|
|
318
|
+
/** Get or create a CollectionService for the given name/id. */
|
|
319
|
+
collection(nameOrId: string): CollectionService;
|
|
320
|
+
/** Current state version from the QueryStore's internal tracker. */
|
|
321
|
+
get version(): Readonly<StateVersion>;
|
|
322
|
+
private _headers;
|
|
323
|
+
private _request;
|
|
324
|
+
list(collection: string, options?: ListOptions): Promise<ListResult>;
|
|
325
|
+
getOne(collection: string, id: string, options?: Pick<ListOptions, 'expand' | 'fields'>): Promise<BaseRecord>;
|
|
326
|
+
create(collection: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
327
|
+
update(collection: string, id: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
328
|
+
delete(collection: string, id: string): Promise<void>;
|
|
329
|
+
signInWithPassword(collection: string, identity: string, password: string): Promise<{
|
|
330
|
+
token: string;
|
|
331
|
+
record: BaseRecord;
|
|
332
|
+
}>;
|
|
333
|
+
signUp(collection: string, data: Record<string, unknown>): Promise<BaseRecord>;
|
|
334
|
+
refreshAuth(collection: string): Promise<{
|
|
335
|
+
token: string;
|
|
336
|
+
record: BaseRecord;
|
|
337
|
+
}>;
|
|
338
|
+
signOut(): void;
|
|
339
|
+
/**
|
|
340
|
+
* Send a raw request to the Base API.
|
|
341
|
+
* Convenience for endpoints not covered by CollectionService.
|
|
342
|
+
*/
|
|
343
|
+
send<T = unknown>(path: string, options?: {
|
|
344
|
+
method?: string;
|
|
345
|
+
headers?: Record<string, string>;
|
|
346
|
+
body?: string | FormData;
|
|
347
|
+
query?: Record<string, string>;
|
|
348
|
+
signal?: AbortSignal;
|
|
349
|
+
}): Promise<T>;
|
|
350
|
+
health(): Promise<{
|
|
351
|
+
code: number;
|
|
352
|
+
message: string;
|
|
353
|
+
}>;
|
|
354
|
+
/**
|
|
355
|
+
* Subscribe to realtime events for a collection topic.
|
|
356
|
+
* Also wires events into the QueryStore automatically.
|
|
357
|
+
*/
|
|
358
|
+
subscribeAndSync(collection: string, topic?: string, callback?: (e: RealtimeEvent) => void): () => void;
|
|
359
|
+
/** Disconnect realtime and clear caches. */
|
|
360
|
+
disconnect(): void;
|
|
361
|
+
}
|
|
362
|
+
declare class BaseClientError extends Error {
|
|
363
|
+
readonly status: number;
|
|
364
|
+
readonly detail: unknown;
|
|
365
|
+
constructor(status: number, detail: unknown);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export { type AuthChangeCallback, type AuthResponse, type AuthStore, BaseClient, BaseClientError, type BaseRecord, type ClientConfig, ClientResponseError, type ClientResponseErrorData, CollectionService, type ConnectionCallback, type ConnectionState, type FileOptions, FileService, type ListOptions, type ListResult, MemoryAuthStore, type Modification, type OAuth2Options, type QueryKey, QueryStore, type RealtimeCallback, type RealtimeEvent, RealtimeService, type RecordFullListOptions, type RecordQueryOptions, type StateVersion, type StoreCallback, type Transition, VersionTracker };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|