pbtsdb 0.9.3 → 0.10.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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/expand-paths.ts","../src/pocketbase-query-converter.ts","../src/keyed-where.ts","../src/logger.ts","../src/build-collection.ts","../src/collection.ts","../src/util.ts"],"names":["createTanStackCollection"],"mappings":"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","file":"chunk-NVAHFHH4.js","sourcesContent":["import type { ExpandTargetCollection } from './types'\n\nexport type RelationTargets = Record<string, ExpandTargetCollection>\n\nexport function normalizePaths(paths: Iterable<string>): string[] {\n const set = new Set<string>()\n for (const path of paths) {\n const trimmed = path.trim()\n if (trimmed) set.add(trimmed)\n }\n return [...set].sort()\n}\n\nexport function splitPaths(csv: string | undefined): string[] {\n return csv ? normalizePaths(csv.split(',')) : []\n}\n\nexport function joinPaths(paths: Iterable<string>): string | undefined {\n const normalized = normalizePaths(paths)\n return normalized.length > 0 ? normalized.join(',') : undefined\n}\n\nexport const BACK_RELATION_EXPAND_CAP = 1000\n\n/** `<collection>_via_<field>` → `{ field }`, split at the first `_via_`. */\nexport function parseViaKey(key: string): { field: string } | undefined {\n const index = key.indexOf('_via_')\n if (index < 0) return undefined\n const field = key.slice(index + '_via_'.length)\n return field ? { field } : undefined\n}\n\n/**\n * After a parent filed the values expanded under `key`, record on the target\n * that the subset `field = parentId` is complete — unless the key is a forward\n * relation or PocketBase may have capped the expand.\n */\nexport function markFiledSubset(\n target: ExpandTargetCollection,\n key: string,\n values: readonly object[],\n parentId: string\n): void {\n const via = parseViaKey(key)\n if (!via || values.length >= BACK_RELATION_EXPAND_CAP) return\n target.markSubsetLoaded?.(via.field, parentId)\n}\n\nexport function validateExpandPath(\n collectionName: string,\n targets: RelationTargets | undefined,\n path: string\n): void {\n if (!targets) {\n throw new Error(\n `Cannot expand \"${path}\" on collection \"${collectionName}\": no relations declared`\n )\n }\n let current: RelationTargets | undefined = targets\n for (const segment of path.split('.')) {\n const next: ExpandTargetCollection | undefined = current?.[segment]\n if (!next) {\n throw new Error(\n `Cannot expand \"${path}\" on collection \"${collectionName}\": segment \"${segment}\" is not a declared relation`\n )\n }\n current = next.relationTargets\n }\n}\n","import type { IR } from '@tanstack/db'\nimport {\n type FieldPath,\n type ParsedOrderBy,\n parseOrderByExpression,\n parseWhereExpression,\n} from '@tanstack/db'\n\ntype BasicExpression<T = unknown> = IR.BasicExpression<T>\n\nexport function escapeValue(value: unknown): string {\n if (value === null) {\n return 'null'\n }\n if (typeof value === 'boolean') {\n return value ? 'true' : 'false'\n }\n if (typeof value === 'number') {\n return value.toString()\n }\n if (typeof value === 'string') {\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`\n }\n if (value instanceof Date) {\n return `\"${value.toISOString()}\"`\n }\n if (Array.isArray(value)) {\n return `[${value.map(escapeValue).join(',')}]`\n }\n return `\"${String(value)}\"`\n}\n\nfunction fieldPathToString(path: FieldPath): string {\n return path.join('.')\n}\n\nexport function convertToPocketBaseFilter(\n where: BasicExpression<boolean> | undefined | null\n): string | undefined {\n if (!where) {\n return undefined\n }\n\n const result = parseWhereExpression(where, {\n handlers: {\n eq: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} = ${escapeValue(value)}`\n },\n gt: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} > ${escapeValue(value)}`\n },\n gte: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} >= ${escapeValue(value)}`\n },\n lt: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} < ${escapeValue(value)}`\n },\n lte: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} <= ${escapeValue(value)}`\n },\n and: (...conditions: string[]) => {\n if (conditions.length === 0) return ''\n if (conditions.length === 1) return conditions[0]\n return `(${conditions.join(' && ')})`\n },\n or: (...conditions: string[]) => {\n if (conditions.length === 0) return ''\n if (conditions.length === 1) return conditions[0]\n return `(${conditions.join(' || ')})`\n },\n not: (condition: string) => {\n return `!(${condition})`\n },\n in: (field: FieldPath, values: unknown) => {\n const valueArray = Array.isArray(values) ? values : [values]\n const uniqueValues = [...new Set(valueArray)]\n const fieldStr = fieldPathToString(field)\n const conditions = uniqueValues.map(v => `${fieldStr} = ${escapeValue(v)}`)\n return conditions.length > 1 ? `(${conditions.join(' || ')})` : conditions[0]\n },\n like: (field: FieldPath, value: unknown) => {\n return `${fieldPathToString(field)} ~ ${escapeValue(value)}`\n },\n isNull: (field: FieldPath) => {\n return `${fieldPathToString(field)} = null`\n },\n isUndefined: (field: FieldPath) => {\n return `${fieldPathToString(field)} = null`\n },\n },\n onUnknownOperator: (operator: string, _args: unknown[]) => {\n throw new Error(\n `Unsupported operator '${operator}' for PocketBase filter conversion. ` +\n `Supported operators: eq, gt, gte, lt, lte, in, like, and, or, not, isNull, isUndefined`\n )\n },\n })\n\n return result || undefined\n}\n\nexport function convertToPocketBaseSort(\n orderBy: IR.OrderBy | undefined | null\n): string | undefined {\n if (!orderBy) {\n return undefined\n }\n\n const sorts = parseOrderByExpression(orderBy)\n\n if (sorts.length === 0) {\n return undefined\n }\n\n return sorts\n .map((sort: ParsedOrderBy) => {\n const field = fieldPathToString(sort.field)\n return sort.direction === 'desc' ? `-${field}` : field\n })\n .join(',')\n}\n","import type { IR } from '@tanstack/db'\nimport { escapeValue } from './pocketbase-query-converter'\n\nexport type WhereSubset = { field: string; values: string[] }\n\ntype Node = { type: string; name?: string; args?: Node[]; path?: string[]; value?: unknown }\n\nfunction fieldRef(node: Node | undefined): string | undefined {\n return node?.type === 'ref' && node.path?.length === 1 ? node.path[0] : undefined\n}\n\nfunction stringValue(node: Node | undefined): string | undefined {\n return node?.type === 'val' && typeof node.value === 'string' ? node.value : undefined\n}\n\nfunction collectEq(a: Node | undefined, b: Node | undefined): WhereSubset | undefined {\n const field = fieldRef(a) ?? fieldRef(b)\n if (field === undefined) return undefined\n const value = stringValue(fieldRef(a) !== undefined ? b : a)\n return value === undefined ? undefined : { field, values: [value] }\n}\n\nfunction collectIn(a: Node | undefined, b: Node | undefined): WhereSubset | undefined {\n const field = fieldRef(a)\n if (field === undefined || b?.type !== 'val' || !Array.isArray(b.value)) return undefined\n return b.value.every(v => typeof v === 'string')\n ? { field, values: b.value as string[] }\n : undefined\n}\n\nfunction collectOr(args: Node[]): WhereSubset | undefined {\n let field: string | undefined\n const values: string[] = []\n for (const arg of args) {\n const sub = collect(arg)\n if (!sub || (field !== undefined && sub.field !== field)) return undefined\n field = sub.field\n values.push(...sub.values)\n }\n return field === undefined ? undefined : { field, values }\n}\n\nfunction collect(node: Node): WhereSubset | undefined {\n if (node.type !== 'func' || !node.args) return undefined\n const [a, b] = node.args\n switch (node.name) {\n case 'eq':\n return collectEq(a, b)\n case 'in':\n return collectIn(a, b)\n case 'or':\n return collectOr(node.args)\n default:\n return undefined\n }\n}\n\n/**\n * The single-field subset a `where` selects when it is nothing but equalities on\n * one top-level field: `eq(field, x)`, `in(field, [...])`, or an `or` of those.\n * Anything else returns `undefined`.\n */\nexport function subsetFromWhere(\n where: IR.BasicExpression<boolean> | undefined | null\n): WhereSubset | undefined {\n if (!where) return undefined\n const subset = collect(where as unknown as Node)\n return subset ? { field: subset.field, values: [...new Set(subset.values)].sort() } : undefined\n}\n\n// PocketBase refuses a filter over MaxFilterLength (3500 bytes) with a generic\n// 400, and a subset's size is the caller's data — a user's memberships, a\n// mailbox's threads. The margin below the server cap absorbs multi-byte values,\n// since `.length` counts UTF-16 units.\nconst MAX_FILTER_LENGTH = 2500\n\n/**\n * The PocketBase filters that select `subset`, each short enough for the server\n * to accept: one when every value fits, more when they do not.\n */\nexport function subsetFilters({ field, values }: WhereSubset): string[] {\n const filters: string[] = []\n let current = ''\n for (const value of values) {\n const clause = `${field} = ${escapeValue(value)}`\n const joined = current ? `${current} || ${clause}` : clause\n if (current && joined.length > MAX_FILTER_LENGTH) {\n filters.push(current)\n current = clause\n } else {\n current = joined\n }\n }\n if (current) filters.push(current)\n return filters\n}\n\n/** Whether a row's `field` is one of `wanted` (a multiple relation matches by containment). */\nexport function matchesSubset(row: object, field: string, wanted: ReadonlySet<string>): boolean {\n const value = (row as Record<string, unknown>)[field]\n if (typeof value === 'string') return wanted.has(value)\n if (Array.isArray(value))\n return value.some(item => typeof item === 'string' && wanted.has(item))\n return false\n}\n","/**\n * Logger interface for subscription events and internal operations.\n * Users can provide their own implementation to integrate with external logging services.\n */\nexport interface Logger {\n /**\n * Log debug-level messages (typically only shown in development).\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n debug: (msg: string, context?: object) => void\n\n /**\n * Log info-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n info: (msg: string, context?: object) => void\n\n /**\n * Log warning-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n warn: (msg: string, context?: object) => void\n\n /**\n * Log error-level messages.\n * @param msg - The message to log\n * @param context - Optional context object with additional information\n */\n error: (msg: string, context?: object) => void\n}\n\n/**\n * Default console-based logger implementation.\n * Only logs debug messages in development mode.\n */\nconst defaultLogger: Logger = {\n debug: (msg: string, context?: object) => {\n if (process.env.NODE_ENV === 'development') {\n console.debug(`[pbtsdb] ${msg}`, context || '')\n }\n },\n info: (msg: string, context?: object) => {\n console.info(`[pbtsdb] ${msg}`, context || '')\n },\n warn: (msg: string, context?: object) => {\n console.warn(`[pbtsdb] ${msg}`, context || '')\n },\n error: (msg: string, context?: object) => {\n console.error(`[pbtsdb] ${msg}`, context || '')\n },\n}\n\n/**\n * Current logger instance (can be replaced by users).\n */\nlet currentLogger: Logger = defaultLogger\n\n/**\n * Internal logger instance used by the library.\n */\nexport const logger: Logger = {\n debug: (msg: string, context?: object) => currentLogger.debug(msg, context),\n info: (msg: string, context?: object) => currentLogger.info(msg, context),\n warn: (msg: string, context?: object) => currentLogger.warn(msg, context),\n error: (msg: string, context?: object) => currentLogger.error(msg, context),\n}\n\n/**\n * Set a custom logger implementation.\n * This allows users to integrate with their own logging services (e.g., Sentry, LogRocket, etc.).\n *\n * @param customLogger - The custom logger implementation\n *\n * @example\n * ```ts\n * import { setLogger } from 'pbtsdb';\n *\n * // Integration with a custom logging service\n * setLogger({\n * debug: (msg, context) => myLogger.debug(msg, context),\n * warn: (msg, context) => myLogger.warn(msg, context),\n * error: (msg, context) => {\n * myLogger.error(msg, context);\n * Sentry.captureMessage(msg, { level: 'error', extra: context });\n * },\n * });\n * ```\n *\n * @example\n * ```ts\n * // Disable all logging\n * setLogger({\n * debug: () => {},\n * warn: () => {},\n * error: () => {},\n * });\n * ```\n */\nexport function setLogger(customLogger: Logger): void {\n currentLogger = customLogger\n}\n\n/**\n * Reset the logger to the default implementation.\n */\nexport function resetLogger(): void {\n currentLogger = defaultLogger\n}\n","import {\n BTreeIndex,\n type Collection,\n createCollection as createTanStackCollection,\n type LoadSubsetOptions,\n} from '@tanstack/db'\nimport {\n DeleteOperationItemNotFoundError,\n type QueryCollectionUtils,\n queryCollectionOptions,\n} from '@tanstack/query-db-collection'\nimport type { QueryClient } from '@tanstack/react-query'\nimport type PocketBase from 'pocketbase'\nimport type { RecordSubscribeOptions, RecordSubscription } from 'pocketbase'\nimport type { RelationTargets } from './expand-paths'\nimport {\n joinPaths,\n markFiledSubset,\n normalizePaths,\n parseViaKey,\n splitPaths,\n validateExpandPath,\n} from './expand-paths'\nimport { matchesSubset, subsetFilters, subsetFromWhere, type WhereSubset } from './keyed-where'\nimport { logger } from './logger'\nimport { convertToPocketBaseFilter, convertToPocketBaseSort } from './pocketbase-query-converter'\nimport type {\n CreateCollectionOptions,\n ExpandTargetCollection,\n ExtractRecordType,\n SchemaDeclaration,\n} from './types'\n\n// Subscriptions created through a view, mapped to the view's expand paths. Keyed\n// by the subscription object TanStack hands back to loadSubset/unloadSubset.\nconst viewPaths = new WeakMap<object, string[]>()\n\n// A correlated subquery over a relation target (e.g. a `materialize` include\n// keyed off the parent row's id) can have its own `loadSubset` dispatched by\n// TanStack DB's query planner before the parent's own fetch — the one that\n// would file and mark this exact subset — has resolved. Keyed by the target\n// collection instance and via-field, this lets the target's own fetch wait\n// for a same-tick parent fetch that might satisfy it instead of racing it.\nconst pendingFilings = new WeakMap<object, Map<string, Promise<void>[]>>()\n\n// Called by a PARENT collection's own fetch, on the relation TARGET instance,\n// to register that it might mark `field` once that fetch's upsertExpanded\n// settles. The target's own fetchItems awaits these (see awaitPendingFiling)\n// before issuing a request for a not-yet-loaded subset on that field. Returns\n// an unregister function the caller runs once its fetch settles, so a\n// long-lived target never accumulates promises for fetches that finished.\nfunction registerPendingFiling(target: object, field: string, settles: Promise<void>): () => void {\n let byField = pendingFilings.get(target)\n if (!byField) {\n byField = new Map()\n pendingFilings.set(target, byField)\n }\n let pending = byField.get(field)\n if (!pending) {\n pending = []\n byField.set(field, pending)\n }\n pending.push(settles)\n return () => {\n const index = pending.indexOf(settles)\n if (index !== -1) pending.splice(index, 1)\n if (pending.length === 0) byField.delete(field)\n if (byField.size === 0) pendingFilings.delete(target)\n }\n}\n\nasync function awaitPendingFiling(target: object, field: string): Promise<void> {\n const pending = pendingFilings.get(target)?.get(field)\n if (!pending || pending.length === 0) return\n await Promise.all(pending)\n}\n\n/**\n * Minimal shape of the two collection events that invalidate every loaded-subset\n * mark: `status:change` (cleared on reaching `cleaned-up`) and `truncate`\n * (cleared unconditionally). Extracted so the wiring itself is unit-testable\n * against a fake emitter, independent of a real `Collection` instance.\n * @internal\n */\nexport type MarkInvalidatingCollection = {\n onStatusChange: (callback: (event: { status: string }) => void) => () => void\n onTruncate: (callback: () => void) => () => void\n}\n\n/**\n * Without a live subscription, back-relation children can appear server-side\n * unseen, so every mark is stale once the collection cleans up or truncates.\n * @internal\n */\nexport function registerMarkInvalidationEvents(\n collection: MarkInvalidatingCollection,\n clearMarks: () => void\n): void {\n collection.onStatusChange(event => {\n if (event.status === 'cleaned-up') clearMarks()\n })\n collection.onTruncate(() => clearMarks())\n}\n\n/**\n * Options applied to every collection built by a {@link createCollection} factory.\n */\nexport interface CreateCollectionFactoryOptions {\n /**\n * Extra options passed to every real-time subscription this factory creates,\n * such as `headers`, `filter`, `expand` or `fields`.\n *\n * Invoked at subscribe time rather than read once, because a subscription is\n * re-established on reconnect and whenever the subscriber count rises from\n * zero — a value captured at build time would go stale exactly then.\n *\n * Returning `undefined` subscribes with no extra options.\n */\n subscribeOptions?: () => RecordSubscribeOptions | undefined\n}\n\n/**\n * Subscription helpers added to collection instances.\n * @internal\n */\nexport interface CollectionSubscriptionHelpers {\n /** The PocketBase collection name */\n collectionName: string\n /** Wait for subscription to be established (useful in tests) */\n waitForSubscription: (timeout?: number) => Promise<void>\n /** Check if collection has an active subscription */\n isSubscribed: () => boolean\n /** Relation targets declared through `relations` */\n relationTargets: RelationTargets | undefined\n /** Number of relation targets currently held live */\n heldRelationTargetCount: () => number\n /** Record that every row with `field === value` is now in this collection's store */\n markSubsetLoaded: (field: string, value: string) => void\n /** Number of field/value pairs currently marked loaded */\n loadedSubsetCount: () => number\n}\n\n/**\n * Runtime shape of a built collection, before the public factory narrows it.\n * @internal\n */\nexport type BuiltCollection<T extends object> = Collection<\n T,\n string | number,\n QueryCollectionUtils<T, string | number, T>,\n never,\n T\n> &\n CollectionSubscriptionHelpers\n\n/** @internal */\nexport interface BuildCollectionInput<\n Schema extends SchemaDeclaration,\n C extends keyof Schema & string,\n> {\n pb: PocketBase\n queryClient: QueryClient\n factoryOptions: CreateCollectionFactoryOptions | undefined\n collectionName: C\n options: CreateCollectionOptions<Schema, C> | undefined\n}\n\n/** @internal */\nexport function buildCollection<Schema extends SchemaDeclaration, C extends keyof Schema & string>(\n input: BuildCollectionInput<Schema, C>\n): BuiltCollection<ExtractRecordType<Schema, C>> {\n const { pb, queryClient, factoryOptions, collectionName, options } = input\n type RecordType = ExtractRecordType<Schema, C>\n\n const relationTargets = options?.relations as RelationTargets | undefined\n const alwaysFetch = normalizePaths(options?.alwaysFetchRelations ?? [])\n for (const path of alwaysFetch) validateExpandPath(collectionName, relationTargets, path)\n const syncMode = options?.syncMode ?? 'eager'\n\n // Paths requested by views that have subscribed at least once. Eager fetches\n // read it because they cannot receive per-subset options; the realtime\n // subscription reads it so echoes carry every relation in use.\n const requestedExpand = new Set<string>()\n\n type LoadOptions = LoadSubsetOptions & { expand?: readonly string[] }\n type PbRequest = {\n filter?: string\n sort?: string\n limit?: number\n expand?: string\n subset?: WhereSubset\n }\n\n function toRequest(opts: LoadSubsetOptions | undefined): PbRequest {\n const request: PbRequest = {}\n const subset = subsetFromWhere(opts?.where)\n const filter = subset ? undefined : convertToPocketBaseFilter(opts?.where)\n const sort = convertToPocketBaseSort(opts?.orderBy)\n const expand = joinPaths((opts as LoadOptions | undefined)?.expand ?? [])\n if (subset) request.subset = subset\n if (filter) request.filter = filter\n if (sort) request.sort = sort\n if (opts?.limit) request.limit = opts.limit\n if (expand) request.expand = expand\n return request\n }\n\n function queryKeyFor(opts?: LoadSubsetOptions): [C] | [C, PbRequest] {\n const request = toRequest(opts)\n return Object.keys(request).length === 0 ? [collectionName] : [collectionName, request]\n }\n\n function activeExpand(request: PbRequest): string | undefined {\n return joinPaths([\n ...alwaysFetch,\n ...splitPaths(request.expand),\n ...(syncMode === 'eager' ? requestedExpand : []),\n ])\n }\n\n // The declared relation targets this request's top-level expand keys will\n // file into, for each key that is a back-relation (`<collection>_via_<field>`).\n // Used to give a same-tick correlated subquery on one of those targets a\n // chance to be served from the store instead of racing this fetch.\n function backRelationTargetsFor(\n request: PbRequest\n ): Array<{ target: ExpandTargetCollection; key: string; field: string }> {\n if (!relationTargets) return []\n const results: Array<{ target: ExpandTargetCollection; key: string; field: string }> = []\n for (const key of splitPaths(activeExpand(request)).map(path => path.split('.')[0])) {\n const target = relationTargets[key]\n const via = target && parseViaKey(key)\n if (target && via) results.push({ target, key, field: via.field })\n }\n return results\n }\n\n // pbtsdb asked PocketBase for these relations only to file them into their\n // target collections; the copies never reach a row in any cache.\n function stripFetchedRelations(\n items: RecordType[],\n expandString: string | undefined\n ): RecordType[] {\n const heads = new Set(splitPaths(expandString).map(path => path.split('.')[0]))\n if (heads.size === 0) return items\n return items.map(item => {\n const { expand, ...plain } = item as RecordType & {\n expand?: Record<string, unknown>\n }\n if (!expand) return item\n const kept = Object.fromEntries(\n Object.entries(expand).filter(([key]) => !heads.has(key))\n )\n return (Object.keys(kept).length > 0 ? { ...plain, expand: kept } : plain) as RecordType\n })\n }\n\n const ignoreAutoCancellation = options?.ignoreAutoCancellation ?? true\n const refetchOnMutation = options?.refetchOnMutation ?? false\n\n function eagerSyncInFlight(target: ExpandTargetCollection): boolean {\n return (\n target.status !== undefined &&\n target.status !== 'idle' &&\n target.status !== 'cleaned-up'\n )\n }\n\n // A filed copy never carries `expand`: any part of it with a declared\n // target was filed by the recursive upsertExpanded call right after\n // upsertInto, and any part without one has nowhere to go and is dropped.\n function withoutExpand(values: object[]): object[] {\n return values.map(value => {\n const { expand: _expand, ...plain } = value as { expand?: unknown }\n return plain\n })\n }\n\n // Returns whether a write actually happened. A silent no-op (no utils, or\n // not ready with no way to become ready) must never be treated as a filing:\n // the caller uses this to decide whether the values just upserted can be\n // trusted to mark a subset complete.\n async function upsertInto(\n key: string,\n target: ExpandTargetCollection,\n values: object[]\n ): Promise<boolean> {\n if (!target.utils) return false\n if (!target.isReady()) {\n if (target.config?.syncMode === 'on-demand') {\n await target._sync.startSync()\n } else if (target.preload && eagerSyncInFlight(target)) {\n // An eager target whose full load is already running (a held\n // subscription started it) becomes ready shortly; wait rather\n // than drop the records or race the load.\n await target.preload()\n } else {\n logger.warn(\n `not syncing ${key} on ${collectionName} because store is not yet ready`\n )\n return false\n }\n }\n target.utils.writeUpsert(withoutExpand(values))\n return true\n }\n\n type ExpandedGroup = { values: object[]; byParent: [string, object[]][] }\n\n function addExpanded(\n byKey: Map<string, ExpandedGroup>,\n key: string,\n value: object | object[],\n parentId: unknown\n ): void {\n const values = Array.isArray(value) ? value : [value]\n const group = byKey.get(key) ?? { values: [], byParent: [] }\n group.values.push(...values)\n if (typeof parentId === 'string') group.byParent.push([parentId, values])\n byKey.set(key, group)\n }\n\n function groupExpandedByKey(records: object[]): Map<string, ExpandedGroup> {\n const byKey = new Map<string, ExpandedGroup>()\n for (const record of records) {\n const { id, expand } = record as {\n id?: unknown\n expand?: Record<string, object | object[]>\n }\n if (!expand) continue\n for (const [key, value] of Object.entries(expand)) {\n addExpanded(byKey, key, value, id)\n }\n }\n return byKey\n }\n\n // Many parents can expand the same record; the last copy wins.\n function lastById(values: object[]): object[] {\n const byId = new Map<unknown, object>()\n for (const value of values) byId.set((value as { id?: unknown }).id, value)\n return [...byId.values()]\n }\n\n // One write per relation key for the whole batch: a write pushes the\n // target's entire row set into every cached query for it.\n async function upsertExpanded(\n records: object[],\n targets: RelationTargets | undefined\n ): Promise<void> {\n if (!targets) return\n for (const [key, group] of groupExpandedByKey(records)) {\n const target = targets[key]\n if (!target) {\n logger.debug('No relation target for expanded field', { collectionName, key })\n continue\n }\n const values = lastById(group.values)\n const filed = await upsertInto(key, target, values)\n await upsertExpanded(values, target.relationTargets)\n if (!filed) continue\n for (const [parentId, parentValues] of group.byParent) {\n markFiledSubset(target, key, parentValues, parentId)\n }\n }\n }\n\n // PocketBase omits the expand key entirely when a back-relation has no\n // records, so absence after a server fetch means zero children for that parent.\n function markEmptyBackRelations(items: readonly object[], request: PbRequest): void {\n const heads = backRelationTargetsFor(request)\n if (heads.length === 0) return\n for (const item of items) {\n const { id, expand } = item as { id?: unknown; expand?: Record<string, unknown> }\n if (typeof id !== 'string') continue\n for (const { target, key, field } of heads) {\n if (expand?.[key] === undefined) target.markSubsetLoaded?.(field, id)\n }\n }\n }\n\n // Field → parent ids whose child subset is known complete in the store,\n // recorded when a parent files a back-relation expand for that parent id.\n // Grows with the distinct parents filed while this target is held live,\n // pairs with rows the store already retains, and is cleared on stop,\n // cleanup, or truncate.\n const loadedSubsets = new Map<string, Set<string>>()\n\n function markSubsetLoaded(field: string, value: string): void {\n let values = loadedSubsets.get(field)\n if (!values) {\n values = new Set()\n loadedSubsets.set(field, values)\n }\n values.add(value)\n }\n\n function loadedSubsetCount(): number {\n let count = 0\n for (const values of loadedSubsets.values()) count += values.size\n return count\n }\n\n function subsetIsLoaded({ field, values }: WhereSubset): boolean {\n const marked = loadedSubsets.get(field)\n return marked !== undefined && values.every(value => marked.has(value))\n }\n\n function forgetMarkedValue(marked: Set<string>, value: unknown): string[] {\n if (typeof value === 'string') return marked.delete(value) ? [value] : []\n if (!Array.isArray(value)) return []\n return value.filter(item => typeof item === 'string' && marked.delete(item))\n }\n\n // True when `query` reads a subset of this collection keyed on a field the\n // caller marks, with at least one value the caller marks. Shared by\n // invalidateForgottenSubset (one field, the values just forgotten) and\n // invalidateMarkedSubsets (every field/value currently marked).\n function matchesMarkedSubset(\n query: { queryKey: readonly unknown[] },\n isMarked: (field: string, value: string) => boolean\n ): boolean {\n if (query.queryKey[0] !== collectionName) return false\n const request = query.queryKey[1] as PbRequest | undefined\n if (!request?.subset) return false\n const { field, values } = request.subset\n return values.some(value => isMarked(field, value))\n }\n\n function invalidateMarkedQueries(isMarked: (field: string, value: string) => boolean): void {\n void queryClient\n .invalidateQueries({ predicate: query => matchesMarkedSubset(query, isMarked) })\n .catch(error =>\n logger.error('Failed to invalidate marked subset queries', {\n collectionName,\n error,\n })\n )\n }\n\n // A subset query that already resolved successfully is served from\n // query-db-collection's own observer cache on the next mount regardless of\n // our own marks, so forgetting a mark must also invalidate that cached\n // query for a fresh fetch to actually happen.\n function invalidateForgottenSubset(field: string, values: readonly string[]): void {\n invalidateMarkedQueries(\n (queryField, value) => queryField === field && values.includes(value)\n )\n }\n\n // Every mark held for this target justified serving some subset query from\n // the store; releasing them on a real stop (see doStopSubscription) must\n // invalidate those queries too, or a later mount reads the same cached\n // result instead of re-checking with a live subscription.\n function invalidateAllMarkedSubsets(): void {\n invalidateMarkedQueries((field, value) => loadedSubsets.get(field)?.has(value) ?? false)\n }\n\n // A row leaving the store other than by a server-confirmed delete means the\n // subsets it belonged to are no longer complete. Deferred with\n // queueMicrotask: this runs inside the guarded sync write, i.e. inside\n // TanStack's write batch, and invalidateQueries can start a queryFn\n // synchronously up to its first await — which must not re-enter\n // fetchRecords/registerPendingFiling mid-batch.\n function forgetMarksFor(row: unknown): void {\n if (!row || typeof row !== 'object') return\n for (const [field, marked] of loadedSubsets) {\n const forgotten = forgetMarkedValue(marked, (row as Record<string, unknown>)[field])\n if (forgotten.length > 0) {\n queueMicrotask(() => invalidateForgottenSubset(field, forgotten))\n }\n }\n }\n\n // Rows already in the synced store are as fresh as realtime keeps them;\n // an id-only request whose ids are all present needs no round trip.\n function rowsFromStore(ids: readonly string[]): RecordType[] | undefined {\n const rows: RecordType[] = []\n for (const id of ids) {\n const row = collection._state.syncedData.get(id) as RecordType | undefined\n if (!row) return undefined\n rows.push(row)\n }\n return rows\n }\n\n // A row already in the store was fetched (and filed) with this collection's own\n // alwaysFetchRelations, so that part of `expand` is already reflected. Only\n // `request.expand` — the extra paths a fetchRelations() view adds — may not have\n // been filed for this row yet, so only that forces a real fetch. An empty subset\n // (e.g. `in(id, [])`) selects nothing and must never fall through to a request,\n // which an empty id filter would turn into \"fetch everything\".\n function idSubsetFromStore(\n subset: WhereSubset,\n limit: number | undefined\n ): RecordType[] | undefined {\n const present = rowsFromStore(subset.values)\n if (!present) return undefined\n return limit ? present.slice(0, limit) : present\n }\n\n function fieldSubsetFromStore(\n subset: WhereSubset,\n limit: number | undefined\n ): RecordType[] | undefined {\n if (!subsetIsLoaded(subset)) return undefined\n const wanted = new Set(subset.values)\n const rows = [...collection._state.syncedData.values()].filter(row =>\n matchesSubset(row as object, subset.field, wanted)\n ) as RecordType[]\n return limit ? rows.slice(0, limit) : rows\n }\n\n function servedFromStore(request: PbRequest): RecordType[] | undefined {\n const { subset, sort, limit } = request\n if (!subset) return undefined\n if (subset.values.length === 0) return []\n if (request.expand) return undefined\n // A sorted + limited request must be sliced in that order; the store\n // holds rows in id order, so slicing here could return the wrong subset.\n // TanStack passes neither for id-only loads today, so this only guards\n // against a future caller combining them.\n if (sort && limit) return undefined\n return subset.field === 'id'\n ? idSubsetFromStore(subset, limit)\n : fieldSubsetFromStore(subset, limit)\n }\n\n async function fetchItems(request: PbRequest): Promise<RecordType[]> {\n const served = servedFromStore(request)\n if (served) return served\n // A same-tick parent fetch may be about to file and mark exactly this\n // subset (see pendingFilings above); give it the chance before fetching.\n // Invariant: a registering fetch never waits. This fetch's own active\n // expand (alwaysFetchRelations included, not just request.expand) may\n // itself register pending filings on other targets (backRelationTargetsFor\n // below, in fetchRecords); waiting here too would let two mutually\n // back-related collections each register before either awaits, and then\n // await each other forever.\n if (\n request.subset &&\n request.subset.field !== 'id' &&\n backRelationTargetsFor(request).length === 0\n ) {\n await awaitPendingFiling(collection, request.subset.field)\n const servedAfterFiling = servedFromStore(request)\n if (servedAfterFiling) return servedAfterFiling\n }\n const { sort, limit, subset } = request\n const filters = subset ? subsetFilters(subset) : [request.filter]\n const expand = activeExpand(request)\n // Each chunk carries its own request key so the SDK's auto-cancellation\n // (keyed on method + path by default) does not abort sibling chunks.\n // A limited request returns each chunk's first rows unsliced: the live\n // query re-applies sort and limit over the union.\n async function fetchPage(filter: string | undefined, index: number): Promise<RecordType[]> {\n const requestKey = `${collectionName}:${index}`\n if (limit) {\n const result = await pb.collection(collectionName).getList(1, limit, {\n filter,\n sort,\n skipTotal: true,\n expand,\n requestKey,\n })\n return result.items as unknown as RecordType[]\n }\n return (await pb.collection(collectionName).getFullList({\n filter,\n sort,\n expand,\n requestKey,\n })) as unknown as RecordType[]\n }\n const items = (await Promise.all(filters.map(fetchPage))).flat()\n markEmptyBackRelations(items, request)\n return items\n }\n\n // Each in-flight fetch registers a set here before its request goes out;\n // authoritative local writes (mutation write-backs and realtime echoes)\n // add the confirmed record ids to every registered set. An id added\n // after a fetch was issued is newer than that fetch's view of the\n // server, so the result cannot speak to the id's absence. The merge\n // deliberately ignores the fetch's filter: the manual-write cache push\n // grants every active query ownership of every synced row, so even a\n // row outside this subset's filter must be shielded from its reconcile.\n //\n // Why this exists: @tanstack/query-db-collection's applySuccessfulResult\n // reconcile-DELETES every row a query owns that its result omits, and the\n // synced-write guard below deliberately exempts deletes. A subset read\n // issued before a row existed can therefore resolve late and delete the\n // just-confirmed row (rows a query owns include rows pushed into its\n // cache by the manual-write path that runs on every write-back). The fix\n // is applied to the RESULT rather than the delete: fetchRecords merges\n // such rows back in, which both prevents the delete and keeps the row\n // owned by the query — a dropped delete alone would still strip\n // ownership and leave the row to a later GC pass.\n const inFlightConfirmedIds = new Set<Set<string>>()\n\n function markConfirmedPresent(records: RecordType[]): void {\n if (inFlightConfirmedIds.size === 0) return\n for (const record of records) {\n const id = (record as { id?: unknown } | null | undefined)?.id\n if (typeof id !== 'string') continue\n for (const confirmed of inFlightConfirmedIds) confirmed.add(id)\n }\n }\n\n function withRowsConfirmedMidFlight(\n items: RecordType[],\n confirmedMidFlight: Set<string>\n ): RecordType[] {\n if (confirmedMidFlight.size === 0) return items\n const resultIds = new Set(\n items.map(item => (item as { id?: unknown } | null | undefined)?.id)\n )\n // Ids absent from the synced store (deleted mid-flight, or never\n // landed) have nothing to protect and drop out of the merge.\n const mergedIds = [...confirmedMidFlight].filter(\n id => !resultIds.has(id) && collection._state.syncedData.has(id)\n )\n if (mergedIds.length === 0) return items\n logger.debug('Merging rows confirmed while fetch was in flight', {\n collectionName,\n ids: mergedIds,\n })\n return [\n ...items,\n ...mergedIds.map(id => collection._state.syncedData.get(id) as RecordType),\n ]\n }\n\n async function fetchRecords(\n request: PbRequest,\n queryKey: readonly unknown[]\n ): Promise<RecordType[]> {\n const confirmedMidFlight = new Set<string>()\n inFlightConfirmedIds.add(confirmedMidFlight)\n // Registered up front, before fetchItems runs, so a target's own\n // fetchItems — dispatched the same tick by a correlated subquery — can\n // await this fetch's filing instead of racing it. Resolves once filing\n // settles either way (including on an error/autocancel path below), so\n // a waiter is never left hanging on a subset this fetch never files.\n let settleFiling: () => void = () => undefined\n const filed = new Promise<void>(resolve => {\n settleFiling = resolve\n })\n const unregisterFilings = backRelationTargetsFor(request).map(({ target, field }) =>\n registerPendingFiling(target, field, filed)\n )\n try {\n let items: RecordType[]\n try {\n items = await fetchItems(request)\n } catch (error) {\n if (\n ignoreAutoCancellation &&\n error instanceof Error &&\n error.message.includes('autocancelled')\n ) {\n // PocketBase auto-cancelled this in-flight read because a newer\n // request superseded it. Resolve to THIS subset's own cached rows\n // (keyed by the full query key) so the reconcile is a no-op for the\n // subset. The base key ([collectionName]) holds the full-collection\n // snapshot — returning that here would let applySuccessfulResult\n // reconcile foreign rows into a filtered subset (re-introducing rows\n // the subset's filter excludes). Re-throwing instead would error the\n // subset and empty/retry it.\n return withRowsConfirmedMidFlight(\n queryClient.getQueryData<RecordType[]>(queryKey) ?? [],\n confirmedMidFlight\n )\n }\n throw error\n }\n\n await upsertExpanded(items, relationTargets)\n return withRowsConfirmedMidFlight(\n stripFetchedRelations(items, activeExpand(request)),\n confirmedMidFlight\n )\n } finally {\n inFlightConfirmedIds.delete(confirmedMidFlight)\n settleFiling()\n for (const unregister of unregisterFilings) unregister()\n }\n }\n\n // TanStack DB 0.6 turned auto-indexing off by default; without an index an\n // orderBy+limit query loads the whole subset instead of paging lazily and\n // warns on every compile. Restore the earlier default; callers can override\n // both settings through collectionOptions.\n const queryCollectionConfig = queryCollectionOptions({\n autoIndex: 'eager',\n defaultIndexType: BTreeIndex,\n ...options?.collectionOptions,\n queryClient,\n queryKey: queryKeyFor,\n syncMode,\n queryFn: async (ctx): Promise<RecordType[]> => {\n const request = (ctx.queryKey[1] as PbRequest | undefined) ?? {}\n return fetchRecords(request, ctx.queryKey)\n },\n getKey: (item: RecordType) => {\n const record = item as unknown as Record<string, unknown>\n if (!record || typeof record !== 'object' || !('id' in record)) {\n throw new Error(\n `Record in collection '${collectionName}' is missing required 'id' field. Received: ${JSON.stringify(item)}`\n )\n }\n return record.id as string\n },\n onInsert:\n options?.onInsert === false\n ? undefined\n : (options?.onInsert ??\n (async ({ transaction }) => {\n const created = await Promise.all(\n transaction.mutations.map(async mutation => {\n const {\n created: _created,\n updated: _updated,\n collectionId: _collectionId,\n collectionName: _collectionName,\n ...data\n } = mutation.modified as unknown as Record<string, unknown>\n return pb.collection(collectionName).create(data)\n })\n )\n writeBackAfterPersisted(transaction, created)\n return { refetch: refetchOnMutation }\n })),\n onUpdate:\n options?.onUpdate === false\n ? undefined\n : (options?.onUpdate ??\n (async ({ transaction }) => {\n const updated = await Promise.all(\n transaction.mutations.map(async mutation => {\n const recordWithId = mutation.original as { id: string }\n return pb\n .collection(collectionName)\n .update(recordWithId.id, mutation.changes)\n })\n )\n writeBackAfterPersisted(transaction, updated)\n return { refetch: refetchOnMutation }\n })),\n onDelete:\n options?.onDelete === false\n ? undefined\n : (options?.onDelete ??\n (async ({ transaction }) => {\n await Promise.all(\n transaction.mutations.map(async mutation => {\n const recordWithId = mutation.original as { id: string }\n await pb.collection(collectionName).delete(recordWithId.id)\n })\n )\n return { refetch: refetchOnMutation }\n })),\n })\n\n // queryCollectionOptions consumes `gcTime` for the underlying react-query\n // observer and never forwards it to the collection options it returns, so\n // the DB collection's own lifecycle GC (what controls when an idle\n // collection reaches 'cleaned-up') would silently fall back to its\n // 5-minute default. Re-apply it explicitly so a caller-supplied value\n // reaches both layers.\n const collectionOptions =\n options?.collectionOptions?.gcTime === undefined\n ? queryCollectionConfig\n : { ...queryCollectionConfig, gcTime: options.collectionOptions.gcTime }\n\n // Write the server's copy of a mutation's rows back AFTER the transaction\n // has persisted — never from inside its handler.\n //\n // TanStack DB keeps a completed transaction's optimistic draft visible\n // until a synced write for the key arrives, so a record the server\n // fills in (a number, a timestamp) reaches the screen only through that\n // later synced write. A write-back issued from inside the handler lands\n // while the transaction is still `persisting`; TanStack applies it,\n // then on completion re-adds the draft as a \"confirmed but unsynced\"\n // overlay and waits for a synced write that already happened. If the\n // realtime echo has ALSO already been consumed (it arrives before the\n // create resolves under load, and an echo carrying the same `updated`\n // as the write-back is dropped as stale), nothing ever clears the\n // overlay: the row shows the draft — minus every server-assigned field\n // — until a reload. Deferring the write-back to after persistence makes\n // it the synced write TanStack is waiting for.\n //\n // `markConfirmedPresent` still runs immediately: the in-flight fetch\n // bookkeeping needs to know the rows are confirmed the moment the\n // server said so, not a tick later.\n //\n // The deferred write itself: a no-op until the collection is ready\n // (writing into the synced store before sync has initialized throws,\n // and with no live query there is nothing to keep in sync — the next\n // query fetches the already-persisted state; the transaction can\n // outlive the last subscriber), and it drops any row the store already\n // supersedes — a realtime echo may have landed a newer copy while the\n // transaction was settling, and writing the response over it would\n // revert the row.\n function writeBackAfterPersisted(\n transaction: { isPersisted: { promise: Promise<unknown> } },\n records: RecordType[]\n ): void {\n markConfirmedPresent(records)\n void transaction.isPersisted.promise.then(\n () => {\n if (!collection.utils || !collection.isReady()) return\n const fresh = records.filter(record => !isStaleServerRecord(record))\n if (fresh.length === 0) return\n writeOwn(() => collection.utils.writeUpsert(fresh))\n },\n // A rejected transaction rolled its draft back; there is\n // nothing to write and nothing to report here.\n () => undefined\n )\n }\n\n // Set while pbtsdb performs its own authoritative writes (mutation-response\n // write-backs and realtime echoes) through collection.utils.*. Those writes\n // share the same sync `write` primitive as the query-result reconcile path\n // (see the sync.sync wrapper below), so the guard uses this flag to tell them\n // apart: pbtsdb's own writes are exempt from the optimistic-pending arm of the\n // guard (the mutation-response write-back intentionally lands the confirmed\n // value while that very mutation's optimistic overlay is still in flight).\n let applyingOwnWrite = false\n function writeOwn(fn: () => void): void {\n applyingOwnWrite = true\n try {\n fn()\n } finally {\n applyingOwnWrite = false\n }\n }\n\n // The record id a synced insert/update targets, or null when the op is a delete\n // (terminal — never guarded) or carries no usable key.\n function syncedWriteKey(op: { type: string; value?: unknown; key?: unknown }): string | null {\n if (op.type !== 'insert' && op.type !== 'update') return null\n if (typeof op.key === 'string') return op.key\n const id = (op.value as { id?: unknown } | undefined)?.id\n return typeof id === 'string' ? id : null\n }\n\n // Guard the synced write path that pbtsdb does not otherwise control:\n // @tanstack/query-db-collection's applySuccessfulResult reconciles every query\n // result into the synced store via this same `write`, with no recency or\n // optimistic check. Under on-demand contention a single-row/subset read can\n // resolve with a pre-mutation row and land here after the row already moved on,\n // reverting it. We drop such a synced insert/update when either it targets a key\n // with a pending optimistic mutation (see the arm below) or it is strictly older\n // than the synced row (an out-of-order read). pbtsdb's own writes\n // (applyingOwnWrite) skip the optimistic arm; they are staleness-filtered\n // upstream by writeBackAfterPersisted/isStaleEcho.\n function shouldDropSyncedWrite(op: { type: string; value?: unknown; key?: unknown }): boolean {\n const key = syncedWriteKey(op)\n if (key === null) return false\n // Optimistic arm: only guard a key already present in the synced store. A\n // write to a key the synced store doesn't yet hold is populating it (e.g. the\n // initial fetch landing a row the user just optimistically inserted) and must\n // pass — dropping it would leave the row absent once the overlay clears. A\n // write to a key already synced, while an optimistic mutation is pending, is a\n // racing read that would revert the in-flight value, so drop it.\n if (\n !applyingOwnWrite &&\n hasPendingOptimisticMutation(key) &&\n collection._state.syncedData.has(key)\n ) {\n logger.debug('Dropping synced write for optimistically-pending row', {\n collectionName,\n id: key,\n })\n return true\n }\n if (isStaleServerRecord(op.value)) {\n logger.debug('Dropping stale synced write', { collectionName, id: key })\n return true\n }\n return false\n }\n\n // A view's subscription is tagged in viewPaths (see createView below); this\n // adds the view's expand paths to load options for a tagged subscription so\n // loadSubset/unloadSubset fetch (and later untrack) with the right `expand`.\n // A subscription's initial snapshot loads synchronously inside\n // collection.subscribeChanges, before that call returns the subscription\n // object a view tags in viewPaths — so that first loadSubset cannot yet be\n // looked up by identity. While a view's subscribeChanges call is on the\n // stack, its paths are used for load options with no tagged subscription;\n // every later call (untracked demand growth, unloadSubset) is tagged by then.\n let subscribingViewPaths: string[] | undefined\n\n function withViewExpand(opts: LoadSubsetOptions): LoadOptions {\n const paths =\n (opts.subscription && viewPaths.get(opts.subscription)) ?? subscribingViewPaths\n return paths ? { ...opts, expand: paths } : opts\n }\n\n // Wrap the sync factory so every synced `write` flows through the guard above,\n // and every loadSubset/unloadSubset call is tagged with a view's expand paths.\n // @tanstack/db invokes sync.sync with the write primitives; we hand back the\n // same params with a filtered `write`. begin/commit/markReady/etc. pass through.\n const innerSync = collectionOptions.sync.sync\n collectionOptions.sync = {\n ...collectionOptions.sync,\n sync: (params: Parameters<typeof innerSync>[0]) => {\n const guardedWrite: typeof params.write = message => {\n const op = message as { type: string; value?: unknown; key?: unknown }\n if (op.type === 'delete' && !applyingOwnWrite) forgetMarksFor(op.value)\n if (shouldDropSyncedWrite(op)) return\n return params.write(message)\n }\n const res = innerSync({ ...params, write: guardedWrite })\n if (!res || typeof res === 'function') return res\n const { loadSubset, unloadSubset } = res\n return {\n ...res,\n loadSubset: loadSubset\n ? (opts: LoadSubsetOptions) => loadSubset(withViewExpand(opts))\n : undefined,\n unloadSubset: unloadSubset\n ? (opts: LoadSubsetOptions) => unloadSubset(withViewExpand(opts))\n : undefined,\n }\n },\n }\n\n const collection = createTanStackCollection(collectionOptions)\n\n const views = new Map<string, object>()\n\n function createView(paths: string[]): object {\n const view = Object.create(collection)\n Object.defineProperties(view, {\n id: { value: `${collectionName}?expand=${paths.join(',')}` },\n subscribeChanges: {\n value: (...args: Parameters<typeof collection.subscribeChanges>) => {\n noteViewSubscribed(paths)\n subscribingViewPaths = paths\n try {\n const subscription = collection.subscribeChanges(...args)\n viewPaths.set(subscription, paths)\n return subscription\n } finally {\n subscribingViewPaths = undefined\n }\n },\n },\n fetchRelations: {\n value: () => {\n throw new Error(`A view of \"${collectionName}\" cannot fetch further relations`)\n },\n },\n })\n return view\n }\n\n function fetchRelations(...paths: string[]): object {\n for (const path of paths) validateExpandPath(collectionName, relationTargets, path)\n const all = normalizePaths([...alwaysFetch, ...paths])\n if (all.every(path => alwaysFetch.includes(path))) return collection\n const key = all.join(',')\n let view = views.get(key)\n if (!view) {\n view = createView(all)\n views.set(key, view)\n }\n return view\n }\n\n // True when the key has an in-flight (not yet settled) optimistic mutation.\n // While pending, the optimistic overlay — not syncedData — is the visible value,\n // so any synced write would only take effect once the overlay collapses, and an\n // older/racing read landing here is exactly what reverts a just-applied move.\n function hasPendingOptimisticMutation(key: string): boolean {\n const state = collection._state as unknown as {\n optimisticUpserts: { has: (k: string) => boolean }\n optimisticDeletes: { has: (k: string) => boolean }\n }\n return state.optimisticUpserts.has(key) || state.optimisticDeletes.has(key)\n }\n\n // Read the PocketBase `updated` autodate from a record, if present.\n // Collections without an `updated` field opt out of staleness checks.\n function recordUpdatedAt(record: unknown): string | undefined {\n const updated = (record as { updated?: unknown } | null | undefined)?.updated\n return typeof updated === 'string' && updated !== '' ? updated : undefined\n }\n\n // A server record is stale relative to the synced store when an entry for\n // the same key already holds a newer `updated` timestamp. PocketBase can\n // redeliver or reorder realtime echoes (and a slow mutation response can\n // resolve after a newer echo), so applying an older write would revert the\n // row. ISO 8601 timestamps sort lexicographically, so string comparison is\n // chronological. When either side lacks a comparable timestamp we cannot\n // tell, so we treat the write as fresh and let it through.\n //\n // Strictly older, never equal. PocketBase stamps `updated` to the\n // millisecond and bumps it on every write, so an equal timestamp is the\n // same version of the row: re-landing it changes nothing, and it is what\n // lets a confirmed value clear a lingering optimistic overlay. (An earlier\n // `<=` variant on the query-result path guarded against a read carrying\n // old content under a new timestamp, which a real server cannot produce;\n // the revert it chased was the write-back racing its own transaction,\n // fixed in writeBackAfterPersisted.)\n function isStaleServerRecord(record: unknown): boolean {\n const id = (record as { id?: unknown } | null | undefined)?.id\n if (typeof id !== 'string') return false\n const incoming = recordUpdatedAt(record)\n if (!incoming) return false\n const current = recordUpdatedAt(\n collection._state.syncedData.get(id) as RecordType | undefined\n )\n if (current === undefined) return false\n return incoming < current\n }\n\n // Decide whether a realtime echo should be dropped as stale. Under realtime\n // contention PocketBase can redeliver or reorder events, so an echo carrying\n // a pre-mutation value can arrive after the row already moved on (e.g. the\n // local mutation that just wrote the fresh value back). Applying a\n // strictly-older create/update echo would revert the row, so it is ignored.\n // Deletes are terminal and not timestamp-guarded.\n function isStaleEcho(event: RecordSubscription<RecordType>): boolean {\n if (event.action !== 'create' && event.action !== 'update') return false\n if (!isStaleServerRecord(event.record)) return false\n logger.debug('Ignoring stale realtime echo', {\n collectionName,\n id: (event.record as { id?: string } | undefined)?.id,\n })\n return true\n }\n\n // Real-time subscription state\n let unsubscribeFn: (() => Promise<void>) | null = null\n let isSubscribed = false\n let subscriptionPromise: Promise<void> | null = null\n let subscriptionResolve: (() => void) | null = null\n // The `expand` string sent with the currently live subscription, so a\n // caller that widened requestedExpand mid-flight can tell whether the\n // subscription that just landed already covers it.\n let subscribedExpand: string | undefined\n\n // All start/stop/restart work is serialized onto this promise tail so\n // overlapping callers (two views created back-to-back, a reconnect\n // racing a widened expand) never run startSubscription/stopSubscription\n // concurrently — the tail is what lets a later caller's restart observe\n // the outcome of an earlier caller's in-flight start. Errors are caught\n // and logged so a failed step never poisons the tail for later work.\n let subscriptionWork: Promise<void> = Promise.resolve()\n function enqueueSubscriptionWork(fn: () => Promise<void>): Promise<void> {\n const run = subscriptionWork.then(fn, fn).catch(error => {\n logger.error('Subscription work failed', { collectionName, error })\n })\n subscriptionWork = run\n return run\n }\n\n // Handle real-time events from PocketBase.\n //\n // The write primitives differ in how they treat a key that is absent from\n // the *synced* store (collection._state.syncedData, which is what they\n // validate against — not the optimistic view exposed by collection.has()):\n // - writeInsert / writeUpsert: idempotent, never throw on an absent key.\n // - writeDelete: throws DeleteOperationItemNotFoundError on an absent key.\n // So only the delete branch can throw, and we make it idempotent below.\n // Runs BEFORE the stale-echo filter: even a stale create/update echo\n // proves the server holds the row. Delete echoes need no marking — the\n // merge checks the synced store, which the delete's writeDelete empties.\n function markEchoPresence(event: RecordSubscription<RecordType>): void {\n if (event.action !== 'delete') markConfirmedPresent([event.record])\n }\n\n const handleRealtimeEvent = (event: RecordSubscription<RecordType>) => {\n if (!collection.utils) return\n markEchoPresence(event)\n if (isStaleEcho(event)) return\n\n const [stored] = stripFetchedRelations([event.record], pendingSubscribeExpand())\n try {\n writeOwn(() =>\n collection.utils.writeBatch(() => {\n switch (event.action) {\n case 'create':\n collection.utils.writeInsert(stored)\n break\n case 'update':\n collection.utils.writeUpsert(stored)\n break\n case 'delete':\n if (event.record && 'id' in event.record) {\n // Throws DeleteOperationItemNotFoundError if the key\n // is no longer in the synced store (see catch below).\n collection.utils.writeDelete((event.record as { id: string }).id)\n }\n break\n }\n })\n )\n } catch (error) {\n // How a delete echo throws: writeDelete fails when its key is already\n // gone from the synced store. That happens when something removed it\n // before the echo arrived:\n // 1. on-demand sync — each useLiveQuery refetches with a server\n // filter, and query-db-collection prunes rows no longer owned by\n // any active query out of the synced store. If that prune (or a\n // concurrent query's reconcile) runs before this client's own\n // delete echo lands, the key is already gone -> throw. This is\n // the on-demand-only race; eager collections have no such second\n // writer to the synced store, so they cannot hit it.\n // 2. a re-delivered SSE delete (e.g. after a reconnect) for a key\n // that was already deleted -> throw on the second echo.\n // In both cases the record is already in its intended end state\n // (gone), so the echo is a no-op and the error is safe to ignore.\n // Anything that is NOT a missing-key delete is a real error: rethrow.\n if (error instanceof DeleteOperationItemNotFoundError) {\n logger.debug('Ignoring delete echo for already-removed record', {\n collectionName,\n id: (event.record as { id?: string } | undefined)?.id,\n })\n } else {\n throw error\n }\n }\n\n if (event.action !== 'delete') {\n upsertExpanded([event.record], relationTargets).catch(error =>\n logger.error('Failed to upsert expanded records from realtime echo', {\n collectionName,\n error,\n })\n )\n }\n }\n\n // The union of expand paths the next (re)subscribe should carry:\n // alwaysFetch plus every path a view has requested. Pure and\n // side-effect-free (unlike realtimeSubscribeOptions below), so it is\n // safe to call more than once per subscribe attempt to detect drift.\n function pendingSubscribeExpand(): string | undefined {\n return joinPaths([...alwaysFetch, ...requestedExpand])\n }\n\n // Collections along every active expand path. Held live (below) so their\n // stores stay fresh for keyed reads (materialize, joins, get()) and for\n // the store-served short circuit.\n function activeExpandTargets(): Set<ExpandTargetCollection> {\n const targets = new Set<ExpandTargetCollection>()\n for (const path of splitPaths(pendingSubscribeExpand())) {\n let current: RelationTargets | undefined = relationTargets\n for (const segment of path.split('.')) {\n const target: ExpandTargetCollection | undefined = current?.[segment]\n if (!target) break\n targets.add(target)\n current = target.relationTargets\n }\n }\n return targets\n }\n\n // The only place held target subscriptions are added or removed, so the\n // map always mirrors the last desired set exactly.\n const heldTargetSubscriptions = new Map<ExpandTargetCollection, { unsubscribe: () => void }>()\n\n function releaseHeldTarget(target: ExpandTargetCollection): void {\n const held = heldTargetSubscriptions.get(target)\n if (!held) return\n heldTargetSubscriptions.delete(target)\n try {\n held.unsubscribe()\n } catch (error) {\n logger.error('Failed to release relation target subscription', {\n collectionName,\n error,\n })\n }\n }\n\n function holdTarget(target: ExpandTargetCollection): void {\n if (heldTargetSubscriptions.has(target) || !target.subscribeChanges) return\n try {\n const held = target.subscribeChanges(() => {}, { includeInitialState: false })\n heldTargetSubscriptions.set(target, held)\n } catch (error) {\n logger.error('Failed to hold relation target subscription', { collectionName, error })\n }\n }\n\n function syncHeldSubscriptions(desired: Set<ExpandTargetCollection>): void {\n for (const target of [...heldTargetSubscriptions.keys()]) {\n if (!desired.has(target)) releaseHeldTarget(target)\n }\n for (const target of desired) holdTarget(target)\n }\n\n // Options for the next (re)subscribe: the expand union above, merged\n // with whatever the factory's own subscribeOptions() supplies rather\n // than overridden by it. Calls the factory callback, so it is invoked\n // exactly once per subscribe attempt (never re-derived afterward).\n function realtimeSubscribeOptions(): RecordSubscribeOptions | undefined {\n const base = factoryOptions?.subscribeOptions?.()\n const expand = joinPaths([\n ...splitPaths(pendingSubscribeExpand()),\n ...splitPaths(base?.expand),\n ])\n return expand ? { ...base, expand } : base\n }\n\n // Start PocketBase real-time subscription. Only ever run through\n // enqueueSubscriptionWork so it never overlaps a stop/restart.\n const doStartSubscription = async () => {\n if (isSubscribed) return\n\n // Create promise before starting so waiters can await it\n if (!subscriptionPromise) {\n subscriptionPromise = new Promise<void>(resolve => {\n subscriptionResolve = resolve\n })\n }\n\n const pendingExpand = pendingSubscribeExpand()\n try {\n unsubscribeFn = await pb\n .collection(collectionName)\n .subscribe('*', handleRealtimeEvent, realtimeSubscribeOptions())\n isSubscribed = true\n subscribedExpand = pendingExpand\n syncHeldSubscriptions(activeExpandTargets())\n logger.debug('Subscription started', { collectionName })\n // Resolve the promise to notify waiters\n if (subscriptionResolve) {\n subscriptionResolve()\n }\n } catch (error) {\n logger.error('Failed to start subscription', { collectionName, error })\n }\n\n // requestedExpand can grow while the subscribe() call above was in\n // flight (a view mounted mid-round-trip sees no live subscription\n // yet, and would otherwise never schedule a restart). Comparing\n // against the pure expand union (not realtimeSubscribeOptions,\n // which would re-invoke the factory's own subscribeOptions()\n // callback) lets this check run after every start with no\n // observable side effect.\n if (pendingSubscribeExpand() !== subscribedExpand) {\n enqueueSubscriptionWork(doRestartSubscription).catch(() => {})\n }\n }\n\n // Stop PocketBase real-time subscription. Only ever run through\n // enqueueSubscriptionWork so it never overlaps a start/restart.\n const doStopSubscription = async (releaseTargets = true) => {\n // Before the guard below: a restart whose subscribe() threw leaves\n // isSubscribed false with targets still held, and this real stop is\n // the only remaining chance to release them.\n if (releaseTargets) {\n syncHeldSubscriptions(new Set())\n invalidateAllMarkedSubsets()\n loadedSubsets.clear()\n }\n if (!isSubscribed || !unsubscribeFn) return\n\n try {\n await unsubscribeFn()\n logger.debug('Subscription stopped', { collectionName })\n } catch (error) {\n logger.debug('Unsubscribe failed (expected if connection closed)', {\n collectionName,\n error,\n })\n } finally {\n // Unconditional: a throwing unsubscribe must not leave the state\n // machine believing it is still subscribed after targets were\n // released, or the next start would return early and never re-hold.\n unsubscribeFn = null\n isSubscribed = false\n subscribedExpand = undefined\n subscriptionPromise = null\n subscriptionResolve = null\n }\n }\n\n // Restart the live subscription, e.g. after the requested expand union\n // grows. A no-op when there is no live subscription to restart — the\n // next first-subscriber start already picks up the current union.\n const doRestartSubscription = async () => {\n if (!isSubscribed) return\n await doStopSubscription(false)\n await doStartSubscription()\n }\n\n const startSubscription = () => enqueueSubscriptionWork(doStartSubscription)\n const stopSubscription = () => enqueueSubscriptionWork(() => doStopSubscription())\n const restartSubscription = () => enqueueSubscriptionWork(doRestartSubscription)\n\n // Record which expand paths a view has subscribed with at least once.\n // Eager collections cannot request per-subset options, so a wider union\n // needs a refetch to pick up the new expand; a live realtime subscription\n // needs restarting so its own expand union grows too.\n function noteViewSubscribed(paths: string[]): void {\n let grew = false\n for (const path of paths) {\n if (requestedExpand.has(path)) continue\n requestedExpand.add(path)\n grew = true\n }\n if (!grew) return\n if (\n syncMode === 'eager' &&\n collection.status !== 'idle' &&\n collection.status !== 'cleaned-up'\n ) {\n void collection.utils.refetch().catch(error =>\n logger.error('Failed to refetch after widening expand', {\n collectionName,\n error,\n })\n )\n }\n // Enqueued unconditionally (not gated on isSubscribed): the tail\n // guarantees this runs after any in-flight start/stop, and\n // doRestartSubscription itself no-ops when nothing is live.\n restartSubscription().catch(error =>\n logger.error('Failed to restart subscription with wider expand', {\n collectionName,\n error,\n })\n )\n }\n\n // Wait for subscription to be established (for testing)\n const waitForSubscription = async (timeout = 5000): Promise<void> => {\n if (isSubscribed) return\n\n if (!subscriptionPromise) {\n // No subscription in progress, wait for one to start\n await new Promise<void>(resolve => {\n const checkInterval = setInterval(() => {\n if (subscriptionPromise) {\n clearInterval(checkInterval)\n resolve()\n }\n }, 10)\n setTimeout(() => {\n clearInterval(checkInterval)\n resolve()\n }, timeout)\n })\n }\n\n if (subscriptionPromise) {\n await Promise.race([\n subscriptionPromise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error('Subscription timeout')), timeout)\n ),\n ])\n }\n }\n\n // Manage subscription based on collection subscriber count\n collection.on(\n 'subscribers:change',\n (event: { subscriberCount: number; previousSubscriberCount: number }) => {\n const newCount = event.subscriberCount\n const previousCount = event.previousSubscriberCount\n\n if (newCount > 0 && previousCount === 0) {\n // First subscriber - start real-time subscription\n startSubscription().catch(() => {})\n } else if (newCount === 0 && previousCount > 0) {\n // Last subscriber removed - stop real-time subscription\n stopSubscription().catch(() => {})\n }\n }\n )\n\n registerMarkInvalidationEvents(\n {\n onStatusChange: callback => collection.on('status:change', callback),\n onTruncate: callback => collection.on('truncate', callback),\n },\n () => loadedSubsets.clear()\n )\n\n // Add collectionName and subscription helpers\n Object.assign(collection, {\n collectionName,\n relationTargets,\n waitForSubscription,\n isSubscribed: () => isSubscribed,\n heldRelationTargetCount: () => heldTargetSubscriptions.size,\n markSubsetLoaded,\n loadedSubsetCount,\n fetchRelations,\n })\n\n return collection as unknown as BuiltCollection<RecordType>\n}\n","import type { Collection } from '@tanstack/db'\nimport type { QueryCollectionUtils } from '@tanstack/query-db-collection'\nimport type { QueryClient } from '@tanstack/react-query'\nimport type PocketBase from 'pocketbase'\nimport { buildCollection, type CreateCollectionFactoryOptions } from './build-collection'\nimport type {\n CreateCollectionOptions,\n ExpandPath,\n ExtractRecordType,\n InsertInputOf,\n PbMeta,\n RelationsOf,\n SchemaDeclaration,\n} from './types'\n\nexport type { CreateCollectionFactoryOptions } from './build-collection'\nexport type { BaseRecord, CreateCollectionOptions, SchemaDeclaration } from './types'\n\n/**\n * A pbtsdb collection or view: a TanStack DB collection over\n * `ExtractRecordType<Schema, C>` rows, plus pbtsdb's subscription helpers.\n * Views are created by {@link PbCollection.fetchRelations} and are leaves:\n * they have no further `fetchRelations()`.\n */\nexport type PbCollectionView<\n Schema extends SchemaDeclaration,\n C extends keyof Schema & string,\n Opts,\n> = Collection<\n ExtractRecordType<Schema, C>,\n string | number,\n QueryCollectionUtils<\n ExtractRecordType<Schema, C>,\n string | number,\n ExtractRecordType<Schema, C>\n >,\n never,\n InsertInputOf<Schema, C, Opts>\n> & {\n /** The PocketBase collection name */\n readonly collectionName: C\n /** Wait for the real-time subscription to be established (useful in tests) */\n waitForSubscription: (timeout?: number) => Promise<void>\n /** Whether the collection has an active real-time subscription */\n isSubscribed: () => boolean\n /** @internal relation targets declared through `relations` */\n readonly relationTargets: Record<string, unknown> | undefined\n /** @internal number of relation targets currently held live */\n readonly heldRelationTargetCount: () => number\n /** @internal record that every row with `field === value` is now in this collection's store */\n readonly markSubsetLoaded: (field: string, value: string) => void\n /** @internal number of field/value pairs currently marked loaded */\n readonly loadedSubsetCount: () => number\n /** @internal phantom; never present at runtime */\n readonly __pbtsdb: PbMeta<Schema, C, RelationsOf<Opts>>\n}\n\n/**\n * The collection returned by {@link createCollection}: a {@link PbCollectionView}\n * plus `fetchRelations()` for per-query views.\n */\nexport type PbCollection<\n Schema extends SchemaDeclaration,\n C extends keyof Schema & string,\n Opts,\n> = PbCollectionView<Schema, C, Opts> & {\n /**\n * A view of this collection whose queries also fetch `paths` and file the\n * expanded records into their target collections. Rows are unchanged; read\n * related records through `materialize()`, a join, or the target's `get()`.\n */\n fetchRelations<const P extends readonly ExpandPath<RelationsOf<Opts>>[]>(\n ...paths: P\n ): PbCollectionView<Schema, C, Opts>\n}\n\ntype AlwaysFetchRelationsCheck<Opts> = {\n alwaysFetchRelations?: readonly ExpandPath<RelationsOf<Opts>>[]\n}\n\n/**\n * Creates a type-safe TanStack DB collection backed by PocketBase.\n * Use this when you need fine-grained control or need to create collections with dependencies.\n *\n * @param pb - PocketBase client instance\n * @param queryClient - TanStack Query client\n * @returns A curried function that takes collection name and options\n *\n * @example\n * Basic usage:\n * ```ts\n * const booksCollection = createCollection<Schema>(pb, queryClient)('books', {});\n *\n * // Use directly\n * const books = await booksCollection.getFullList();\n * ```\n *\n * @example\n * With relations fetched on every request:\n * ```ts\n * const authorsCollection = createCollection<Schema>(pb, queryClient)('authors', {});\n * const booksCollection = createCollection<Schema>(pb, queryClient)('books', {\n * relations: { author: authorsCollection },\n * alwaysFetchRelations: ['author'],\n * });\n *\n * const { data } = useLiveQuery((q) => q.from({ books: booksCollection }));\n * // The expanded author is filed into authorsCollection, not kept on the row.\n * authorsCollection.get(data[0].author)?.name\n * ```\n *\n * @example\n * With a per-query fetchRelations view:\n * ```ts\n * const booksCollection = createCollection<Schema>(pb, queryClient)('books', {\n * relations: { author: authorsCollection },\n * });\n *\n * const view = booksCollection.fetchRelations('author');\n * const { data } = useLiveQuery((q) => q.from({ books: view }));\n * // Same target collection as above; the view only affects what gets fetched.\n * authorsCollection.get(data[0].author)?.name\n * ```\n */\nexport function createCollection<Schema extends SchemaDeclaration>(\n pb: PocketBase,\n queryClient: QueryClient,\n factoryOptions?: CreateCollectionFactoryOptions\n) {\n return <C extends keyof Schema & string, const Opts extends CreateCollectionOptions<Schema, C>>(\n collectionName: C,\n options?: Opts & AlwaysFetchRelationsCheck<Opts>\n ): PbCollection<Schema, C, Opts> => {\n return buildCollection<Schema, C>({\n pb,\n queryClient,\n factoryOptions,\n collectionName,\n options,\n }) as unknown as PbCollection<Schema, C, Opts>\n }\n}\n","/**\n * Generates a new PocketBase-compatible record ID.\n * Returns a 15-character alphanumeric string (lowercase letters and numbers).\n *\n * PocketBase uses 15-character IDs for records, formatted as lowercase alphanumeric.\n *\n * @returns A 15-character alphanumeric string suitable for use as a PocketBase record ID\n *\n * @example\n * ```ts\n * const id = newRecordId(); // \"a1b2c3d4e5f6g7h\"\n * ```\n */\nexport function newRecordId(): string {\n const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'\n let result = ''\n for (let i = 0; i < 15; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length))\n }\n return result\n}\n"]}