@lsync/server 0.0.2 → 0.0.3
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/README.md +46 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/index.d.mts +26 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +214 -56
- package/dist/index.mjs.map +1 -1
- package/dist/{router-D_wddPdy.d.mts → router-B9emOwKj.d.mts} +13 -110
- package/dist/{router-D_wddPdy.d.mts.map → router-B9emOwKj.d.mts.map} +1 -1
- package/dist/router-CZnnFmXh.mjs +39 -0
- package/dist/router-CZnnFmXh.mjs.map +1 -0
- package/package.json +3 -4
- package/dist/router-C4eYfMV7.mjs +0 -39
- package/dist/router-C4eYfMV7.mjs.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["readExpressionReferences","readExpressionRow","compileReadExpression","val","valueAtPath","combinePredicates","matchesReadPredicate","readExpressionRow","tableName","jsonPath","quoteIdentifier"],"sources":["../src/access-expression.ts","../src/collections.ts","../src/access.ts","../src/collection-normalize.ts","../src/sqlite-sql.ts","../src/sqlite-json-read.ts","../src/storage.ts","../src/collection-builder.ts","../src/definition-builder.ts","../src/durable-object-rpc.ts","../src/history-watermarks.ts","../src/history.ts","../src/messages.ts","../src/socket-attachment.ts","../src/access-invalidation.ts","../src/subscription-invalidation.ts","../src/validation.ts","../src/durable-object.ts","../src/worker.ts"],"sourcesContent":["import {\n compileReadExpression,\n readExpressionReferences,\n readExpressionRow,\n type FuncExpression,\n type ReadExpression,\n type ReadExpressionRow,\n type RefExpression,\n type ValExpression,\n} from \"@lsync/transport\";\nimport type { ReadPredicate } from \"./types\";\n\nexport interface ReferenceDependency {\n collection: string;\n field: string;\n key: string | number;\n name: string;\n}\n\nexport interface ReducedAccessExpression {\n allow: boolean;\n dependencies: Array<ReferenceDependency>;\n predicate?: ReadPredicate;\n}\n\nexport function accessRows(referenceNames: Array<string>): {\n references: Record<string, ReadExpressionRow<Record<string, unknown>>>;\n row: ReadExpressionRow<Record<string, unknown>>;\n} {\n return {\n references: readExpressionReferences(referenceNames),\n row: readExpressionRow(),\n };\n}\n\nexport function reduceAccessExpression(\n expression: ReadExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n): ReducedAccessExpression {\n const dependencies: Array<ReferenceDependency> = [];\n const reduced = reduce(expression, references, dependencies);\n\n if (isVal(reduced)) {\n return {\n allow: reduced.value === true,\n dependencies,\n };\n }\n\n return {\n allow: true,\n dependencies,\n predicate: compileReadExpression(reduced),\n };\n}\n\nfunction reduce(\n expression: ReadExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const unwrapped = unwrap(expression);\n if (isVal(unwrapped)) return unwrapped;\n\n if (isRef(unwrapped)) {\n return reduceRef(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"and\") {\n return reduceAnd(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"or\") {\n return reduceOr(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"not\") {\n const child = reduceExpressionArg(unwrapped.args[0], references, dependencies);\n return isVal(child) ? val(child.value !== true) : func(\"not\", child);\n }\n\n const args = unwrapped.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (args.every(isVal)) {\n return val(\n evaluate(\n unwrapped.name,\n args.map((arg) => arg.value),\n ),\n );\n }\n\n return func(unwrapped.name, ...args);\n}\n\nfunction reduceRef(\n expression: RefExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n if (expression.source !== \"reference\") {\n return expression;\n }\n\n const name = expression.name;\n const reference = name ? references.get(name) : undefined;\n if (!name || !reference) {\n return val(undefined);\n }\n\n const field = expression.path.join(\".\");\n dependencies.push({ collection: reference.collection, field, key: reference.key, name });\n return val(valueAtPath(reference.value, expression.path));\n}\n\nfunction reduceAnd(\n expression: FuncExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const reduced = expression.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (reduced.some((arg) => isVal(arg) && arg.value !== true)) return val(false);\n const remaining = reduced.filter((arg) => !isVal(arg));\n if (remaining.length === 0) return val(true);\n return remaining.length === 1 ? remaining[0]! : func(\"and\", ...remaining);\n}\n\nfunction reduceOr(\n expression: FuncExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const reduced = expression.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (reduced.some((arg) => isVal(arg) && arg.value === true)) return val(true);\n const remaining = reduced.filter((arg) => !isVal(arg));\n if (remaining.length === 0) return val(false);\n return remaining.length === 1 ? remaining[0]! : func(\"or\", ...remaining);\n}\n\nfunction reduceExpressionArg(\n value: unknown,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n return isExpression(value) ? reduce(value, references, dependencies) : val(value);\n}\n\nfunction evaluate(name: string, args: Array<unknown>): boolean {\n const [left, right] = args;\n switch (name) {\n case \"eq\":\n return left === right;\n case \"not_eq\":\n return left !== right;\n case \"gt\":\n return compare(left, right, (a, b) => a > b);\n case \"gte\":\n return compare(left, right, (a, b) => a >= b);\n case \"lt\":\n return compare(left, right, (a, b) => a < b);\n case \"lte\":\n return compare(left, right, (a, b) => a <= b);\n case \"in\":\n return Array.isArray(right) && right.includes(left);\n default:\n throw new Error(`Unsupported read access operator: ${name}`);\n }\n}\n\nfunction compare(\n left: unknown,\n right: unknown,\n compareValues: (left: number | string, right: number | string) => boolean,\n): boolean {\n if (typeof left === \"number\" && typeof right === \"number\") return compareValues(left, right);\n if (typeof left === \"string\" && typeof right === \"string\") return compareValues(left, right);\n return false;\n}\n\nfunction func(name: string, ...args: Array<unknown>): FuncExpression {\n return { type: \"func\", name, args };\n}\n\nfunction val(value: unknown): ValExpression {\n return { type: \"val\", value };\n}\n\nfunction valueAtPath(value: unknown, path: Array<string | number>): unknown {\n return path.reduce<unknown>((current, segment) => {\n if (typeof current !== \"object\" || current === null) return undefined;\n return (current as Record<string, unknown>)[String(segment)];\n }, value);\n}\n\nfunction unwrap(expression: ReadExpression): FuncExpression | RefExpression | ValExpression {\n return \"expression\" in expression ? unwrap(expression.expression) : expression;\n}\n\nfunction isExpression(value: unknown): value is ReadExpression {\n return typeof value === \"object\" && value !== null && (\"type\" in value || \"expression\" in value);\n}\n\nfunction isVal(value: ReadExpression): value is ValExpression {\n const unwrapped = unwrap(value);\n return unwrapped.type === \"val\";\n}\n\nfunction isRef(value: ReadExpression): value is RefExpression {\n const unwrapped = unwrap(value);\n return unwrapped.type === \"ref\";\n}\n","import type { ApiHandler, CollectionConfig, CollectionConfigs } from \"./types\";\n\nexport interface ResolvedCollection {\n name: string;\n collection: CollectionConfig;\n params: Record<string, string>;\n scope: string;\n}\n\ninterface PatternMatch {\n name: string;\n collection: CollectionConfig;\n params: Record<string, string>;\n staticSegments: number;\n segments: number;\n index: number;\n}\n\nexport function resolveCollection(\n collectionName: string,\n collections: CollectionConfigs = {},\n): ResolvedCollection | undefined {\n const exact = collections[collectionName];\n\n if (exact) {\n return {\n name: collectionName,\n collection: exact,\n params: {},\n scope: collectionScope(collectionName),\n };\n }\n\n const matches = Object.entries(collections).flatMap(([name, collection], index) => {\n const match = matchCollectionPattern(name, collectionName);\n\n return match\n ? [\n {\n name,\n collection,\n params: match.params,\n staticSegments: match.staticSegments,\n segments: match.segments,\n index,\n },\n ]\n : [];\n });\n\n const best = matches.sort(comparePatternMatches)[0];\n if (!best) {\n return undefined;\n }\n\n return {\n name: best.name,\n collection: best.collection,\n params: best.params,\n scope: collectionScope(collectionName),\n };\n}\n\nexport function collectionScope(collectionName: string): string {\n const segments = splitCollectionPath(collectionName);\n return `/${segments.map(normalizeSegment).join(\"/\")}/`;\n}\n\nexport function isCollectionPattern(collectionName: string): boolean {\n return collectionName.split(\"/\").some((segment) => /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(segment));\n}\n\nexport function collectionApiHandlers(\n collections: CollectionConfigs = {},\n): Record<string, ApiHandler> {\n const handlers: Record<string, ApiHandler> = {};\n\n for (const [collectionPath, collection] of Object.entries(collections)) {\n for (const [name, definition] of Object.entries(collection.api ?? {})) {\n const path = defaultCollectionApiPath(collectionPath, name);\n\n if (handlers[path]) {\n throw new Error(`Duplicate API path: ${path}`);\n }\n\n handlers[path] = (args) =>\n definition.handler({\n ...args,\n input: definition.input.parse(args.input),\n });\n }\n }\n\n return handlers;\n}\n\nexport function defaultCollectionApiPath(collectionPath: string, name: string): string {\n const prefix = splitCollectionPath(collectionPath)\n .filter((segment) => !collectionPathParamName(segment))\n .join(\".\");\n\n return prefix ? `${prefix}.${name}` : name;\n}\n\nfunction matchCollectionPattern(\n pattern: string,\n collectionName: string,\n): Omit<PatternMatch, \"name\" | \"collection\" | \"index\"> | undefined {\n if (!isCollectionPattern(pattern)) {\n return undefined;\n }\n\n const patternSegments = splitCollectionPath(pattern);\n const collectionSegments = splitCollectionPath(collectionName);\n\n if (patternSegments.length !== collectionSegments.length) {\n return undefined;\n }\n\n const params: Record<string, string> = {};\n let staticSegments = 0;\n\n for (const [index, segment] of patternSegments.entries()) {\n const param = segment.match(/^\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\n if (param?.[1]) {\n params[param[1]] = decodeURIComponent(collectionSegments[index] ?? \"\");\n continue;\n }\n\n if (segment !== collectionSegments[index]) {\n return undefined;\n }\n\n staticSegments += 1;\n }\n\n return {\n params,\n staticSegments,\n segments: patternSegments.length,\n };\n}\n\nfunction comparePatternMatches(left: PatternMatch, right: PatternMatch): number {\n return (\n right.staticSegments - left.staticSegments ||\n right.segments - left.segments ||\n left.index - right.index\n );\n}\n\nfunction splitCollectionPath(path: string): Array<string> {\n const trimmed = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n\n if (!trimmed) {\n return [];\n }\n\n return trimmed.split(\"/\");\n}\n\nfunction collectionPathParamName(segment: string): string | undefined {\n return (\n segment.match(/^\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/)?.[1] ??\n segment.match(/^:([A-Za-z_][A-Za-z0-9_]*)$/)?.[1]\n );\n}\n\nfunction normalizeSegment(segment: string): string {\n return encodeURIComponent(decodeURIComponent(segment));\n}\n","import { matchesReadPredicate, readExpressionRow } from \"@lsync/transport\";\nimport { accessRows, reduceAccessExpression, type ReferenceDependency } from \"./access-expression\";\nimport { resolveCollection } from \"./collections\";\nimport type {\n AccessAuth,\n AccessReference,\n ApiAccessHandler,\n Batch,\n CollectionAccessConfig,\n CollectionConfigs,\n OperationType,\n ReadPredicate,\n ReadQuery,\n Update,\n} from \"./types\";\n\nexport interface AccessStore {\n read(collection: string, key: string | number): Record<string, unknown> | undefined;\n}\n\nexport interface ReadAccessDecision {\n allow: boolean;\n dependencies: Array<ReferenceDependency>;\n predicate?: ReadPredicate;\n}\n\nexport function authorizeReadQuery(\n query: ReadQuery,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadQuery | undefined {\n const decision = readAccessDecision(query.collection, collections, auth, store);\n if (!decision.allow) return undefined;\n if (!decision.predicate) return query;\n\n const predicate = combinePredicates(decision.predicate, query.predicate);\n return predicate ? { ...query, predicate } : query;\n}\n\nexport function visibleUpdateForAuth(\n update: Update,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): Update | undefined {\n const decision = readAccessDecision(update.collection, collections, auth, store);\n if (!decision.allow) return undefined;\n if (!decision.predicate) return update;\n\n const before = update.previousValue\n ? matchesReadPredicate(update.previousValue, decision.predicate)\n : false;\n const after = update.value ? matchesReadPredicate(update.value, decision.predicate) : false;\n\n if (!before && !after) return undefined;\n\n if (before && !after) {\n const { previousValue, value, ...base } = update;\n void previousValue;\n void value;\n return { ...base, type: \"delete\" };\n }\n\n return !before && after && update.type === \"update\" ? { ...update, type: \"insert\" } : update;\n}\n\nexport function authorizeWriteBatch(\n batch: Batch,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): void {\n for (const update of batch.updates) {\n const decision = writeAccessDecision(update, collections, auth, store);\n if (decision.allow) continue;\n\n throw new Error(`Access denied for ${update.type} on ${update.collection}`);\n }\n}\n\nexport function authorizeApiCall(\n handler: ApiAccessHandler | undefined,\n name: string,\n input: unknown,\n auth: AccessAuth,\n): void {\n if (!handler) return;\n\n const row = asRecord(input) ?? {};\n const expression = handler({ auth, input: readExpressionRow() });\n const decision = reduceAccessExpression(expression, new Map());\n const allowed =\n decision.allow && (!decision.predicate || matchesReadPredicate(row, decision.predicate));\n\n if (!allowed) {\n throw new Error(`Access denied for API: ${name}`);\n }\n}\n\nexport function readAccessDecision(\n collection: string,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadAccessDecision {\n const resolved = resolveCollection(collection, collections);\n if (!resolved) {\n return { allow: true, dependencies: [] };\n }\n\n const access = resolved?.collection.access;\n if (!access?.read) return { allow: true, dependencies: [] };\n\n const references = accessReferences(collection, collections, auth);\n const rows = accessRows([...references.keys()]);\n const expression = access.read({\n auth,\n collection: resolved.scope,\n references: rows.references,\n params: resolved.params,\n pattern: resolved.name,\n row: rows.row,\n });\n const referenceValues = new Map(\n [...references].map(([name, reference]) => [\n name,\n {\n ...reference,\n value: store.read(reference.collection, reference.key),\n },\n ]),\n );\n\n return reduceAccessExpression(expression, referenceValues);\n}\n\nexport function writeAccessDecision(\n update: Update,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadAccessDecision {\n const resolved = resolveCollection(update.collection, collections);\n if (!resolved) return { allow: true, dependencies: [] };\n\n const access = resolved.collection.access;\n const handler = writeAccessHandler(access, update.type);\n if (!handler) return { allow: true, dependencies: [] };\n\n const row = writeAccessRow(update, store);\n if (!row) return { allow: false, dependencies: [] };\n\n const references = accessReferences(update.collection, collections, auth);\n const rows = accessRows([...references.keys()]);\n const expression = handler({\n auth,\n collection: resolved.scope,\n references: rows.references,\n params: resolved.params,\n pattern: resolved.name,\n row: rows.row,\n });\n const referenceValues = new Map(\n [...references].map(([name, reference]) => [\n name,\n {\n ...reference,\n value: store.read(reference.collection, reference.key),\n },\n ]),\n );\n const decision = reduceAccessExpression(expression, referenceValues);\n\n if (!decision.allow || !decision.predicate) return decision;\n\n return matchesReadPredicate(row, decision.predicate) ? decision : { ...decision, allow: false };\n}\n\nexport function accessReferences(\n collection: string,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n): Map<string, { collection: string; key: string | number }> {\n const resolved = resolveCollection(collection, collections);\n const references = resolved?.collection.access?.references;\n if (!resolved || !references) return new Map();\n\n return new Map(\n Object.entries(references).map(([name, resolver]) => [\n name,\n normalizeAccessReference(\n resolver({\n auth,\n collection: resolved.scope,\n params: resolved.params,\n pattern: resolved.name,\n }),\n ),\n ]),\n );\n}\n\nexport function normalizeAccessReference(reference: AccessReference): {\n collection: string;\n key: string | number;\n} {\n if (typeof reference !== \"string\") return reference;\n\n const normalized = reference.trim().replace(/^\\/+|\\/+$/g, \"\");\n const segments = normalized ? normalized.split(\"/\") : [];\n const key = segments.at(-1);\n if (!key || segments.length < 2) {\n throw new Error(`Invalid access reference path: ${reference}`);\n }\n\n return {\n collection: `/${segments.slice(0, -1).map(encodeURIComponent).join(\"/\")}/`,\n key: decodeURIComponent(key),\n };\n}\n\nfunction combinePredicates(\n left: ReadPredicate | undefined,\n right: ReadPredicate | undefined,\n): ReadPredicate | undefined {\n if (!left) return right;\n if (!right) return left;\n return { type: \"and\", predicates: [left, right] };\n}\n\nfunction writeAccessHandler(\n access: CollectionAccessConfig | undefined,\n type: OperationType,\n): CollectionAccessConfig[\"read\"] | undefined {\n if (!access) return undefined;\n return access[type] ?? access.write ?? access.read;\n}\n\nfunction writeAccessRow(update: Update, store: AccessStore): Record<string, unknown> | undefined {\n if (update.type === \"insert\") {\n return asRecord(update.value);\n }\n\n const existing = asRecord(update.previousValue) ?? store.read(update.collection, update.key);\n\n if (update.type === \"delete\") {\n return existing;\n }\n\n const next = asRecord(update.value);\n return existing && next ? { ...existing, ...next } : (next ?? existing);\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n","import { collectionScope, resolveCollection } from \"./collections\";\nimport type { CollectionConfigs } from \"./types\";\n\nexport function normalizeCollection(\n collection: string,\n collections: CollectionConfigs | undefined,\n): string {\n const configured = resolveCollection(collection, collections);\n\n if (configured) {\n return configured.scope;\n }\n\n if (collections && Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return collectionScope(collection);\n}\n","import type { Sql } from \"sql-template-tag\";\nimport { raw } from \"sql-template-tag\";\n\ntype SqlStorageValue = ArrayBuffer | string | number | null;\n\ninterface SqlStorageCursorLike<T extends Record<string, SqlStorageValue>> {\n toArray(): Array<T>;\n}\n\ninterface SqlStorageLike {\n exec<T extends Record<string, SqlStorageValue>>(\n query: string,\n ...bindings: Array<unknown>\n ): SqlStorageCursorLike<T>;\n}\n\nexport function execSql<T extends Record<string, SqlStorageValue>>(\n storage: SqlStorageLike,\n statement: Sql,\n): SqlStorageCursorLike<T> {\n return storage.exec<T>(statement.sql, ...statement.values);\n}\n\nexport function identifierSql(identifier: string): Sql {\n return raw(`\"${identifier.replaceAll(`\"`, `\"\"`)}\"`);\n}\n\nexport function rawSql(value: string): Sql {\n return raw(value);\n}\n","import type {\n CollectionConfigs,\n ReadFilter,\n ReadOrderBy,\n ReadPredicate,\n ReadQuery,\n ReadResult,\n SQLiteJsonStorageConfig,\n} from \"./types\";\nimport { resolveCollection } from \"./collections\";\nimport {\n ensureSQLiteJsonTables,\n sqliteJsonStorage,\n type SqlStorageLike,\n type SqlStorageValue,\n} from \"./storage\";\nimport sqlTag, { join, type Sql } from \"sql-template-tag\";\nimport { execSql, identifierSql, rawSql } from \"./sqlite-sql\";\n\nexport function readSQLiteJsonRows(\n sql: SqlStorageLike,\n query: ReadQuery,\n collections: CollectionConfigs = {},\n): ReadResult {\n ensureSQLiteJsonTables(sql, collections);\n\n const resolved = resolveCollection(query.collection, collections);\n if (!resolved) {\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${query.collection}`);\n }\n\n throw new Error(`Cannot read unconfigured collection: ${query.collection}`);\n }\n\n const storage = sqliteJsonStorage(resolved.collection.storage);\n if (!storage) {\n throw new Error(`Collection is not readable with SQLite JSON storage: ${query.collection}`);\n }\n\n const table = tableName(resolved.name, storage);\n const filters = query.filters ?? [];\n const predicate = query.predicate;\n const orderBy = query.orderBy ?? [];\n const limit = query.limit ?? 1000;\n const scope = { scope: resolved.scope };\n\n if (query.cursor) {\n const currentPredicate = combinePredicates(predicate, query.cursor.whereCurrent);\n const fromPredicate = combinePredicates(predicate, query.cursor.whereFrom);\n const currentRows = selectRows(sql, table, {\n filters,\n orderBy,\n ...scope,\n ...(currentPredicate ? { predicate: currentPredicate } : {}),\n });\n const fromRows = selectRows(sql, table, {\n filters,\n limit,\n orderBy,\n ...scope,\n ...(fromPredicate ? { predicate: fromPredicate } : {}),\n });\n\n return {\n rows: uniqueRows([...currentRows, ...fromRows]).map((row) => JSON.parse(row.value)),\n };\n }\n\n const rows = selectRows(sql, table, {\n filters,\n limit,\n offset: query.offset ?? 0,\n orderBy,\n ...scope,\n ...(predicate ? { predicate } : {}),\n });\n\n return {\n rows: rows.map((row) => JSON.parse(row.value)),\n };\n}\n\nexport function readSQLiteJsonRow(\n sql: SqlStorageLike,\n collection: string,\n key: string | number,\n collections: CollectionConfigs = {},\n): Record<string, unknown> | undefined {\n ensureSQLiteJsonTables(sql, collections);\n\n const resolved = resolveCollection(collection, collections);\n if (!resolved) {\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n throw new Error(`Cannot read unconfigured collection: ${collection}`);\n }\n\n if (resolved.collection.storage?.kind !== \"sqlite-json\") {\n throw new Error(`Collection is not readable with SQLite JSON storage: ${collection}`);\n }\n\n const table = tableName(resolved.name, resolved.collection.storage);\n const row = execSql<{ value: string }>(\n sql,\n sqlTag`\n SELECT value FROM ${identifierSql(table)}\n WHERE path = ${resolved.scope} AND key = ${String(key)}\n `,\n ).toArray()[0];\n\n return row ? (JSON.parse(row.value) as Record<string, unknown>) : undefined;\n}\n\ninterface SelectRowsOptions {\n filters: Array<ReadFilter>;\n limit?: number;\n offset?: number;\n orderBy: Array<ReadOrderBy>;\n scope: string;\n predicate?: ReadPredicate;\n}\n\nfunction selectRows(\n sql: SqlStorageLike,\n table: string,\n options: SelectRowsOptions,\n): Array<{ key: string; value: string }> {\n const where = [sqlTag`path = ${options.scope}`];\n\n where.push(...options.filters.map((filter) => filterSql(filter)));\n if (options.predicate) {\n where.push(predicateSql(options.predicate));\n }\n\n const order =\n options.orderBy.length > 0\n ? join(options.orderBy.map((item) => orderBySql(item)))\n : sqlTag`key`;\n\n return execSql<{ key: string; value: string }>(\n sql,\n sqlTag`\n SELECT key, value FROM ${identifierSql(table)}\n WHERE ${join(where, \" AND \")}\n ORDER BY ${order}\n LIMIT ${options.limit ?? 1000} OFFSET ${options.offset ?? 0}\n `,\n ).toArray();\n}\n\nfunction uniqueRows(\n rows: Array<{ key: string; value: string }>,\n): Array<{ key: string; value: string }> {\n const seen = new Set<string>();\n const unique: Array<{ key: string; value: string }> = [];\n for (const row of rows) {\n if (!seen.has(row.key)) {\n seen.add(row.key);\n unique.push(row);\n }\n }\n return unique;\n}\n\nfunction tableName(collectionName: string, storage: SQLiteJsonStorageConfig): string {\n return storage.tableName ?? collectionName;\n}\n\nfunction jsonPath(field: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(field)) {\n throw new Error(`Invalid JSON index field: ${field}`);\n }\n\n return `$.${field}`;\n}\n\nfunction orderBySql(orderBy: ReadOrderBy): Sql {\n const direction = orderBy.direction === \"desc\" ? \"DESC\" : \"ASC\";\n return sqlTag`json_extract(value, ${jsonPath(orderBy.field)}) ${directionSql(direction)}`;\n}\n\nfunction predicateSql(predicate: ReadPredicate): Sql {\n if (predicate.type === \"comparison\") {\n return filterSql(predicate);\n }\n\n const joiner = predicate.type === \"and\" ? \" AND \" : \" OR \";\n return sqlTag`(${join(\n predicate.predicates.map((child) => predicateSql(child)),\n joiner,\n )})`;\n}\n\nfunction combinePredicates(\n left: ReadPredicate | undefined,\n right: ReadPredicate | undefined,\n): ReadPredicate | undefined {\n if (!left) return right;\n if (!right) return left;\n return { type: \"and\", predicates: [left, right] };\n}\n\nfunction filterSql(filter: ReadFilter): Sql {\n const field = sqlTag`json_extract(value, ${jsonPath(filter.field)})`;\n\n if (filter.op === \"in\") {\n if (!Array.isArray(filter.value) || filter.value.length === 0) {\n throw new Error(\"The in filter requires a non-empty array value\");\n }\n\n return sqlTag`${field} IN (${join(filter.value.map(toSqlJsonValue))})`;\n }\n\n const value = toSqlJsonValue(filter.value);\n\n if (value === null) {\n if (filter.op === \"eq\") return sqlTag`${field} IS ${value}`;\n if (filter.op === \"ne\") return sqlTag`${field} IS NOT ${value}`;\n }\n\n switch (filter.op) {\n case \"eq\":\n return sqlTag`${field} = ${value}`;\n case \"ne\":\n return sqlTag`${field} != ${value}`;\n case \"gt\":\n return sqlTag`${field} > ${value}`;\n case \"gte\":\n return sqlTag`${field} >= ${value}`;\n case \"lt\":\n return sqlTag`${field} < ${value}`;\n case \"lte\":\n return sqlTag`${field} <= ${value}`;\n }\n}\n\nfunction directionSql(direction: \"ASC\" | \"DESC\"): Sql {\n return rawSql(direction);\n}\n\nfunction toSqlJsonValue(value: unknown): SqlStorageValue {\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value instanceof ArrayBuffer\n ) {\n return value;\n }\n\n throw new Error(`Unsupported SQLite JSON filter value: ${typeof value}`);\n}\n","import type {\n Batch,\n CollectionConfigs,\n CollectionStorageConfig,\n SQLiteJsonIndexConfig,\n SQLiteJsonStorageConfig,\n} from \"./types\";\nimport { collectionScope, resolveCollection } from \"./collections\";\nimport sqlTag, { join, type Sql } from \"sql-template-tag\";\nimport { execSql, identifierSql, rawSql } from \"./sqlite-sql\";\n\nexport { readSQLiteJsonRow, readSQLiteJsonRows } from \"./sqlite-json-read\";\n\nexport type SqlStorageValue = ArrayBuffer | string | number | null;\n\nexport interface SqlStorageCursorLike<T extends Record<string, SqlStorageValue>> {\n toArray(): Array<T>;\n}\n\nexport interface SqlStorageLike {\n exec<T extends Record<string, SqlStorageValue>>(\n query: string,\n ...bindings: Array<unknown>\n ): SqlStorageCursorLike<T>;\n}\n\nexport interface SQLiteJsonTableOptions {\n tableName?: string;\n indexes?: Array<Array<string> | SQLiteJsonIndexConfig>;\n}\n\nexport function sqliteJsonTable(options: SQLiteJsonTableOptions = {}): SQLiteJsonStorageConfig {\n return {\n kind: \"sqlite-json\",\n ...(options.tableName ? { tableName: options.tableName } : {}),\n indexes: (options.indexes ?? []).map((index) =>\n Array.isArray(index) ? { fields: index } : index,\n ),\n };\n}\n\nexport function ensureSQLiteJsonTables(\n sql: SqlStorageLike,\n collections: CollectionConfigs = {},\n): void {\n for (const [collectionName, collection] of Object.entries(collections)) {\n const storage = sqliteJsonStorage(collection.storage);\n if (!storage) {\n continue;\n }\n\n const table = tableName(collectionName, storage);\n const result = execSql(\n sql,\n sqlTag`\n CREATE TABLE IF NOT EXISTS ${identifierSql(table)} (\n key TEXT NOT NULL,\n path TEXT NOT NULL,\n value TEXT NOT NULL,\n version INTEGER NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (path, key)\n )\n `,\n );\n\n for (const index of storage.indexes) {\n execSql(sql, createIndexSql(table, index));\n }\n\n if ((result as unknown as { rowsWritten: number }).rowsWritten > 0) {\n if (collection.initialData) {\n for (const data of collection.initialData) {\n const key = String(data.id);\n const path = collectionScope(collectionName);\n const value = JSON.stringify(data);\n const version = 1;\n const createdAt = new Date().toISOString();\n const updatedAt = createdAt;\n execSql(\n sql,\n sqlTag`\n INSERT INTO ${identifierSql(table)} (key, path, value, version, created_at, updated_at)\n VALUES (${key}, ${path}, ${value}, ${version}, ${createdAt}, ${updatedAt})\n `,\n );\n }\n }\n }\n }\n}\n\nexport function applySQLiteJsonBatch(\n sql: SqlStorageLike,\n batch: Batch,\n collections: CollectionConfigs = {},\n): void {\n ensureSQLiteJsonTables(sql, collections);\n\n for (const update of batch.updates) {\n const resolved = resolveCollection(update.collection, collections);\n const storage = resolved ? sqliteJsonStorage(resolved.collection.storage) : undefined;\n\n if (!resolved || !storage) {\n continue;\n }\n\n const table = tableName(resolved.name, storage);\n const key = String(update.key);\n const scope = resolved.scope;\n const updatedAt = new Date(update.createdAt).toISOString();\n\n if (update.type === \"delete\") {\n execSql(sql, sqlTag`DELETE FROM ${identifierSql(table)} WHERE ${whereKeySql(scope, key)}`);\n continue;\n }\n\n if (update.type === \"insert\") {\n execSql(\n sql,\n sqlTag`\n INSERT INTO ${identifierSql(table)} (key, path, value, version, created_at, updated_at)\n VALUES (${key}, ${scope}, ${stringifyRow(update.value)}, 1, ${updatedAt}, ${updatedAt})\n ON CONFLICT(path, key) DO UPDATE SET\n path = excluded.path,\n value = excluded.value,\n version = ${identifierSql(table)}.version + 1,\n updated_at = excluded.updated_at\n `,\n );\n continue;\n }\n\n const existing = execSql<{ value: string }>(\n sql,\n sqlTag`SELECT value FROM ${identifierSql(table)} WHERE ${whereKeySql(scope, key)}`,\n ).toArray()[0];\n\n if (!existing) {\n throw new Error(`Cannot update missing ${update.collection} row: ${key}`);\n }\n\n const merged = mergeRows(JSON.parse(existing.value), update.value);\n execSql(\n sql,\n sqlTag`\n UPDATE ${identifierSql(table)}\n SET value = ${JSON.stringify(merged)}, version = version + 1, updated_at = ${updatedAt}\n WHERE ${whereKeySql(scope, key)}\n `,\n );\n }\n}\n\nexport function sqliteJsonStorage(\n storage: CollectionStorageConfig | undefined,\n): SQLiteJsonStorageConfig | undefined {\n if (!storage) {\n return sqliteJsonTable();\n }\n\n return storage.kind === \"sqlite-json\" ? storage : undefined;\n}\n\nfunction whereKeySql(scope: string, key: string): Sql {\n return sqlTag`path = ${scope} AND key = ${key}`;\n}\n\nfunction tableName(collectionName: string, storage: SQLiteJsonStorageConfig): string {\n return storage.tableName ?? collectionName;\n}\n\nfunction createIndexSql(table: string, index: SQLiteJsonIndexConfig): Sql {\n const name = index.name ?? `${table}_${index.fields.join(\"_\")}_idx`;\n const fields = index.fields.map((field) => rawSql(`json_extract(value, '$.${jsonPath(field)}')`));\n\n return sqlTag`\n CREATE INDEX IF NOT EXISTS ${identifierSql(name)}\n ON ${identifierSql(table)} (${join(fields)})\n `;\n}\n\nfunction jsonPath(field: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(field)) {\n throw new Error(`Invalid JSON index field: ${field}`);\n }\n\n return field;\n}\n\nfunction stringifyRow(value: unknown): string {\n if (!isRecord(value)) {\n throw new Error(\"SQLite JSON storage requires object row values\");\n }\n\n return JSON.stringify(value);\n}\n\nfunction mergeRows(existing: unknown, changes: unknown): Record<string, unknown> {\n if (!isRecord(existing) || !isRecord(changes)) {\n throw new Error(\"SQLite JSON storage can only merge object update values\");\n }\n\n return {\n ...existing,\n ...changes,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import type { z } from \"zod\";\nimport type {\n ApiHandler,\n CollectionAccessConfig,\n CollectionApiHandlers,\n CollectionConfig,\n CollectionConfigs,\n CollectionStorageConfig,\n SQLiteJsonIndexConfig,\n} from \"./types\";\nimport { sqliteJsonTable } from \"./storage\";\n\ntype BuilderState = {\n path?: string;\n schema?: z.ZodTypeAny;\n access?: CollectionAccessConfig<any>;\n storage?: CollectionStorageConfig;\n indexes?: Array<SQLiteJsonIndexConfig>;\n initialData?: Array<Record<string, unknown>>;\n api?: CollectionApiHandlers;\n children?: Record<string, CollectionBuilder<any>>;\n};\n\ntype InitialCollectionBuilder = Pick<CollectionBuilder<Record<string, unknown>>, \"name\" | \"path\">;\ntype ConfiguredCollectionBuilder<T extends object> = Omit<\n CollectionBuilder<T>,\n \"name\" | \"path\" | \"schema\"\n>;\ntype IndexField<T extends object> = string extends keyof T ? string : Extract<keyof T, string>;\ntype BuilderIndexConfig<T extends object> = Omit<SQLiteJsonIndexConfig, \"fields\"> & {\n fields: Array<IndexField<T>>;\n};\n\nexport function collectionConfigsBuilder(): CollectionConfigsBuilder {\n return new CollectionConfigsBuilder({});\n}\n\nexport function collectionBuilder(): InitialCollectionBuilder {\n return new CollectionBuilder({});\n}\n\nexport const Collections = {\n builder: collectionConfigsBuilder,\n collection: collectionBuilder,\n};\n\nexport class CollectionConfigsBuilder {\n private readonly collections: Readonly<CollectionConfigs>;\n\n constructor(collections: CollectionConfigs) {\n this.collections = Object.freeze({ ...collections });\n }\n\n collection<TBuilder extends CollectionBuilder<any>>(\n name: string,\n configure: (\n builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\" | \"path\">,\n ) => TBuilder,\n ): CollectionConfigsBuilder {\n const builder = configure(new CollectionBuilder({ path: rootPathForName(name) }));\n return new CollectionConfigsBuilder({\n ...this.collections,\n ...builder.entries(),\n });\n }\n\n path<TBuilder extends CollectionBuilder<any>>(\n path: string,\n configure: (builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\">) => TBuilder,\n ): CollectionConfigsBuilder {\n const builder = configure(new CollectionBuilder({ path }));\n return new CollectionConfigsBuilder({\n ...this.collections,\n ...builder.entries(),\n });\n }\n\n build(): CollectionConfigs {\n return { ...this.collections };\n }\n}\n\nexport class CollectionBuilder<T extends object = Record<string, unknown>> {\n private readonly state: Readonly<BuilderState>;\n\n constructor(state: BuilderState) {\n this.state = freezeState(state);\n }\n\n name(name: string): Pick<CollectionBuilder<T>, \"schema\" | \"path\"> {\n return this.next({ path: rootPathForName(name) });\n }\n\n path(path: string): Pick<CollectionBuilder<T>, \"schema\"> {\n return this.next({ path });\n }\n\n schema<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n ): ConfiguredCollectionBuilder<z.output<TSchema> & object> {\n return this.next({ schema }) as unknown as ConfiguredCollectionBuilder<\n z.output<TSchema> & object\n >;\n }\n\n access(access: CollectionAccessConfig<T>): CollectionBuilder<T> {\n return this.next({ access });\n }\n\n storage(storage: CollectionStorageConfig): CollectionBuilder<T> {\n return this.next({ storage });\n }\n\n index(field: IndexField<T>, ...fields: Array<IndexField<T>>): CollectionBuilder<T>;\n index(fields: Array<IndexField<T>> | BuilderIndexConfig<T>): CollectionBuilder<T>;\n index(\n fieldOrIndex: IndexField<T> | Array<IndexField<T>> | BuilderIndexConfig<T>,\n ...fields: Array<IndexField<T>>\n ): CollectionBuilder<T> {\n return this.next({\n indexes: [...(this.state.indexes ?? []), normalizeIndex(fieldOrIndex, fields)],\n });\n }\n\n initialData<TData extends T>(...initialData: Array<TData>): CollectionBuilder<T> {\n return this.next({ initialData: initialData as Array<Record<string, unknown>> });\n }\n\n api<TName extends string, TSchema extends z.ZodTypeAny, TResult = unknown>(\n name: TName,\n input: TSchema,\n handler: ApiHandler<TResult, z.output<TSchema>>,\n ): CollectionBuilder<T> {\n return this.next({\n api: {\n ...this.state.api,\n [name]: freezeApiDefinition({ input, handler }),\n },\n });\n }\n\n child<TBuilder extends CollectionBuilder<any>>(\n name: string,\n configure: (\n builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\" | \"path\">,\n ) => TBuilder,\n ): CollectionBuilder<T> {\n const path = this.requirePath(\"CollectionBuilder.child\");\n const builder = configure(\n new CollectionBuilder({\n path: childPathForName(path, parentIdParamForName(path), name),\n }),\n );\n\n return this.next({\n children: {\n ...this.state.children,\n [name]: builder,\n },\n });\n }\n\n buildConfig(): CollectionConfig<T> {\n if (!this.state.schema) {\n throw new Error(\"CollectionBuilder requires a schema\");\n }\n\n const config: CollectionConfig<T> = {\n schema: this.state.schema,\n };\n\n if (this.state.access) config.access = this.state.access as CollectionAccessConfig<T>;\n config.storage = storageWithIndexes(this.state.storage, this.state.indexes ?? []);\n if (this.state.initialData) config.initialData = [...this.state.initialData];\n if (this.state.api) config.api = { ...this.state.api };\n\n return config;\n }\n\n build(): CollectionConfigs {\n return this.entries();\n }\n\n entries(): CollectionConfigs {\n const path = this.requirePath(\"CollectionBuilder.build\");\n const entries: CollectionConfigs = {\n [path]: this.buildConfig() as CollectionConfig,\n };\n\n for (const child of Object.values(this.state.children ?? {})) {\n Object.assign(entries, child.entries());\n }\n\n return entries;\n }\n\n private next(updates: Partial<BuilderState>): CollectionBuilder<T> {\n return new CollectionBuilder<T>({\n ...this.state,\n ...updates,\n });\n }\n\n private requirePath(caller: string): string {\n if (!this.state.path) {\n throw new Error(`${caller} requires a name or path`);\n }\n\n return this.state.path;\n }\n}\n\nfunction freezeState(state: BuilderState): Readonly<BuilderState> {\n const next: BuilderState = {};\n\n if (state.path) next.path = state.path;\n if (state.schema) next.schema = state.schema;\n if (state.access) next.access = state.access;\n if (state.storage) next.storage = state.storage;\n if (state.indexes) next.indexes = state.indexes.map((index) => ({ ...index }));\n if (state.initialData) next.initialData = [...state.initialData];\n if (state.api) next.api = Object.freeze({ ...state.api });\n if (state.children) next.children = Object.freeze({ ...state.children });\n\n return Object.freeze(next);\n}\n\nfunction freezeApiDefinition(\n definition: CollectionApiHandlers[string],\n): CollectionApiHandlers[string] {\n return Object.freeze({ ...definition });\n}\n\nfunction normalizeIndex(\n fieldOrIndex: string | Array<string> | SQLiteJsonIndexConfig,\n fields: Array<string>,\n): SQLiteJsonIndexConfig {\n if (typeof fieldOrIndex === \"string\") {\n return { fields: [fieldOrIndex, ...fields] };\n }\n\n return Array.isArray(fieldOrIndex) ? { fields: fieldOrIndex } : fieldOrIndex;\n}\n\nfunction storageWithIndexes(\n storage: CollectionStorageConfig | undefined,\n indexes: Array<SQLiteJsonIndexConfig>,\n): CollectionStorageConfig {\n const current = storage ?? sqliteJsonTable();\n\n if (current.kind !== \"sqlite-json\") {\n return current;\n }\n\n return {\n ...current,\n indexes: [...current.indexes, ...indexes],\n };\n}\n\nfunction rootPathForName(name: string): string {\n return `/${encodeURIComponent(name)}/`;\n}\n\nfunction childPathForName(parentPath: string, parentParam: string, name: string): string {\n return `${parentPath.replace(/\\/+$/g, \"\")}/{${parentParam}}/${encodeURIComponent(name)}/`;\n}\n\nfunction parentIdParamForName(parentPath: string): string {\n const segment = parentPath\n .trim()\n .replace(/^\\/+|\\/+$/g, \"\")\n .split(\"/\")\n .filter((part) => !part.startsWith(\"{\") && !part.startsWith(\":\"))\n .at(-1);\n\n return `${singularize(segment ?? \"parent\")}Id`;\n}\n\nfunction singularize(value: string): string {\n return value.endsWith(\"s\") ? value.slice(0, -1) : value;\n}\n","import type {\n CollectionAtPath,\n CollectionDefinition,\n CollectionDefinitions,\n CollectionPath,\n CollectionSet,\n} from \"@lsync/definitions\";\nimport { authorizeApiCall } from \"./access\";\nimport { collectionBuilder } from \"./collection-builder\";\nimport { defaultCollectionApiPath } from \"./collections\";\nimport type { CollectionShardOptions } from \"./durable-object-types\";\nimport { z } from \"zod\";\nimport type {\n AccessReferenceResolver,\n ApiAccessHandler,\n ApiHandler,\n CollectionAccessConfig,\n CollectionConfigs,\n ReadAccessHandler,\n} from \"./types\";\n\nexport function collectionShardOptionsFrom<TCollections extends CollectionDefinitions>(\n definitions: CollectionSet<TCollections>,\n): CollectionShardDefinitionBuilder<TCollections> {\n return new CollectionShardDefinitionBuilder(definitions.collections, {});\n}\n\nexport class CollectionShardDefinitionBuilder<TCollections extends CollectionDefinitions> {\n constructor(\n private readonly definitions: TCollections,\n private readonly overrides: Record<string, ServerCollectionOverride>,\n ) {}\n\n collection<TPath extends CollectionPath<TCollections>>(\n path: TPath,\n configure: (\n collection: ServerCollectionBuilder<CollectionAtPath<TCollections, TPath>>,\n ) => ServerCollectionBuilder<CollectionAtPath<TCollections, TPath>>,\n ): CollectionShardDefinitionBuilder<TCollections> {\n const override = configure(new ServerCollectionBuilder({})).toOverride();\n return new CollectionShardDefinitionBuilder(this.definitions, {\n ...this.overrides,\n [path]: override,\n });\n }\n\n build(): CollectionShardOptions {\n const collections = {} as CollectionConfigs;\n\n for (const [name, definition] of Object.entries(this.definitions)) {\n addDefinition(collections, definition, name, this.overrides);\n }\n\n return { collections };\n }\n}\n\nexport class ServerCollectionBuilder<TDefinition> {\n constructor(private readonly override: ServerCollectionOverride) {}\n\n index(...fields: Array<string>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n indexes: [...(this.override.indexes ?? []), fields],\n });\n }\n\n initialData(data: Array<Record<string, unknown>>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({ ...this.override, initialData: data });\n }\n\n reference(name: string, resolver: AccessReferenceResolver): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n references: {\n ...this.override.references,\n [name]: resolver,\n },\n });\n }\n\n access(\n kind: ServerWriteAccessKind,\n handler: ReadAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition>;\n access(\n kind: `api.${string}`,\n handler: ApiAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition>;\n access(\n kind: ServerWriteAccessKind | `api.${string}`,\n handler: ReadAccessHandler<any> | ApiAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n access: {\n ...this.override.access,\n [kind]: handler,\n },\n });\n }\n\n api(name: string, handler: ApiHandler<any, any>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n api: {\n ...this.override.api,\n [name]: handler,\n },\n });\n }\n\n toOverride(): ServerCollectionOverride {\n return this.override;\n }\n}\n\ntype ServerWriteAccessKind = \"read\" | \"write\" | \"insert\" | \"update\" | \"delete\";\n\ninterface ServerCollectionOverride {\n indexes?: Array<Array<string>>;\n initialData?: Array<Record<string, unknown>>;\n references?: Record<string, AccessReferenceResolver>;\n access?: Record<string, ReadAccessHandler<any> | ApiAccessHandler<any>>;\n api?: Record<string, ApiHandler<any, any>>;\n}\n\nfunction addDefinition(\n collections: CollectionConfigs,\n definition: CollectionDefinition,\n dotPath: string,\n overrides: Record<string, ServerCollectionOverride>,\n): void {\n const override = overrides[dotPath] ?? {};\n let builder = collectionBuilder()\n .path(definition.path)\n .schema(definition.schema as z.ZodTypeAny) as any;\n\n for (const fields of override.indexes ?? []) {\n builder = builder.index(fields);\n }\n\n if (override.initialData) {\n builder = builder.initialData(...override.initialData);\n }\n\n const access = accessConfig(override);\n if (access) {\n builder = builder.access(access);\n }\n\n for (const [name, handler] of Object.entries(override.api ?? {})) {\n const apiDefinition = definition.api[name];\n const apiAccess = override.access?.[`api.${name}`] as ApiAccessHandler | undefined;\n const apiPath = apiDefinition?.path ?? defaultCollectionApiPath(definition.path, name);\n const input = (apiDefinition?.input ?? z.undefined()) as z.ZodTypeAny;\n\n builder = builder.api(name, input, async (args: any) => {\n authorizeApiCall(apiAccess, apiPath, args.input, args.auth);\n return handler(args);\n });\n }\n\n Object.assign(collections, builder.build());\n\n for (const [name, child] of Object.entries(definition.children)) {\n addDefinition(collections, child, `${dotPath}.${name}`, overrides);\n }\n}\n\nfunction accessConfig(override: ServerCollectionOverride): CollectionAccessConfig | undefined {\n const access = override.access ?? {};\n const apiAccess = Object.fromEntries(\n Object.entries(access)\n .filter(([kind]) => kind.startsWith(\"api.\"))\n .map(([kind, handler]) => [kind.slice(\"api.\".length), handler]),\n );\n const config: CollectionAccessConfig = {};\n if (override.references) config.references = override.references;\n if (access.read) config.read = access.read as ReadAccessHandler;\n if (access.write) config.write = access.write as ReadAccessHandler;\n if (access.insert) config.insert = access.insert as ReadAccessHandler;\n if (access.update) config.update = access.update as ReadAccessHandler;\n if (access.delete) config.delete = access.delete as ReadAccessHandler;\n if (Object.keys(apiAccess).length > 0) {\n config.api = apiAccess as Record<string, ApiAccessHandler<any>>;\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n","import { parseClientRpcRequest } from \"@lsync/transport\";\nimport { router } from \"./router\";\n\nexport function callRouter(\n caller: ReturnType<typeof router.createCaller>,\n request: ReturnType<typeof parseClientRpcRequest>,\n): unknown {\n if (request.method === \"query\" && request.params.path === \"read\") {\n return caller.read(request.params.input.json);\n }\n\n if (request.method === \"query\" && request.params.path === \"changes\") {\n return caller.changes(request.params.input.json);\n }\n\n if (request.method === \"subscribe\") {\n return caller.subscribe(request.params.input.json);\n }\n\n if (request.method === \"unsubscribe\") {\n return caller.unsubscribe(request.params.input.json);\n }\n\n if (request.method !== \"mutation\") {\n throw new Error(\"Unsupported operation\");\n }\n\n if (request.params.path === \"push\") {\n return caller.push(request.params.input.json);\n }\n\n if (request.params.path === \"api\") {\n return caller.api(request.params.input.json);\n }\n\n throw new Error(\"Unsupported operation\");\n}\n","import type { SqlStorageLike } from \"./storage\";\n\nconst COLLECTION_WATERMARKS_TABLE = \"_lsync_collection_watermarks\";\n\nexport function ensureCollectionWatermarkTable(sql: SqlStorageLike): void {\n sql.exec(`\n CREATE TABLE IF NOT EXISTS ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)} (\n scope TEXT PRIMARY KEY,\n collection TEXT NOT NULL,\n latest_sequence INTEGER NOT NULL\n )\n `);\n}\n\nexport function recordCollectionWatermark(\n sql: SqlStorageLike,\n collection: string,\n scope: string,\n sequence: number,\n): void {\n sql.exec(\n `\n INSERT INTO ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)}\n (scope, collection, latest_sequence)\n VALUES (?, ?, ?)\n ON CONFLICT(scope) DO UPDATE SET\n collection = excluded.collection,\n latest_sequence = excluded.latest_sequence\n `,\n scope,\n collection,\n sequence,\n );\n}\n\nexport function readCollectionWatermark(sql: SqlStorageLike, scope: string): number {\n const row = sql\n .exec<{ latest_sequence: number }>(\n `\n SELECT latest_sequence FROM ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)}\n WHERE scope = ?\n `,\n scope,\n )\n .toArray()[0];\n\n return row?.latest_sequence ?? 0;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll(`\"`, `\"\"`)}\"`;\n}\n","import type {\n Batch,\n CollectionConfigs,\n SequencedUpdate,\n SyncChangesQuery,\n SyncChangesResult,\n} from \"./types\";\nimport { collectionScope, resolveCollection } from \"./collections\";\nimport {\n ensureCollectionWatermarkTable,\n readCollectionWatermark,\n recordCollectionWatermark,\n} from \"./history-watermarks\";\nimport { applySQLiteJsonBatch, ensureSQLiteJsonTables, type SqlStorageLike } from \"./storage\";\n\nconst CHANGES_TABLE = \"_lsync_changes\";\n\nexport interface HistoryOptions {\n maxChanges?: number;\n}\n\nexport interface SequencedBatch {\n updates: Array<SequencedUpdate>;\n watermark: number;\n}\n\nexport function persistSQLiteJsonBatchWithHistory(\n sql: SqlStorageLike,\n batch: Batch,\n collections: CollectionConfigs = {},\n options: HistoryOptions = {},\n): SequencedBatch {\n ensureSQLiteJsonTables(sql, collections);\n ensureChangesTable(sql);\n\n applySQLiteJsonBatch(sql, batch, collections);\n\n const updates = batch.updates.map((update) => appendChange(sql, update, collections));\n const watermark = updates.at(-1)?.sequence ?? readWatermark(sql);\n pruneChanges(sql, watermark, options.maxChanges ?? 10000);\n\n return { updates, watermark };\n}\n\nexport function readSQLiteJsonChanges(\n sql: SqlStorageLike,\n query: SyncChangesQuery,\n collections: CollectionConfigs = {},\n): SyncChangesResult {\n ensureChangesTable(sql);\n\n const requested = Object.entries(query.collections).map(([collection, sequence]) => ({\n collection,\n sequence,\n scope: scopeForCollection(collection, collections),\n }));\n const watermark = readWatermark(sql);\n const staleCollections = requested.flatMap((item) =>\n isCursorStale(sql, item.scope, item.sequence) ? [item.collection] : [],\n );\n\n if (staleCollections.length > 0) {\n return {\n type: \"resyncRequired\",\n collections: staleCollections,\n watermark,\n };\n }\n\n if (requested.length === 0) {\n return {\n type: \"changes\",\n updates: [],\n watermark,\n hasMore: false,\n };\n }\n\n const limit = query.limit ?? 1000;\n const rows = selectChanges(sql, requested, limit + 1);\n const page = rows.slice(0, limit);\n\n return {\n type: \"changes\",\n updates: page.map(rowToUpdate),\n watermark,\n hasMore: rows.length > limit,\n };\n}\n\nfunction ensureChangesTable(sql: SqlStorageLike): void {\n sql.exec(`\n CREATE TABLE IF NOT EXISTS ${quoteIdentifier(CHANGES_TABLE)} (\n sequence INTEGER PRIMARY KEY AUTOINCREMENT,\n update_id TEXT NOT NULL,\n collection TEXT NOT NULL,\n scope TEXT NOT NULL,\n \"key\" TEXT NOT NULL,\n type TEXT NOT NULL,\n value TEXT,\n previous_value TEXT,\n client_id TEXT,\n client_created_at INTEGER NOT NULL,\n server_created_at TEXT NOT NULL\n )\n `);\n sql.exec(`\n CREATE INDEX IF NOT EXISTS ${quoteIdentifier(`${CHANGES_TABLE}_scope_sequence_idx`)}\n ON ${quoteIdentifier(CHANGES_TABLE)} (scope, sequence)\n `);\n ensureCollectionWatermarkTable(sql);\n}\n\nfunction appendChange(\n sql: SqlStorageLike,\n update: Batch[\"updates\"][number],\n collections: CollectionConfigs,\n): SequencedUpdate {\n const serverCreatedAt = new Date().toISOString();\n const scope = scopeForCollection(update.collection, collections);\n const row = sql\n .exec<{ sequence: number }>(\n `\n INSERT INTO ${quoteIdentifier(CHANGES_TABLE)}\n (update_id, collection, scope, \"key\", type, value, previous_value, client_id,\n client_created_at, server_created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING sequence\n `,\n update.id,\n update.collection,\n scope,\n JSON.stringify(update.key),\n update.type,\n update.value === undefined ? null : JSON.stringify(update.value),\n update.previousValue === undefined ? null : JSON.stringify(update.previousValue),\n update.clientId ?? null,\n update.createdAt,\n serverCreatedAt,\n )\n .toArray()[0];\n\n if (!row) {\n throw new Error(\"Unable to append sync history row\");\n }\n\n recordCollectionWatermark(sql, update.collection, scope, row.sequence);\n\n return {\n ...update,\n sequence: row.sequence,\n serverCreatedAt,\n };\n}\n\nfunction selectChanges(\n sql: SqlStorageLike,\n requested: Array<{ scope: string; sequence: number }>,\n limit: number,\n): Array<ChangeRow> {\n const bindings = requested.flatMap((item) => [item.scope, item.sequence]);\n bindings.push(limit);\n\n return sql\n .exec<ChangeRow>(\n `\n SELECT sequence, update_id, collection, \"key\", type, value, previous_value, client_id,\n client_created_at, server_created_at\n FROM ${quoteIdentifier(CHANGES_TABLE)}\n WHERE ${requested.map(() => \"(scope = ? AND sequence > ?)\").join(\" OR \")}\n ORDER BY sequence\n LIMIT ?\n `,\n ...bindings,\n )\n .toArray();\n}\n\nfunction rowToUpdate(row: ChangeRow): SequencedUpdate {\n const update: SequencedUpdate = {\n id: row.update_id,\n collection: row.collection,\n key: JSON.parse(row.key) as string | number,\n type: row.type,\n createdAt: row.client_created_at,\n sequence: row.sequence,\n serverCreatedAt: row.server_created_at,\n };\n\n if (row.value !== null) {\n update.value = JSON.parse(row.value);\n }\n\n if (row.previous_value !== null) {\n update.previousValue = JSON.parse(row.previous_value);\n }\n\n if (row.client_id !== null) {\n update.clientId = row.client_id;\n }\n\n return update;\n}\n\nfunction isCursorStale(sql: SqlStorageLike, scope: string, sequence: number): boolean {\n const latest = readCollectionWatermark(sql, scope);\n if (latest === 0) {\n return false;\n }\n\n const row = sql\n .exec<{ sequence: number | null }>(\n `SELECT MIN(sequence) as sequence FROM ${quoteIdentifier(CHANGES_TABLE)} WHERE scope = ?`,\n scope,\n )\n .toArray()[0];\n const oldest = row?.sequence;\n\n if (oldest === null || oldest === undefined) {\n return sequence < latest;\n }\n\n return sequence < oldest - 1;\n}\n\nfunction readWatermark(sql: SqlStorageLike): number {\n const row = sql\n .exec<{ watermark: number }>(\n `SELECT COALESCE(MAX(sequence), 0) as watermark FROM ${quoteIdentifier(CHANGES_TABLE)}`,\n )\n .toArray()[0];\n\n return row?.watermark ?? 0;\n}\n\nfunction pruneChanges(sql: SqlStorageLike, watermark: number, maxChanges: number): void {\n if (!Number.isFinite(maxChanges) || maxChanges < 0) {\n return;\n }\n\n sql.exec(\n `DELETE FROM ${quoteIdentifier(CHANGES_TABLE)} WHERE sequence <= ?`,\n watermark - maxChanges,\n );\n}\n\nfunction scopeForCollection(collection: string, collections: CollectionConfigs): string {\n const resolved = resolveCollection(collection, collections);\n if (resolved) {\n return resolved.scope;\n }\n\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return collectionScope(collection);\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll(`\"`, `\"\"`)}\"`;\n}\n\ninterface ChangeRow extends Record<string, string | number | null> {\n sequence: number;\n update_id: string;\n collection: string;\n key: string;\n type: SequencedUpdate[\"type\"];\n value: string | null;\n previous_value: string | null;\n client_id: string | null;\n client_created_at: number;\n server_created_at: string;\n}\n","import { sendServerMessage, type RpcId } from \"@lsync/transport\";\n\nexport function sendRpcResult(ws: WebSocket, id: RpcId, result: unknown): void {\n sendServerMessage(ws, {\n id,\n result: {\n type: \"data\",\n data: {\n json: result,\n },\n },\n });\n}\n\nexport function sendRpcError(ws: WebSocket, id: RpcId, error: unknown): void {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n sendServerMessage(ws, {\n id,\n error: {\n message,\n },\n });\n}\n","import {\n type AccessAuth,\n type CollectionSubscriptionResult,\n type WebSocketAttachment,\n webSocketAttachmentSchema,\n} from \"./types\";\n\nexport function webSocketAttachment(ws: WebSocket): WebSocketAttachment | undefined {\n const result = webSocketAttachmentSchema.safeParse(ws.deserializeAttachment());\n return result.success ? result.data : undefined;\n}\n\nexport function webSocketAuth(ws: WebSocket): AccessAuth {\n const attachment = webSocketAttachment(ws);\n if (!attachment) return {};\n\n return {\n clientId: attachment.clientId,\n ...attachment.auth,\n };\n}\n\nexport function updateSocketSubscriptions(\n ws: WebSocket,\n collection: string,\n normalize: (collection: string) => string,\n update: (subscriptions: Set<string>, collection: string) => void,\n): CollectionSubscriptionResult {\n const attachment = webSocketAttachment(ws);\n if (!attachment) {\n throw new Error(\"Missing WebSocket attachment\");\n }\n\n const normalized = normalize(collection);\n const subscriptions = new Set(attachment.subscriptions);\n update(subscriptions, normalized);\n const next = [...subscriptions];\n ws.serializeAttachment({\n ...attachment,\n subscriptions: next,\n } satisfies WebSocketAttachment);\n\n return {\n collection: normalized,\n subscriptions: next,\n };\n}\n","import { collectionScope } from \"./collections\";\nimport type { Batch } from \"./types\";\nimport type { ReferenceDependency } from \"./access-expression\";\n\nexport function invalidatesDependency(\n update: Batch[\"updates\"][number],\n dependencies: Array<ReferenceDependency>,\n): boolean {\n return dependencies.some((dependency) => {\n if (collectionScope(update.collection) !== collectionScope(dependency.collection)) return false;\n if (String(update.key) !== String(dependency.key)) return false;\n return fieldChanged(update.previousValue, update.value, dependency.field);\n });\n}\n\nfunction fieldChanged(previous: unknown, next: unknown, field: string): boolean {\n if (!previous || !next) return true;\n return valueAtPath(previous, field) !== valueAtPath(next, field);\n}\n\nfunction valueAtPath(value: unknown, field: string): unknown {\n return field.split(\".\").reduce<unknown>((current, segment) => {\n if (typeof current !== \"object\" || current === null) return undefined;\n return (current as Record<string, unknown>)[segment];\n }, value);\n}\n","import { readAccessDecision, type AccessStore } from \"./access\";\nimport { invalidatesDependency } from \"./access-invalidation\";\nimport type { AccessAuth, Batch, CollectionConfigs, CollectionInvalidation } from \"./types\";\n\nexport function subscribedInvalidations(\n subscriptions: Array<string>,\n batch: Batch,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): Array<CollectionInvalidation> {\n const invalidations = new Set<string>();\n for (const collection of subscriptions) {\n const decision = readAccessDecision(collection, collections, auth, store);\n if (decision.dependencies.length === 0) continue;\n\n if (batch.updates.some((update) => invalidatesDependency(update, decision.dependencies))) {\n invalidations.add(collection);\n }\n }\n\n return [...invalidations].map((collection) => ({ collection }));\n}\n","import { z } from \"zod\";\nimport { resolveCollection } from \"./collections\";\nimport type { Batch, CollectionConfigs } from \"./types\";\n\nexport function validateBatch(batch: Batch, collections?: CollectionConfigs): void {\n for (const update of batch.updates) {\n const schema = schemaFor(update.collection, collections);\n\n if (!schema || update.type === \"delete\") {\n continue;\n }\n\n if (update.type === \"update\" && schema instanceof z.ZodObject) {\n schema.partial().parse(update.value);\n continue;\n }\n\n schema.parse(update.value);\n }\n}\n\nfunction schemaFor(collection: string, collections?: CollectionConfigs): z.ZodTypeAny | undefined {\n const configured = resolveCollection(collection, collections);\n\n if (!configured) {\n if (collections && Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return undefined;\n }\n\n return configured.collection.schema;\n}\n","import { parseClientRpcRequest, readRpcId, sendServerMessage } from \"@lsync/transport\";\nimport {\n authorizeReadQuery,\n authorizeWriteBatch,\n visibleUpdateForAuth,\n type AccessStore,\n} from \"./access\";\nimport { normalizeCollection } from \"./collection-normalize\";\nimport { collectionApiHandlers } from \"./collections\";\nimport { collectionShardOptionsFrom } from \"./definition-builder\";\nimport { callRouter } from \"./durable-object-rpc\";\nimport type { CollectionShardOptions, Env } from \"./durable-object-types\";\nimport { persistSQLiteJsonBatchWithHistory, readSQLiteJsonChanges } from \"./history\";\nimport { sendRpcError, sendRpcResult } from \"./messages\";\nimport { router } from \"./router\";\nimport { updateSocketSubscriptions, webSocketAttachment, webSocketAuth } from \"./socket-attachment\";\nimport { readSQLiteJsonRow, readSQLiteJsonRows } from \"./storage\";\nimport { subscribedInvalidations } from \"./subscription-invalidation\";\nimport {\n type AccessAuth,\n type ApiCall,\n type ApiHandler,\n type ApiHandlerArgs,\n type Batch,\n type Broadcast,\n type CollectionSubscription,\n type CollectionSubscriptionResult,\n type PushResult,\n type ReadQuery,\n type ReadResult,\n type SequencedBatch,\n type SyncChangesQuery,\n type SyncChangesResult,\n type WebSocketAttachment,\n} from \"./types\";\nimport { validateBatch } from \"./validation\";\n\nexport type { CollectionShardOptions, Env } from \"./durable-object-types\";\n\nexport class CollectionShardDurableObject implements DurableObject {\n static from = collectionShardOptionsFrom;\n\n private readonly apiHandlers: Record<string, ApiHandler>;\n\n constructor(\n private readonly state: DurableObjectState,\n private readonly env: Env,\n private readonly options: CollectionShardOptions = {},\n ) {\n this.apiHandlers = collectionApiHandlers(options.collections);\n }\n\n async fetch(request: Request): Promise<Response> {\n if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n return new Response(\"Expected WebSocket upgrade\", { status: 426 });\n }\n\n const pair = new WebSocketPair();\n const client = pair[0];\n const server = pair[1];\n\n const url = new URL(request.url);\n const clientId = url.searchParams.get(\"clientId\") ?? crypto.randomUUID();\n const auth = (await this.options.authenticate?.({ clientId, request })) ?? { clientId };\n\n this.state.acceptWebSocket(server);\n server.serializeAttachment({\n clientId,\n connectedAt: Date.now(),\n auth,\n subscriptions: [],\n } satisfies WebSocketAttachment);\n\n return new Response(null, { status: 101, webSocket: client });\n }\n\n async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void> {\n try {\n const request = parseClientRpcRequest(message);\n\n const caller = router.createCaller({\n shardId: this.shardId(),\n validate: (input) => this.validate(input),\n persist: (input) => this.persist(input),\n publish: (input) => this.publish(input),\n mutate: (input) => this.mutate(input, webSocketAuth(ws)),\n subscribe: (input) => this.subscribe(ws, input),\n unsubscribe: (input) => this.unsubscribe(ws, input),\n read: (input) => this.read(input, webSocketAuth(ws)),\n changes: (input) => this.readChanges(input, webSocketAuth(ws)),\n callApi: (input) => this.callApi(ws, input),\n });\n\n const result = await callRouter(caller, request);\n sendRpcResult(ws, request.id, result);\n } catch (error) {\n sendRpcError(ws, readRpcId(message), error);\n }\n }\n\n private publish(batch: SequencedBatch): void {\n const payload: Broadcast = {\n type: \"updates\",\n shardId: this.shardId(),\n updates: batch.updates,\n watermark: batch.watermark,\n };\n\n for (const socket of this.state.getWebSockets()) {\n const updates = this.subscribedUpdates(socket, batch);\n const invalidations = this.subscribedInvalidations(socket, batch);\n if (updates.length === 0 && invalidations.length === 0) continue;\n\n sendServerMessage(socket, {\n method: \"subscription\",\n params: {\n path: \"updates\",\n input: {\n json: {\n ...payload,\n ...(invalidations.length > 0 ? { invalidations } : {}),\n updates,\n },\n },\n },\n });\n }\n }\n\n protected validate(batch: Batch): void {\n validateBatch(batch, this.options.collections);\n }\n\n protected persist(batch: Batch): SequencedBatch {\n return this.state.storage.transactionSync(() =>\n persistSQLiteJsonBatchWithHistory(\n this.state.storage.sql,\n batch,\n this.options.collections,\n this.options.history,\n ),\n );\n }\n\n protected read(query: ReadQuery, auth: AccessAuth = {}): ReadResult {\n const authorized = authorizeReadQuery(\n query,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return authorized\n ? readSQLiteJsonRows(this.state.storage.sql, authorized, this.options.collections)\n : { rows: [] };\n }\n\n protected readChanges(query: SyncChangesQuery, auth: AccessAuth = {}): SyncChangesResult {\n const result = readSQLiteJsonChanges(this.state.storage.sql, query, this.options.collections);\n if (result.type === \"resyncRequired\") return result;\n\n return {\n ...result,\n updates: result.updates.flatMap((update) => {\n const visible = visibleUpdateForAuth(\n update,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return visible\n ? [{ ...visible, sequence: update.sequence, serverCreatedAt: update.serverCreatedAt }]\n : [];\n }),\n };\n }\n\n private subscribe(ws: WebSocket, input: CollectionSubscription): CollectionSubscriptionResult {\n return this.updateSubscriptions(ws, input.collection, (subscriptions, collection) => {\n subscriptions.add(collection);\n });\n }\n\n private unsubscribe(ws: WebSocket, input: CollectionSubscription): CollectionSubscriptionResult {\n return this.updateSubscriptions(ws, input.collection, (subscriptions, collection) => {\n subscriptions.delete(collection);\n });\n }\n\n private async callApi(ws: WebSocket, call: ApiCall): Promise<unknown> {\n const handler = this.apiHandlers[call.path];\n\n if (!handler) {\n throw new Error(`Unknown API path: ${call.path}`);\n }\n\n const clientId = this.clientId(ws);\n const auth = webSocketAuth(ws);\n const args: ApiHandlerArgs = {\n shardId: this.shardId(),\n input: call.input,\n auth,\n validate: (input) => this.validate(input),\n persist: (input) => this.persist(input),\n publish: (input) => this.publish(input),\n subscribe: (input) => this.subscribe(ws, input),\n unsubscribe: (input) => this.unsubscribe(ws, input),\n mutate: (input) => this.mutate(input, auth),\n read: (input) => this.read(input, auth),\n changes: (input) => this.readChanges(input, auth),\n };\n\n if (clientId) args.clientId = clientId;\n return handler(args);\n }\n\n private mutate(batch: Batch, auth: AccessAuth = {}): PushResult {\n this.validate(batch);\n authorizeWriteBatch(batch, this.options.collections, auth, this.accessStore());\n const persisted = this.persist(batch);\n this.publish(persisted);\n return { accepted: batch.updates.length, watermark: persisted.watermark };\n }\n\n private clientId(ws: WebSocket): string | undefined {\n return webSocketAttachment(ws)?.clientId;\n }\n\n private updateSubscriptions(\n ws: WebSocket,\n collection: string,\n update: (subscriptions: Set<string>, collection: string) => void,\n ): CollectionSubscriptionResult {\n return updateSocketSubscriptions(\n ws,\n collection,\n (input) => normalizeCollection(input, this.options.collections),\n update,\n );\n }\n\n private subscribedUpdates(ws: WebSocket, batch: SequencedBatch): SequencedBatch[\"updates\"] {\n const attachment = webSocketAttachment(ws);\n if (!attachment || attachment.subscriptions.length === 0) return [];\n\n const subscriptions = new Set(attachment.subscriptions);\n const auth = webSocketAuth(ws);\n return batch.updates.flatMap((update) => {\n if (!subscriptions.has(normalizeCollection(update.collection, this.options.collections))) {\n return [];\n }\n\n const visible = visibleUpdateForAuth(\n update,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return visible\n ? [{ ...visible, sequence: update.sequence, serverCreatedAt: update.serverCreatedAt }]\n : [];\n });\n }\n\n private subscribedInvalidations(ws: WebSocket, batch: SequencedBatch) {\n const attachment = webSocketAttachment(ws);\n if (!attachment || attachment.subscriptions.length === 0) return [];\n\n return subscribedInvalidations(\n attachment.subscriptions,\n batch,\n this.options.collections,\n webSocketAuth(ws),\n this.accessStore(),\n );\n }\n\n private accessStore(): AccessStore {\n return {\n read: (collection, key) =>\n readSQLiteJsonRow(this.state.storage.sql, collection, key, this.options.collections),\n };\n }\n\n private shardId(): string {\n return this.state.id.toString();\n }\n}\n","import type { Env } from \"./durable-object\";\n\nexport interface WorkerOptions {\n binding?: keyof Env;\n routePattern?: RegExp;\n}\n\nexport function createWorkerHandler(options: WorkerOptions = {}) {\n const binding = options.binding ?? \"SYNC_SHARDS\";\n const routePattern = options.routePattern ?? /^\\/sync\\/([^/]+)$/;\n\n return {\n fetch(request: Request, env: Env): Promise<Response> | Response {\n const url = new URL(request.url);\n const match = url.pathname.match(routePattern);\n\n if (!match?.[1]) {\n return new Response(\"Not found\", { status: 404 });\n }\n\n const namespace = env[binding] as DurableObjectNamespace | undefined;\n if (!namespace) {\n return new Response(`Missing Durable Object binding: ${String(binding)}`, { status: 500 });\n }\n\n const id = namespace.idFromName(decodeURIComponent(match[1]));\n const stub = namespace.get(id);\n return stub.fetch(request);\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["readExpressionReferences","readExpressionRow","compileReadExpression","val","valueAtPath","combinePredicates","matchesReadPredicate","asRecord","readExpressionRow","tableName","jsonPath","quoteIdentifier","quoteIdentifier"],"sources":["../src/access-expression.ts","../src/collections.ts","../src/access.ts","../src/collection-normalize.ts","../src/sqlite-sql.ts","../src/sqlite-json-read.ts","../src/storage.ts","../src/collection-builder.ts","../src/definition-builder.ts","../src/durable-object-rpc.ts","../src/history-watermarks.ts","../src/mutation-dedup.ts","../src/history.ts","../src/messages.ts","../src/socket-attachment.ts","../src/safeguards.ts","../src/access-invalidation.ts","../src/subscription-invalidation.ts","../src/validation.ts","../src/durable-object.ts","../src/worker.ts"],"sourcesContent":["import {\n compileReadExpression,\n readExpressionReferences,\n readExpressionRow,\n type FuncExpression,\n type ReadExpression,\n type ReadExpressionRow,\n type RefExpression,\n type ValExpression,\n} from \"@lsync/transport\";\nimport type { ReadPredicate } from \"./types\";\n\nexport interface ReferenceDependency {\n collection: string;\n field: string;\n key: string | number;\n name: string;\n}\n\nexport interface ReducedAccessExpression {\n allow: boolean;\n dependencies: Array<ReferenceDependency>;\n predicate?: ReadPredicate;\n}\n\nexport function accessRows(referenceNames: Array<string>): {\n references: Record<string, ReadExpressionRow<Record<string, unknown>>>;\n row: ReadExpressionRow<Record<string, unknown>>;\n} {\n return {\n references: readExpressionReferences(referenceNames),\n row: readExpressionRow(),\n };\n}\n\nexport function reduceAccessExpression(\n expression: ReadExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n): ReducedAccessExpression {\n const dependencies: Array<ReferenceDependency> = [];\n const reduced = reduce(expression, references, dependencies);\n\n if (isVal(reduced)) {\n return {\n allow: reduced.value === true,\n dependencies,\n };\n }\n\n return {\n allow: true,\n dependencies,\n predicate: compileReadExpression(reduced),\n };\n}\n\nfunction reduce(\n expression: ReadExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const unwrapped = unwrap(expression);\n if (isVal(unwrapped)) return unwrapped;\n\n if (isRef(unwrapped)) {\n return reduceRef(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"and\") {\n return reduceAnd(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"or\") {\n return reduceOr(unwrapped, references, dependencies);\n }\n\n if (unwrapped.name === \"not\") {\n const child = reduceExpressionArg(unwrapped.args[0], references, dependencies);\n return isVal(child) ? val(child.value !== true) : func(\"not\", child);\n }\n\n const args = unwrapped.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (args.every(isVal)) {\n return val(\n evaluate(\n unwrapped.name,\n args.map((arg) => arg.value),\n ),\n );\n }\n\n return func(unwrapped.name, ...args);\n}\n\nfunction reduceRef(\n expression: RefExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n if (expression.source !== \"reference\") {\n return expression;\n }\n\n const name = expression.name;\n const reference = name ? references.get(name) : undefined;\n if (!name || !reference) {\n return val(undefined);\n }\n\n const field = expression.path.join(\".\");\n dependencies.push({ collection: reference.collection, field, key: reference.key, name });\n return val(valueAtPath(reference.value, expression.path));\n}\n\nfunction reduceAnd(\n expression: FuncExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const reduced = expression.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (reduced.some((arg) => isVal(arg) && arg.value !== true)) return val(false);\n const remaining = reduced.filter((arg) => !isVal(arg));\n if (remaining.length === 0) return val(true);\n return remaining.length === 1 ? remaining[0]! : func(\"and\", ...remaining);\n}\n\nfunction reduceOr(\n expression: FuncExpression,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n const reduced = expression.args.map((arg) => reduceExpressionArg(arg, references, dependencies));\n if (reduced.some((arg) => isVal(arg) && arg.value === true)) return val(true);\n const remaining = reduced.filter((arg) => !isVal(arg));\n if (remaining.length === 0) return val(false);\n return remaining.length === 1 ? remaining[0]! : func(\"or\", ...remaining);\n}\n\nfunction reduceExpressionArg(\n value: unknown,\n references: Map<string, { collection: string; key: string | number; value: unknown }>,\n dependencies: Array<ReferenceDependency>,\n): ReadExpression {\n return isExpression(value) ? reduce(value, references, dependencies) : val(value);\n}\n\nfunction evaluate(name: string, args: Array<unknown>): boolean {\n const [left, right] = args;\n switch (name) {\n case \"eq\":\n return left === right;\n case \"not_eq\":\n return left !== right;\n case \"gt\":\n return compare(left, right, (a, b) => a > b);\n case \"gte\":\n return compare(left, right, (a, b) => a >= b);\n case \"lt\":\n return compare(left, right, (a, b) => a < b);\n case \"lte\":\n return compare(left, right, (a, b) => a <= b);\n case \"in\":\n return Array.isArray(right) && right.includes(left);\n default:\n throw new Error(`Unsupported read access operator: ${name}`);\n }\n}\n\nfunction compare(\n left: unknown,\n right: unknown,\n compareValues: (left: number | string, right: number | string) => boolean,\n): boolean {\n if (typeof left === \"number\" && typeof right === \"number\") return compareValues(left, right);\n if (typeof left === \"string\" && typeof right === \"string\") return compareValues(left, right);\n return false;\n}\n\nfunction func(name: string, ...args: Array<unknown>): FuncExpression {\n return { type: \"func\", name, args };\n}\n\nfunction val(value: unknown): ValExpression {\n return { type: \"val\", value };\n}\n\nfunction valueAtPath(value: unknown, path: Array<string | number>): unknown {\n return path.reduce<unknown>((current, segment) => {\n if (typeof current !== \"object\" || current === null) return undefined;\n return (current as Record<string, unknown>)[String(segment)];\n }, value);\n}\n\nfunction unwrap(expression: ReadExpression): FuncExpression | RefExpression | ValExpression {\n return \"expression\" in expression ? unwrap(expression.expression) : expression;\n}\n\nfunction isExpression(value: unknown): value is ReadExpression {\n return typeof value === \"object\" && value !== null && (\"type\" in value || \"expression\" in value);\n}\n\nfunction isVal(value: ReadExpression): value is ValExpression {\n const unwrapped = unwrap(value);\n return unwrapped.type === \"val\";\n}\n\nfunction isRef(value: ReadExpression): value is RefExpression {\n const unwrapped = unwrap(value);\n return unwrapped.type === \"ref\";\n}\n","import type { ApiHandler, CollectionConfig, CollectionConfigs } from \"./types\";\n\nexport interface ResolvedCollection {\n name: string;\n collection: CollectionConfig;\n params: Record<string, string>;\n scope: string;\n}\n\ninterface PatternMatch {\n name: string;\n collection: CollectionConfig;\n params: Record<string, string>;\n staticSegments: number;\n segments: number;\n index: number;\n}\n\nexport function resolveCollection(\n collectionName: string,\n collections: CollectionConfigs = {},\n): ResolvedCollection | undefined {\n const exact = collections[collectionName];\n\n if (exact) {\n return {\n name: collectionName,\n collection: exact,\n params: {},\n scope: collectionScope(collectionName),\n };\n }\n\n const matches = Object.entries(collections).flatMap(([name, collection], index) => {\n const match = matchCollectionPattern(name, collectionName);\n\n return match\n ? [\n {\n name,\n collection,\n params: match.params,\n staticSegments: match.staticSegments,\n segments: match.segments,\n index,\n },\n ]\n : [];\n });\n\n const best = matches.sort(comparePatternMatches)[0];\n if (!best) {\n return undefined;\n }\n\n return {\n name: best.name,\n collection: best.collection,\n params: best.params,\n scope: collectionScope(collectionName),\n };\n}\n\nexport function collectionScope(collectionName: string): string {\n const segments = splitCollectionPath(collectionName);\n return `/${segments.map(normalizeSegment).join(\"/\")}/`;\n}\n\nexport function isCollectionPattern(collectionName: string): boolean {\n return collectionName.split(\"/\").some((segment) => /^\\{[A-Za-z_][A-Za-z0-9_]*\\}$/.test(segment));\n}\n\nexport function collectionApiHandlers(\n collections: CollectionConfigs = {},\n): Record<string, ApiHandler> {\n const handlers: Record<string, ApiHandler> = {};\n\n for (const [collectionPath, collection] of Object.entries(collections)) {\n for (const [name, definition] of Object.entries(collection.api ?? {})) {\n const path = defaultCollectionApiPath(collectionPath, name);\n\n if (handlers[path]) {\n throw new Error(`Duplicate API path: ${path}`);\n }\n\n handlers[path] = (args) =>\n definition.handler({\n ...args,\n input: definition.input.parse(args.input),\n });\n }\n }\n\n return handlers;\n}\n\nexport function defaultCollectionApiPath(collectionPath: string, name: string): string {\n const prefix = splitCollectionPath(collectionPath)\n .filter((segment) => !collectionPathParamName(segment))\n .join(\".\");\n\n return prefix ? `${prefix}.${name}` : name;\n}\n\nfunction matchCollectionPattern(\n pattern: string,\n collectionName: string,\n): Omit<PatternMatch, \"name\" | \"collection\" | \"index\"> | undefined {\n if (!isCollectionPattern(pattern)) {\n return undefined;\n }\n\n const patternSegments = splitCollectionPath(pattern);\n const collectionSegments = splitCollectionPath(collectionName);\n\n if (patternSegments.length !== collectionSegments.length) {\n return undefined;\n }\n\n const params: Record<string, string> = {};\n let staticSegments = 0;\n\n for (const [index, segment] of patternSegments.entries()) {\n const param = segment.match(/^\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/);\n\n if (param?.[1]) {\n params[param[1]] = decodeURIComponent(collectionSegments[index] ?? \"\");\n continue;\n }\n\n if (segment !== collectionSegments[index]) {\n return undefined;\n }\n\n staticSegments += 1;\n }\n\n return {\n params,\n staticSegments,\n segments: patternSegments.length,\n };\n}\n\nfunction comparePatternMatches(left: PatternMatch, right: PatternMatch): number {\n return (\n right.staticSegments - left.staticSegments ||\n right.segments - left.segments ||\n left.index - right.index\n );\n}\n\nfunction splitCollectionPath(path: string): Array<string> {\n const trimmed = path.trim().replace(/^\\/+|\\/+$/g, \"\");\n\n if (!trimmed) {\n return [];\n }\n\n return trimmed.split(\"/\");\n}\n\nfunction collectionPathParamName(segment: string): string | undefined {\n return (\n segment.match(/^\\{([A-Za-z_][A-Za-z0-9_]*)\\}$/)?.[1] ??\n segment.match(/^:([A-Za-z_][A-Za-z0-9_]*)$/)?.[1]\n );\n}\n\nfunction normalizeSegment(segment: string): string {\n return encodeURIComponent(decodeURIComponent(segment));\n}\n","import { matchesReadPredicate, readExpressionRow } from \"@lsync/transport\";\nimport { accessRows, reduceAccessExpression, type ReferenceDependency } from \"./access-expression\";\nimport { resolveCollection } from \"./collections\";\nimport type {\n AccessAuth,\n AccessReference,\n ApiAccessHandler,\n Batch,\n CollectionAccessConfig,\n CollectionConfigs,\n OperationType,\n ReadPredicate,\n ReadQuery,\n Update,\n} from \"./types\";\n\nexport interface AccessStore {\n read(collection: string, key: string | number): Record<string, unknown> | undefined;\n}\n\nexport interface ReadAccessDecision {\n allow: boolean;\n dependencies: Array<ReferenceDependency>;\n predicate?: ReadPredicate;\n}\n\nexport function authorizeReadQuery(\n query: ReadQuery,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadQuery | undefined {\n const decision = readAccessDecision(query.collection, collections, auth, store);\n if (!decision.allow) return undefined;\n if (!decision.predicate) return query;\n\n const predicate = combinePredicates(decision.predicate, query.predicate);\n return predicate ? { ...query, predicate } : query;\n}\n\nexport function visibleUpdateForAuth(\n update: Update,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): Update | undefined {\n const decision = readAccessDecision(update.collection, collections, auth, store);\n if (!decision.allow) return undefined;\n if (!decision.predicate) return update;\n\n const before = update.previousValue\n ? matchesReadPredicate(update.previousValue, decision.predicate)\n : false;\n const after = update.value ? matchesReadPredicate(update.value, decision.predicate) : false;\n\n if (!before && !after) return undefined;\n\n if (before && !after) {\n const { previousValue, value, ...base } = update;\n void previousValue;\n void value;\n return { ...base, type: \"delete\" };\n }\n\n return !before && after && update.type === \"update\" ? { ...update, type: \"insert\" } : update;\n}\n\nexport function authorizeWriteBatch(\n batch: Batch,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): void {\n for (const update of batch.updates) {\n const decision = writeAccessDecision(update, collections, auth, store);\n if (decision.allow) continue;\n\n throw new Error(`Access denied for ${update.type} on ${update.collection}`);\n }\n}\n\nexport function authorizeApiCall(\n handler: ApiAccessHandler | undefined,\n name: string,\n input: unknown,\n auth: AccessAuth,\n): void {\n if (!handler) return;\n\n const row = asRecord(input) ?? {};\n const expression = handler({ auth, input: readExpressionRow() });\n const decision = reduceAccessExpression(expression, new Map());\n const allowed =\n decision.allow && (!decision.predicate || matchesReadPredicate(row, decision.predicate));\n\n if (!allowed) {\n throw new Error(`Access denied for API: ${name}`);\n }\n}\n\nexport function readAccessDecision(\n collection: string,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadAccessDecision {\n const resolved = resolveCollection(collection, collections);\n if (!resolved) {\n return { allow: true, dependencies: [] };\n }\n\n const access = resolved?.collection.access;\n if (!access?.read) return { allow: true, dependencies: [] };\n\n const references = accessReferences(collection, collections, auth);\n const rows = accessRows([...references.keys()]);\n const expression = access.read({\n auth,\n collection: resolved.scope,\n references: rows.references,\n params: resolved.params,\n pattern: resolved.name,\n row: rows.row,\n });\n const referenceValues = new Map(\n [...references].map(([name, reference]) => [\n name,\n {\n ...reference,\n value: store.read(reference.collection, reference.key),\n },\n ]),\n );\n\n return reduceAccessExpression(expression, referenceValues);\n}\n\nexport function writeAccessDecision(\n update: Update,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): ReadAccessDecision {\n const resolved = resolveCollection(update.collection, collections);\n if (!resolved) return { allow: true, dependencies: [] };\n\n const access = resolved.collection.access;\n const handler = writeAccessHandler(access, update.type);\n if (!handler) return { allow: true, dependencies: [] };\n\n const row = writeAccessRow(update, store);\n if (!row) return { allow: false, dependencies: [] };\n\n const references = accessReferences(update.collection, collections, auth);\n const rows = accessRows([...references.keys()]);\n const expression = handler({\n auth,\n collection: resolved.scope,\n references: rows.references,\n params: resolved.params,\n pattern: resolved.name,\n row: rows.row,\n });\n const referenceValues = new Map(\n [...references].map(([name, reference]) => [\n name,\n {\n ...reference,\n value: store.read(reference.collection, reference.key),\n },\n ]),\n );\n const decision = reduceAccessExpression(expression, referenceValues);\n\n if (!decision.allow || !decision.predicate) return decision;\n\n return matchesReadPredicate(row, decision.predicate) ? decision : { ...decision, allow: false };\n}\n\nexport function accessReferences(\n collection: string,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n): Map<string, { collection: string; key: string | number }> {\n const resolved = resolveCollection(collection, collections);\n const references = resolved?.collection.access?.references;\n if (!resolved || !references) return new Map();\n\n return new Map(\n Object.entries(references).map(([name, resolver]) => [\n name,\n normalizeAccessReference(\n resolver({\n auth,\n collection: resolved.scope,\n params: resolved.params,\n pattern: resolved.name,\n }),\n ),\n ]),\n );\n}\n\nexport function normalizeAccessReference(reference: AccessReference): {\n collection: string;\n key: string | number;\n} {\n if (typeof reference !== \"string\") return reference;\n\n const normalized = reference.trim().replace(/^\\/+|\\/+$/g, \"\");\n const segments = normalized ? normalized.split(\"/\") : [];\n const key = segments.at(-1);\n if (!key || segments.length < 2) {\n throw new Error(`Invalid access reference path: ${reference}`);\n }\n\n return {\n collection: `/${segments.slice(0, -1).map(encodeURIComponent).join(\"/\")}/`,\n key: decodeURIComponent(key),\n };\n}\n\nfunction combinePredicates(\n left: ReadPredicate | undefined,\n right: ReadPredicate | undefined,\n): ReadPredicate | undefined {\n if (!left) return right;\n if (!right) return left;\n return { type: \"and\", predicates: [left, right] };\n}\n\nfunction writeAccessHandler(\n access: CollectionAccessConfig | undefined,\n type: OperationType,\n): CollectionAccessConfig[\"read\"] | undefined {\n if (!access) return undefined;\n return access[type] ?? access.write ?? access.read;\n}\n\nfunction writeAccessRow(update: Update, store: AccessStore): Record<string, unknown> | undefined {\n if (update.type === \"insert\") {\n return asRecord(update.value);\n }\n\n const existing = asRecord(update.previousValue) ?? store.read(update.collection, update.key);\n\n if (update.type === \"delete\") {\n return existing;\n }\n\n const next = asRecord(update.value);\n return existing && next ? { ...existing, ...next } : (next ?? existing);\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n","import { collectionScope, resolveCollection } from \"./collections\";\nimport type { CollectionConfigs } from \"./types\";\n\nexport function normalizeCollection(\n collection: string,\n collections: CollectionConfigs | undefined,\n): string {\n const configured = resolveCollection(collection, collections);\n\n if (configured) {\n return configured.scope;\n }\n\n if (collections && Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return collectionScope(collection);\n}\n","import type { Sql } from \"sql-template-tag\";\nimport { raw } from \"sql-template-tag\";\n\ntype SqlStorageValue = ArrayBuffer | string | number | null;\n\ninterface SqlStorageCursorLike<T extends Record<string, SqlStorageValue>> {\n toArray(): Array<T>;\n}\n\ninterface SqlStorageLike {\n exec<T extends Record<string, SqlStorageValue>>(\n query: string,\n ...bindings: Array<unknown>\n ): SqlStorageCursorLike<T>;\n}\n\nexport function execSql<T extends Record<string, SqlStorageValue>>(\n storage: SqlStorageLike,\n statement: Sql,\n): SqlStorageCursorLike<T> {\n return storage.exec<T>(statement.sql, ...statement.values);\n}\n\nexport function identifierSql(identifier: string): Sql {\n return raw(`\"${identifier.replaceAll(`\"`, `\"\"`)}\"`);\n}\n\nexport function rawSql(value: string): Sql {\n return raw(value);\n}\n","import type {\n CollectionConfigs,\n ReadFilter,\n ReadOrderBy,\n ReadPredicate,\n ReadQuery,\n ReadResult,\n SQLiteJsonStorageConfig,\n} from \"./types\";\nimport { resolveCollection } from \"./collections\";\nimport {\n ensureSQLiteJsonTables,\n sqliteJsonStorage,\n type SqlStorageLike,\n type SqlStorageValue,\n} from \"./storage\";\nimport sqlTag, { join, type Sql } from \"sql-template-tag\";\nimport { execSql, identifierSql, rawSql } from \"./sqlite-sql\";\n\nexport function readSQLiteJsonRows(\n sql: SqlStorageLike,\n query: ReadQuery,\n collections: CollectionConfigs = {},\n): ReadResult {\n ensureSQLiteJsonTables(sql, collections);\n\n const resolved = resolveCollection(query.collection, collections);\n if (!resolved) {\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${query.collection}`);\n }\n\n throw new Error(`Cannot read unconfigured collection: ${query.collection}`);\n }\n\n const storage = sqliteJsonStorage(resolved.collection.storage);\n if (!storage) {\n throw new Error(`Collection is not readable with SQLite JSON storage: ${query.collection}`);\n }\n\n const table = tableName(resolved.name, storage);\n const filters = query.filters ?? [];\n const predicate = query.predicate;\n const orderBy = query.orderBy ?? [];\n const limit = query.limit ?? 1000;\n const scope = { scope: resolved.scope };\n\n if (query.cursor) {\n const currentPredicate = combinePredicates(predicate, query.cursor.whereCurrent);\n const fromPredicate = combinePredicates(predicate, query.cursor.whereFrom);\n const currentRows = selectRows(sql, table, {\n filters,\n orderBy,\n ...scope,\n ...(currentPredicate ? { predicate: currentPredicate } : {}),\n });\n const fromRows = selectRows(sql, table, {\n filters,\n limit,\n orderBy,\n ...scope,\n ...(fromPredicate ? { predicate: fromPredicate } : {}),\n });\n\n return {\n rows: uniqueRows([...currentRows, ...fromRows]).map((row) => JSON.parse(row.value)),\n };\n }\n\n const rows = selectRows(sql, table, {\n filters,\n limit,\n offset: query.offset ?? 0,\n orderBy,\n ...scope,\n ...(predicate ? { predicate } : {}),\n });\n\n return {\n rows: rows.map((row) => JSON.parse(row.value)),\n };\n}\n\nexport function readSQLiteJsonRow(\n sql: SqlStorageLike,\n collection: string,\n key: string | number,\n collections: CollectionConfigs = {},\n): Record<string, unknown> | undefined {\n ensureSQLiteJsonTables(sql, collections);\n\n const resolved = resolveCollection(collection, collections);\n if (!resolved) {\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n throw new Error(`Cannot read unconfigured collection: ${collection}`);\n }\n\n if (resolved.collection.storage?.kind !== \"sqlite-json\") {\n throw new Error(`Collection is not readable with SQLite JSON storage: ${collection}`);\n }\n\n const table = tableName(resolved.name, resolved.collection.storage);\n const row = execSql<{ value: string }>(\n sql,\n sqlTag`\n SELECT value FROM ${identifierSql(table)}\n WHERE path = ${resolved.scope} AND key = ${String(key)}\n `,\n ).toArray()[0];\n\n return row ? (JSON.parse(row.value) as Record<string, unknown>) : undefined;\n}\n\ninterface SelectRowsOptions {\n filters: Array<ReadFilter>;\n limit?: number;\n offset?: number;\n orderBy: Array<ReadOrderBy>;\n scope: string;\n predicate?: ReadPredicate;\n}\n\nfunction selectRows(\n sql: SqlStorageLike,\n table: string,\n options: SelectRowsOptions,\n): Array<{ key: string; value: string }> {\n const where = [sqlTag`path = ${options.scope}`];\n\n where.push(...options.filters.map((filter) => filterSql(filter)));\n if (options.predicate) {\n where.push(predicateSql(options.predicate));\n }\n\n const order =\n options.orderBy.length > 0\n ? sqlTag`${join(options.orderBy.map((item) => orderBySql(item)))}, key`\n : sqlTag`key`;\n\n return execSql<{ key: string; value: string }>(\n sql,\n sqlTag`\n SELECT key, value FROM ${identifierSql(table)}\n WHERE ${join(where, \" AND \")}\n ORDER BY ${order}\n LIMIT ${options.limit ?? 1000} OFFSET ${options.offset ?? 0}\n `,\n ).toArray();\n}\n\nfunction uniqueRows(\n rows: Array<{ key: string; value: string }>,\n): Array<{ key: string; value: string }> {\n const seen = new Set<string>();\n const unique: Array<{ key: string; value: string }> = [];\n for (const row of rows) {\n if (!seen.has(row.key)) {\n seen.add(row.key);\n unique.push(row);\n }\n }\n return unique;\n}\n\nfunction tableName(collectionName: string, storage: SQLiteJsonStorageConfig): string {\n return storage.tableName ?? collectionName;\n}\n\nfunction jsonPath(field: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(field)) {\n throw new Error(`Invalid JSON index field: ${field}`);\n }\n\n return `$.${field}`;\n}\n\nfunction orderBySql(orderBy: ReadOrderBy): Sql {\n const direction = orderBy.direction === \"desc\" ? \"DESC\" : \"ASC\";\n return sqlTag`json_extract(value, ${jsonPath(orderBy.field)}) ${directionSql(direction)}`;\n}\n\nfunction predicateSql(predicate: ReadPredicate): Sql {\n if (predicate.type === \"comparison\") {\n return filterSql(predicate);\n }\n\n const joiner = predicate.type === \"and\" ? \" AND \" : \" OR \";\n return sqlTag`(${join(\n predicate.predicates.map((child) => predicateSql(child)),\n joiner,\n )})`;\n}\n\nfunction combinePredicates(\n left: ReadPredicate | undefined,\n right: ReadPredicate | undefined,\n): ReadPredicate | undefined {\n if (!left) return right;\n if (!right) return left;\n return { type: \"and\", predicates: [left, right] };\n}\n\nfunction filterSql(filter: ReadFilter): Sql {\n const field = sqlTag`json_extract(value, ${jsonPath(filter.field)})`;\n\n if (filter.op === \"in\") {\n if (!Array.isArray(filter.value) || filter.value.length === 0) {\n throw new Error(\"The in filter requires a non-empty array value\");\n }\n\n return sqlTag`${field} IN (${join(filter.value.map(toSqlJsonValue))})`;\n }\n\n const value = toSqlJsonValue(filter.value);\n\n if (value === null) {\n if (filter.op === \"eq\") return sqlTag`${field} IS ${value}`;\n if (filter.op === \"ne\") return sqlTag`${field} IS NOT ${value}`;\n }\n\n switch (filter.op) {\n case \"eq\":\n return sqlTag`${field} = ${value}`;\n case \"ne\":\n return sqlTag`${field} != ${value}`;\n case \"gt\":\n return sqlTag`${field} > ${value}`;\n case \"gte\":\n return sqlTag`${field} >= ${value}`;\n case \"lt\":\n return sqlTag`${field} < ${value}`;\n case \"lte\":\n return sqlTag`${field} <= ${value}`;\n }\n}\n\nfunction directionSql(direction: \"ASC\" | \"DESC\"): Sql {\n return rawSql(direction);\n}\n\nfunction toSqlJsonValue(value: unknown): SqlStorageValue {\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value instanceof ArrayBuffer\n ) {\n return value;\n }\n\n throw new Error(`Unsupported SQLite JSON filter value: ${typeof value}`);\n}\n","import type {\n Batch,\n CollectionConfigs,\n CollectionStorageConfig,\n SQLiteJsonIndexConfig,\n SQLiteJsonStorageConfig,\n} from \"./types\";\nimport { collectionScope, resolveCollection } from \"./collections\";\nimport sqlTag, { join, type Sql } from \"sql-template-tag\";\nimport { execSql, identifierSql, rawSql } from \"./sqlite-sql\";\n\nexport { readSQLiteJsonRow, readSQLiteJsonRows } from \"./sqlite-json-read\";\n\nexport type SqlStorageValue = ArrayBuffer | string | number | null;\n\nexport interface SqlStorageCursorLike<T extends Record<string, SqlStorageValue>> {\n toArray(): Array<T>;\n}\n\nexport interface SqlStorageLike {\n exec<T extends Record<string, SqlStorageValue>>(\n query: string,\n ...bindings: Array<unknown>\n ): SqlStorageCursorLike<T>;\n}\n\nexport interface SQLiteJsonTableOptions {\n tableName?: string;\n indexes?: Array<Array<string> | SQLiteJsonIndexConfig>;\n}\n\nexport function sqliteJsonTable(options: SQLiteJsonTableOptions = {}): SQLiteJsonStorageConfig {\n return {\n kind: \"sqlite-json\",\n ...(options.tableName ? { tableName: options.tableName } : {}),\n indexes: (options.indexes ?? []).map((index) =>\n Array.isArray(index) ? { fields: index } : index,\n ),\n };\n}\n\nexport function ensureSQLiteJsonTables(\n sql: SqlStorageLike,\n collections: CollectionConfigs = {},\n): void {\n for (const [collectionName, collection] of Object.entries(collections)) {\n const storage = sqliteJsonStorage(collection.storage);\n if (!storage) {\n continue;\n }\n\n const table = tableName(collectionName, storage);\n const result = execSql(\n sql,\n sqlTag`\n CREATE TABLE IF NOT EXISTS ${identifierSql(table)} (\n key TEXT NOT NULL,\n path TEXT NOT NULL,\n value TEXT NOT NULL,\n version INTEGER NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (path, key)\n )\n `,\n );\n\n for (const index of storage.indexes) {\n execSql(sql, createIndexSql(table, index));\n }\n\n if ((result as unknown as { rowsWritten: number }).rowsWritten > 0) {\n if (collection.initialData) {\n for (const data of collection.initialData) {\n const key = String(data.id);\n const path = collectionScope(collectionName);\n const value = JSON.stringify(data);\n const version = 1;\n const createdAt = new Date().toISOString();\n const updatedAt = createdAt;\n execSql(\n sql,\n sqlTag`\n INSERT INTO ${identifierSql(table)} (key, path, value, version, created_at, updated_at)\n VALUES (${key}, ${path}, ${value}, ${version}, ${createdAt}, ${updatedAt})\n `,\n );\n }\n }\n }\n }\n}\n\nexport function applySQLiteJsonBatch(\n sql: SqlStorageLike,\n batch: Batch,\n collections: CollectionConfigs = {},\n): void {\n ensureSQLiteJsonTables(sql, collections);\n\n for (const update of batch.updates) {\n const resolved = resolveCollection(update.collection, collections);\n const storage = resolved ? sqliteJsonStorage(resolved.collection.storage) : undefined;\n\n if (!resolved || !storage) {\n continue;\n }\n\n const table = tableName(resolved.name, storage);\n const key = String(update.key);\n const scope = resolved.scope;\n const updatedAt = new Date(update.createdAt).toISOString();\n\n if (update.type === \"delete\") {\n execSql(sql, sqlTag`DELETE FROM ${identifierSql(table)} WHERE ${whereKeySql(scope, key)}`);\n continue;\n }\n\n if (update.type === \"insert\") {\n execSql(\n sql,\n sqlTag`\n INSERT INTO ${identifierSql(table)} (key, path, value, version, created_at, updated_at)\n VALUES (${key}, ${scope}, ${stringifyRow(update.value)}, 1, ${updatedAt}, ${updatedAt})\n ON CONFLICT(path, key) DO UPDATE SET\n path = excluded.path,\n value = excluded.value,\n version = ${identifierSql(table)}.version + 1,\n updated_at = excluded.updated_at\n `,\n );\n continue;\n }\n\n const existing = execSql<{ value: string }>(\n sql,\n sqlTag`SELECT value FROM ${identifierSql(table)} WHERE ${whereKeySql(scope, key)}`,\n ).toArray()[0];\n\n if (!existing) {\n throw new Error(`Cannot update missing ${update.collection} row: ${key}`);\n }\n\n const merged = mergeRows(JSON.parse(existing.value), update.value);\n execSql(\n sql,\n sqlTag`\n UPDATE ${identifierSql(table)}\n SET value = ${JSON.stringify(merged)}, version = version + 1, updated_at = ${updatedAt}\n WHERE ${whereKeySql(scope, key)}\n `,\n );\n }\n}\n\nexport function sqliteJsonStorage(\n storage: CollectionStorageConfig | undefined,\n): SQLiteJsonStorageConfig | undefined {\n if (!storage) {\n return sqliteJsonTable();\n }\n\n return storage.kind === \"sqlite-json\" ? storage : undefined;\n}\n\nfunction whereKeySql(scope: string, key: string): Sql {\n return sqlTag`path = ${scope} AND key = ${key}`;\n}\n\nfunction tableName(collectionName: string, storage: SQLiteJsonStorageConfig): string {\n return storage.tableName ?? collectionName;\n}\n\nfunction createIndexSql(table: string, index: SQLiteJsonIndexConfig): Sql {\n const name = index.name ?? `${table}_${index.fields.join(\"_\")}_idx`;\n const fields = index.fields.map((field) => rawSql(`json_extract(value, '$.${jsonPath(field)}')`));\n\n return sqlTag`\n CREATE INDEX IF NOT EXISTS ${identifierSql(name)}\n ON ${identifierSql(table)} (${join(fields)})\n `;\n}\n\nfunction jsonPath(field: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(field)) {\n throw new Error(`Invalid JSON index field: ${field}`);\n }\n\n return field;\n}\n\nfunction stringifyRow(value: unknown): string {\n if (!isRecord(value)) {\n throw new Error(\"SQLite JSON storage requires object row values\");\n }\n\n return JSON.stringify(value);\n}\n\nfunction mergeRows(existing: unknown, changes: unknown): Record<string, unknown> {\n if (!isRecord(existing) || !isRecord(changes)) {\n throw new Error(\"SQLite JSON storage can only merge object update values\");\n }\n\n return {\n ...existing,\n ...changes,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import type { z } from \"zod\";\nimport type {\n ApiHandler,\n CollectionAccessConfig,\n CollectionApiHandlers,\n CollectionConfig,\n CollectionConfigs,\n CollectionStorageConfig,\n SQLiteJsonIndexConfig,\n} from \"./types\";\nimport { sqliteJsonTable } from \"./storage\";\n\ntype BuilderState = {\n path?: string;\n schema?: z.ZodTypeAny;\n access?: CollectionAccessConfig<any>;\n storage?: CollectionStorageConfig;\n indexes?: Array<SQLiteJsonIndexConfig>;\n initialData?: Array<Record<string, unknown>>;\n api?: CollectionApiHandlers;\n children?: Record<string, CollectionBuilder<any>>;\n};\n\ntype InitialCollectionBuilder = Pick<CollectionBuilder<Record<string, unknown>>, \"name\" | \"path\">;\ntype ConfiguredCollectionBuilder<T extends object> = Omit<\n CollectionBuilder<T>,\n \"name\" | \"path\" | \"schema\"\n>;\ntype IndexField<T extends object> = string extends keyof T ? string : Extract<keyof T, string>;\ntype BuilderIndexConfig<T extends object> = Omit<SQLiteJsonIndexConfig, \"fields\"> & {\n fields: Array<IndexField<T>>;\n};\n\nexport function collectionConfigsBuilder(): CollectionConfigsBuilder {\n return new CollectionConfigsBuilder({});\n}\n\nexport function collectionBuilder(): InitialCollectionBuilder {\n return new CollectionBuilder({});\n}\n\nexport const Collections = {\n builder: collectionConfigsBuilder,\n collection: collectionBuilder,\n};\n\nexport class CollectionConfigsBuilder {\n private readonly collections: Readonly<CollectionConfigs>;\n\n constructor(collections: CollectionConfigs) {\n this.collections = Object.freeze({ ...collections });\n }\n\n collection<TBuilder extends CollectionBuilder<any>>(\n name: string,\n configure: (\n builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\" | \"path\">,\n ) => TBuilder,\n ): CollectionConfigsBuilder {\n const builder = configure(new CollectionBuilder({ path: rootPathForName(name) }));\n return new CollectionConfigsBuilder({\n ...this.collections,\n ...builder.entries(),\n });\n }\n\n path<TBuilder extends CollectionBuilder<any>>(\n path: string,\n configure: (builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\">) => TBuilder,\n ): CollectionConfigsBuilder {\n const builder = configure(new CollectionBuilder({ path }));\n return new CollectionConfigsBuilder({\n ...this.collections,\n ...builder.entries(),\n });\n }\n\n build(): CollectionConfigs {\n return { ...this.collections };\n }\n}\n\nexport class CollectionBuilder<T extends object = Record<string, unknown>> {\n private readonly state: Readonly<BuilderState>;\n\n constructor(state: BuilderState) {\n this.state = freezeState(state);\n }\n\n name(name: string): Pick<CollectionBuilder<T>, \"schema\" | \"path\"> {\n return this.next({ path: rootPathForName(name) });\n }\n\n path(path: string): Pick<CollectionBuilder<T>, \"schema\"> {\n return this.next({ path });\n }\n\n schema<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n ): ConfiguredCollectionBuilder<z.output<TSchema> & object> {\n return this.next({ schema }) as unknown as ConfiguredCollectionBuilder<\n z.output<TSchema> & object\n >;\n }\n\n access(access: CollectionAccessConfig<T>): CollectionBuilder<T> {\n return this.next({ access });\n }\n\n storage(storage: CollectionStorageConfig): CollectionBuilder<T> {\n return this.next({ storage });\n }\n\n index(field: IndexField<T>, ...fields: Array<IndexField<T>>): CollectionBuilder<T>;\n index(fields: Array<IndexField<T>> | BuilderIndexConfig<T>): CollectionBuilder<T>;\n index(\n fieldOrIndex: IndexField<T> | Array<IndexField<T>> | BuilderIndexConfig<T>,\n ...fields: Array<IndexField<T>>\n ): CollectionBuilder<T> {\n return this.next({\n indexes: [...(this.state.indexes ?? []), normalizeIndex(fieldOrIndex, fields)],\n });\n }\n\n initialData<TData extends T>(...initialData: Array<TData>): CollectionBuilder<T> {\n return this.next({ initialData: initialData as Array<Record<string, unknown>> });\n }\n\n api<TName extends string, TSchema extends z.ZodTypeAny, TResult = unknown>(\n name: TName,\n input: TSchema,\n handler: ApiHandler<TResult, z.output<TSchema>>,\n ): CollectionBuilder<T> {\n return this.next({\n api: {\n ...this.state.api,\n [name]: freezeApiDefinition({ input, handler }),\n },\n });\n }\n\n child<TBuilder extends CollectionBuilder<any>>(\n name: string,\n configure: (\n builder: Pick<CollectionBuilder<Record<string, unknown>>, \"schema\" | \"path\">,\n ) => TBuilder,\n ): CollectionBuilder<T> {\n const path = this.requirePath(\"CollectionBuilder.child\");\n const builder = configure(\n new CollectionBuilder({\n path: childPathForName(path, parentIdParamForName(path), name),\n }),\n );\n\n return this.next({\n children: {\n ...this.state.children,\n [name]: builder,\n },\n });\n }\n\n buildConfig(): CollectionConfig<T> {\n if (!this.state.schema) {\n throw new Error(\"CollectionBuilder requires a schema\");\n }\n\n const config: CollectionConfig<T> = {\n schema: this.state.schema,\n };\n\n if (this.state.access) config.access = this.state.access as CollectionAccessConfig<T>;\n config.storage = storageWithIndexes(this.state.storage, this.state.indexes ?? []);\n if (this.state.initialData) config.initialData = [...this.state.initialData];\n if (this.state.api) config.api = { ...this.state.api };\n\n return config;\n }\n\n build(): CollectionConfigs {\n return this.entries();\n }\n\n entries(): CollectionConfigs {\n const path = this.requirePath(\"CollectionBuilder.build\");\n const entries: CollectionConfigs = {\n [path]: this.buildConfig() as CollectionConfig,\n };\n\n for (const child of Object.values(this.state.children ?? {})) {\n Object.assign(entries, child.entries());\n }\n\n return entries;\n }\n\n private next(updates: Partial<BuilderState>): CollectionBuilder<T> {\n return new CollectionBuilder<T>({\n ...this.state,\n ...updates,\n });\n }\n\n private requirePath(caller: string): string {\n if (!this.state.path) {\n throw new Error(`${caller} requires a name or path`);\n }\n\n return this.state.path;\n }\n}\n\nfunction freezeState(state: BuilderState): Readonly<BuilderState> {\n const next: BuilderState = {};\n\n if (state.path) next.path = state.path;\n if (state.schema) next.schema = state.schema;\n if (state.access) next.access = state.access;\n if (state.storage) next.storage = state.storage;\n if (state.indexes) next.indexes = state.indexes.map((index) => ({ ...index }));\n if (state.initialData) next.initialData = [...state.initialData];\n if (state.api) next.api = Object.freeze({ ...state.api });\n if (state.children) next.children = Object.freeze({ ...state.children });\n\n return Object.freeze(next);\n}\n\nfunction freezeApiDefinition(\n definition: CollectionApiHandlers[string],\n): CollectionApiHandlers[string] {\n return Object.freeze({ ...definition });\n}\n\nfunction normalizeIndex(\n fieldOrIndex: string | Array<string> | SQLiteJsonIndexConfig,\n fields: Array<string>,\n): SQLiteJsonIndexConfig {\n if (typeof fieldOrIndex === \"string\") {\n return { fields: [fieldOrIndex, ...fields] };\n }\n\n return Array.isArray(fieldOrIndex) ? { fields: fieldOrIndex } : fieldOrIndex;\n}\n\nfunction storageWithIndexes(\n storage: CollectionStorageConfig | undefined,\n indexes: Array<SQLiteJsonIndexConfig>,\n): CollectionStorageConfig {\n const current = storage ?? sqliteJsonTable();\n\n if (current.kind !== \"sqlite-json\") {\n return current;\n }\n\n return {\n ...current,\n indexes: [...current.indexes, ...indexes],\n };\n}\n\nfunction rootPathForName(name: string): string {\n return `/${encodeURIComponent(name)}/`;\n}\n\nfunction childPathForName(parentPath: string, parentParam: string, name: string): string {\n return `${parentPath.replace(/\\/+$/g, \"\")}/{${parentParam}}/${encodeURIComponent(name)}/`;\n}\n\nfunction parentIdParamForName(parentPath: string): string {\n const segment = parentPath\n .trim()\n .replace(/^\\/+|\\/+$/g, \"\")\n .split(\"/\")\n .filter((part) => !part.startsWith(\"{\") && !part.startsWith(\":\"))\n .at(-1);\n\n return `${singularize(segment ?? \"parent\")}Id`;\n}\n\nfunction singularize(value: string): string {\n return value.endsWith(\"s\") ? value.slice(0, -1) : value;\n}\n","import type {\n CollectionAtPath,\n CollectionDefinition,\n CollectionDefinitions,\n CollectionPath,\n CollectionSet,\n} from \"@lsync/definitions\";\nimport { authorizeApiCall } from \"./access\";\nimport { collectionBuilder } from \"./collection-builder\";\nimport { defaultCollectionApiPath } from \"./collections\";\nimport type {\n CollectionShardLimits,\n CollectionShardOptions,\n RateLimitHandler,\n} from \"./durable-object-types\";\nimport { z } from \"zod\";\nimport type {\n AccessReferenceResolver,\n ApiAccessHandler,\n ApiHandler,\n CollectionAccessConfig,\n CollectionConfigs,\n ReadAccessHandler,\n} from \"./types\";\n\nexport function collectionShardOptionsFrom<TCollections extends CollectionDefinitions>(\n definitions: CollectionSet<TCollections>,\n): CollectionShardDefinitionBuilder<TCollections> {\n return new CollectionShardDefinitionBuilder(definitions.collections, {}, {});\n}\n\nexport class CollectionShardDefinitionBuilder<TCollections extends CollectionDefinitions> {\n constructor(\n private readonly definitions: TCollections,\n private readonly overrides: Record<string, ServerCollectionOverride>,\n private readonly options: Omit<CollectionShardOptions, \"collections\">,\n ) {}\n\n limits(limits: CollectionShardLimits): CollectionShardDefinitionBuilder<TCollections> {\n return new CollectionShardDefinitionBuilder(this.definitions, this.overrides, {\n ...this.options,\n limits,\n });\n }\n\n rateLimit(rateLimit: RateLimitHandler): CollectionShardDefinitionBuilder<TCollections> {\n return new CollectionShardDefinitionBuilder(this.definitions, this.overrides, {\n ...this.options,\n rateLimit,\n });\n }\n\n collection<TPath extends CollectionPath<TCollections>>(\n path: TPath,\n configure: (\n collection: ServerCollectionBuilder<CollectionAtPath<TCollections, TPath>>,\n ) => ServerCollectionBuilder<CollectionAtPath<TCollections, TPath>>,\n ): CollectionShardDefinitionBuilder<TCollections> {\n const override = configure(new ServerCollectionBuilder({})).toOverride();\n return new CollectionShardDefinitionBuilder(\n this.definitions,\n {\n ...this.overrides,\n [path]: override,\n },\n this.options,\n );\n }\n\n build(): CollectionShardOptions {\n const collections = {} as CollectionConfigs;\n\n for (const [name, definition] of Object.entries(this.definitions)) {\n addDefinition(collections, definition, name, this.overrides);\n }\n\n return { ...this.options, collections };\n }\n}\n\nexport class ServerCollectionBuilder<TDefinition> {\n constructor(private readonly override: ServerCollectionOverride) {}\n\n index(...fields: Array<string>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n indexes: [...(this.override.indexes ?? []), fields],\n });\n }\n\n initialData(data: Array<Record<string, unknown>>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({ ...this.override, initialData: data });\n }\n\n reference(name: string, resolver: AccessReferenceResolver): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n references: {\n ...this.override.references,\n [name]: resolver,\n },\n });\n }\n\n access(\n kind: ServerWriteAccessKind,\n handler: ReadAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition>;\n access(\n kind: `api.${string}`,\n handler: ApiAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition>;\n access(\n kind: ServerWriteAccessKind | `api.${string}`,\n handler: ReadAccessHandler<any> | ApiAccessHandler<any>,\n ): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n access: {\n ...this.override.access,\n [kind]: handler,\n },\n });\n }\n\n api(name: string, handler: ApiHandler<any, any>): ServerCollectionBuilder<TDefinition> {\n return new ServerCollectionBuilder({\n ...this.override,\n api: {\n ...this.override.api,\n [name]: handler,\n },\n });\n }\n\n toOverride(): ServerCollectionOverride {\n return this.override;\n }\n}\n\ntype ServerWriteAccessKind = \"read\" | \"write\" | \"insert\" | \"update\" | \"delete\";\n\ninterface ServerCollectionOverride {\n indexes?: Array<Array<string>>;\n initialData?: Array<Record<string, unknown>>;\n references?: Record<string, AccessReferenceResolver>;\n access?: Record<string, ReadAccessHandler<any> | ApiAccessHandler<any>>;\n api?: Record<string, ApiHandler<any, any>>;\n}\n\nfunction addDefinition(\n collections: CollectionConfigs,\n definition: CollectionDefinition,\n dotPath: string,\n overrides: Record<string, ServerCollectionOverride>,\n): void {\n const override = overrides[dotPath] ?? {};\n let builder = collectionBuilder()\n .path(definition.path)\n .schema(definition.schema as z.ZodTypeAny) as any;\n\n for (const fields of override.indexes ?? []) {\n builder = builder.index(fields);\n }\n\n if (override.initialData) {\n builder = builder.initialData(...override.initialData);\n }\n\n const access = accessConfig(override);\n if (access) {\n builder = builder.access(access);\n }\n\n for (const [name, handler] of Object.entries(override.api ?? {})) {\n const apiDefinition = definition.api[name];\n const apiAccess = override.access?.[`api.${name}`] as ApiAccessHandler | undefined;\n const apiPath = apiDefinition?.path ?? defaultCollectionApiPath(definition.path, name);\n const input = (apiDefinition?.input ?? z.undefined()) as z.ZodTypeAny;\n\n builder = builder.api(name, input, async (args: any) => {\n authorizeApiCall(apiAccess, apiPath, args.input, args.auth);\n return handler(args);\n });\n }\n\n Object.assign(collections, builder.build());\n\n for (const [name, child] of Object.entries(definition.children)) {\n addDefinition(collections, child, `${dotPath}.${name}`, overrides);\n }\n}\n\nfunction accessConfig(override: ServerCollectionOverride): CollectionAccessConfig | undefined {\n const access = override.access ?? {};\n const apiAccess = Object.fromEntries(\n Object.entries(access)\n .filter(([kind]) => kind.startsWith(\"api.\"))\n .map(([kind, handler]) => [kind.slice(\"api.\".length), handler]),\n );\n const config: CollectionAccessConfig = {};\n if (override.references) config.references = override.references;\n if (access.read) config.read = access.read as ReadAccessHandler;\n if (access.write) config.write = access.write as ReadAccessHandler;\n if (access.insert) config.insert = access.insert as ReadAccessHandler;\n if (access.update) config.update = access.update as ReadAccessHandler;\n if (access.delete) config.delete = access.delete as ReadAccessHandler;\n if (Object.keys(apiAccess).length > 0) {\n config.api = apiAccess as Record<string, ApiAccessHandler<any>>;\n }\n\n return Object.keys(config).length > 0 ? config : undefined;\n}\n","import type { ParsedClientMessage } from \"@lsync/transport\";\nimport type { Caller } from \"./router\";\nimport type { SyncChangesResult } from \"./types\";\n\nexport async function callRouter(caller: Caller, request: ParsedClientMessage): Promise<unknown> {\n switch (request.type) {\n case \"read\":\n return caller.read(request.input);\n case \"push\":\n return caller.push(request.input);\n case \"changes\":\n return caller.changes(request.input);\n case \"api\":\n return caller.api(request.input);\n case \"subscribe\":\n return caller.subscribe(request.input);\n case \"unsubscribe\":\n return caller.unsubscribe(request.input);\n }\n}\n\nexport function isResyncRequired(\n result: unknown,\n): result is Extract<SyncChangesResult, { type: \"resyncRequired\" }> {\n return (\n typeof result === \"object\" &&\n result !== null &&\n (result as { type?: unknown }).type === \"resyncRequired\"\n );\n}\n","import type { SqlStorageLike } from \"./storage\";\n\nconst COLLECTION_WATERMARKS_TABLE = \"_lsync_collection_watermarks\";\n\nexport function ensureCollectionWatermarkTable(sql: SqlStorageLike): void {\n sql.exec(`\n CREATE TABLE IF NOT EXISTS ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)} (\n scope TEXT PRIMARY KEY,\n collection TEXT NOT NULL,\n latest_sequence INTEGER NOT NULL\n )\n `);\n}\n\nexport function recordCollectionWatermark(\n sql: SqlStorageLike,\n collection: string,\n scope: string,\n sequence: number,\n): void {\n sql.exec(\n `\n INSERT INTO ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)}\n (scope, collection, latest_sequence)\n VALUES (?, ?, ?)\n ON CONFLICT(scope) DO UPDATE SET\n collection = excluded.collection,\n latest_sequence = excluded.latest_sequence\n `,\n scope,\n collection,\n sequence,\n );\n}\n\nexport function readCollectionWatermark(sql: SqlStorageLike, scope: string): number {\n const row = sql\n .exec<{ latest_sequence: number }>(\n `\n SELECT latest_sequence FROM ${quoteIdentifier(COLLECTION_WATERMARKS_TABLE)}\n WHERE scope = ?\n `,\n scope,\n )\n .toArray()[0];\n\n return row?.latest_sequence ?? 0;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll(`\"`, `\"\"`)}\"`;\n}\n","import type { Batch, SequencedUpdate } from \"./types\";\nimport type { SqlStorageLike } from \"./storage\";\n\nconst APPLIED_UPDATES_TABLE = \"_lsync_applied_updates\";\n\nexport function deduplicateMutations(sql: SqlStorageLike, batch: Batch): Batch {\n ensureAppliedUpdatesTable(sql);\n const seen = new Map<string, string>();\n return {\n updates: batch.updates.filter((update) => {\n const payload = JSON.stringify(update);\n const priorPayload = seen.get(update.id) ?? readAppliedPayload(sql, update.id);\n if (priorPayload === undefined) {\n seen.set(update.id, payload);\n return true;\n }\n if (priorPayload !== payload) {\n throw new Error(`Mutation id reused with a different payload: ${update.id}`);\n }\n return false;\n }),\n };\n}\n\nexport function recordAppliedMutations(sql: SqlStorageLike, updates: Array<SequencedUpdate>): void {\n for (const update of updates) {\n const { sequence, serverCreatedAt, ...original } = update;\n void serverCreatedAt;\n sql.exec(\n `INSERT INTO ${quoteIdentifier(APPLIED_UPDATES_TABLE)} (update_id, payload, sequence) VALUES (?, ?, ?)`,\n update.id,\n JSON.stringify(original),\n sequence,\n );\n }\n}\n\nfunction ensureAppliedUpdatesTable(sql: SqlStorageLike): void {\n sql.exec(`\n CREATE TABLE IF NOT EXISTS ${quoteIdentifier(APPLIED_UPDATES_TABLE)} (\n update_id TEXT PRIMARY KEY,\n payload TEXT NOT NULL,\n sequence INTEGER NOT NULL\n )\n `);\n}\n\nfunction readAppliedPayload(sql: SqlStorageLike, updateId: string): string | undefined {\n return sql\n .exec<{ payload: string }>(\n `SELECT payload FROM ${quoteIdentifier(APPLIED_UPDATES_TABLE)} WHERE update_id = ?`,\n updateId,\n )\n .toArray()[0]?.payload;\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll(`\"`, `\"\"`)}\"`;\n}\n","import type {\n Batch,\n CollectionConfigs,\n SequencedUpdate,\n SyncChangesQuery,\n SyncChangesResult,\n} from \"./types\";\nimport { collectionScope, resolveCollection } from \"./collections\";\nimport {\n ensureCollectionWatermarkTable,\n readCollectionWatermark,\n recordCollectionWatermark,\n} from \"./history-watermarks\";\nimport { applySQLiteJsonBatch, ensureSQLiteJsonTables, type SqlStorageLike } from \"./storage\";\nimport { deduplicateMutations, recordAppliedMutations } from \"./mutation-dedup\";\n\nconst CHANGES_TABLE = \"_lsync_changes\";\n\nexport const SQLITE_JSON_CONFLICT_POLICY = \"server-sequence-last-write-wins\" as const;\n\nexport interface HistoryOptions {\n maxChanges?: number;\n}\n\nexport interface SequencedBatch {\n updates: Array<SequencedUpdate>;\n watermark: number;\n}\n\nexport function persistSQLiteJsonBatchWithHistory(\n sql: SqlStorageLike,\n batch: Batch,\n collections: CollectionConfigs = {},\n options: HistoryOptions = {},\n): SequencedBatch {\n ensureSQLiteJsonTables(sql, collections);\n ensureChangesTable(sql);\n const pending = deduplicateMutations(sql, batch);\n if (pending.updates.length === 0) {\n return { updates: [], watermark: readWatermark(sql) };\n }\n\n applySQLiteJsonBatch(sql, pending, collections);\n\n const updates = pending.updates.map((update) => appendChange(sql, update, collections));\n recordAppliedMutations(sql, updates);\n const watermark = updates.at(-1)?.sequence ?? readWatermark(sql);\n pruneChanges(sql, watermark, options.maxChanges ?? 10000);\n\n return { updates, watermark };\n}\n\nexport function readSQLiteJsonChanges(\n sql: SqlStorageLike,\n query: SyncChangesQuery,\n collections: CollectionConfigs = {},\n): SyncChangesResult {\n ensureChangesTable(sql);\n\n const requested = Object.entries(query.collections).map(([collection, sequence]) => ({\n collection,\n sequence,\n scope: scopeForCollection(collection, collections),\n }));\n const watermark = readWatermark(sql);\n const staleCollections = requested.flatMap((item) =>\n isCursorStale(sql, item.scope, item.sequence) ? [item.collection] : [],\n );\n\n if (staleCollections.length > 0) {\n return {\n type: \"resyncRequired\",\n collections: staleCollections,\n watermark,\n };\n }\n\n if (requested.length === 0) {\n return {\n type: \"changes\",\n updates: [],\n watermark,\n hasMore: false,\n };\n }\n\n const limit = query.limit ?? 1000;\n const rows = selectChanges(sql, requested, limit + 1);\n const page = rows.slice(0, limit);\n const cursors = Object.fromEntries(requested.map((item) => [item.collection, item.sequence]));\n for (const row of page) {\n const item = requested.find((candidate) => candidate.scope === row.scope);\n if (item) cursors[item.collection] = row.sequence;\n }\n if (rows.length <= limit) {\n for (const item of requested) cursors[item.collection] = watermark;\n }\n\n return {\n type: \"changes\",\n updates: page.map(rowToUpdate),\n watermark,\n hasMore: rows.length > limit,\n cursors,\n };\n}\n\nfunction ensureChangesTable(sql: SqlStorageLike): void {\n sql.exec(`\n CREATE TABLE IF NOT EXISTS ${quoteIdentifier(CHANGES_TABLE)} (\n sequence INTEGER PRIMARY KEY AUTOINCREMENT,\n update_id TEXT NOT NULL,\n collection TEXT NOT NULL,\n scope TEXT NOT NULL,\n \"key\" TEXT NOT NULL,\n type TEXT NOT NULL,\n value TEXT,\n previous_value TEXT,\n client_id TEXT,\n client_created_at INTEGER NOT NULL,\n server_created_at TEXT NOT NULL\n )\n `);\n sql.exec(`\n CREATE INDEX IF NOT EXISTS ${quoteIdentifier(`${CHANGES_TABLE}_scope_sequence_idx`)}\n ON ${quoteIdentifier(CHANGES_TABLE)} (scope, sequence)\n `);\n ensureCollectionWatermarkTable(sql);\n}\n\nfunction appendChange(\n sql: SqlStorageLike,\n update: Batch[\"updates\"][number],\n collections: CollectionConfigs,\n): SequencedUpdate {\n const serverCreatedAt = new Date().toISOString();\n const scope = scopeForCollection(update.collection, collections);\n const row = sql\n .exec<{ sequence: number }>(\n `\n INSERT INTO ${quoteIdentifier(CHANGES_TABLE)}\n (update_id, collection, scope, \"key\", type, value, previous_value, client_id,\n client_created_at, server_created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n RETURNING sequence\n `,\n update.id,\n update.collection,\n scope,\n JSON.stringify(update.key),\n update.type,\n update.value === undefined ? null : JSON.stringify(update.value),\n update.previousValue === undefined ? null : JSON.stringify(update.previousValue),\n update.clientId ?? null,\n update.createdAt,\n serverCreatedAt,\n )\n .toArray()[0];\n\n if (!row) {\n throw new Error(\"Unable to append sync history row\");\n }\n\n recordCollectionWatermark(sql, update.collection, scope, row.sequence);\n\n return {\n ...update,\n sequence: row.sequence,\n serverCreatedAt,\n };\n}\n\nfunction selectChanges(\n sql: SqlStorageLike,\n requested: Array<{ scope: string; sequence: number }>,\n limit: number,\n): Array<ChangeRow> {\n const bindings = requested.flatMap((item) => [item.scope, item.sequence]);\n bindings.push(limit);\n\n return sql\n .exec<ChangeRow>(\n `\n SELECT sequence, update_id, collection, scope, \"key\", type, value, previous_value, client_id,\n client_created_at, server_created_at\n FROM ${quoteIdentifier(CHANGES_TABLE)}\n WHERE ${requested.map(() => \"(scope = ? AND sequence > ?)\").join(\" OR \")}\n ORDER BY sequence\n LIMIT ?\n `,\n ...bindings,\n )\n .toArray();\n}\n\nfunction rowToUpdate(row: ChangeRow): SequencedUpdate {\n const update: SequencedUpdate = {\n id: row.update_id,\n collection: row.collection,\n key: JSON.parse(row.key) as string | number,\n type: row.type,\n createdAt: row.client_created_at,\n sequence: row.sequence,\n serverCreatedAt: row.server_created_at,\n };\n\n if (row.value !== null) {\n update.value = JSON.parse(row.value);\n }\n\n if (row.previous_value !== null) {\n update.previousValue = JSON.parse(row.previous_value);\n }\n\n if (row.client_id !== null) {\n update.clientId = row.client_id;\n }\n\n return update;\n}\n\nfunction isCursorStale(sql: SqlStorageLike, scope: string, sequence: number): boolean {\n const latest = readCollectionWatermark(sql, scope);\n if (latest === 0) {\n return false;\n }\n\n const row = sql\n .exec<{ sequence: number | null }>(\n `SELECT MIN(sequence) as sequence FROM ${quoteIdentifier(CHANGES_TABLE)} WHERE scope = ?`,\n scope,\n )\n .toArray()[0];\n const oldest = row?.sequence;\n\n if (oldest === null || oldest === undefined) {\n return sequence < latest;\n }\n\n return sequence < oldest - 1;\n}\n\nfunction readWatermark(sql: SqlStorageLike): number {\n const row = sql\n .exec<{ watermark: number }>(\n `SELECT COALESCE(MAX(sequence), 0) as watermark FROM ${quoteIdentifier(CHANGES_TABLE)}`,\n )\n .toArray()[0];\n\n return row?.watermark ?? 0;\n}\n\nfunction pruneChanges(sql: SqlStorageLike, watermark: number, maxChanges: number): void {\n if (!Number.isFinite(maxChanges) || maxChanges < 0) {\n return;\n }\n\n sql.exec(\n `DELETE FROM ${quoteIdentifier(CHANGES_TABLE)} WHERE sequence <= ?`,\n watermark - maxChanges,\n );\n}\n\nfunction scopeForCollection(collection: string, collections: CollectionConfigs): string {\n const resolved = resolveCollection(collection, collections);\n if (resolved) {\n return resolved.scope;\n }\n\n if (Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return collectionScope(collection);\n}\n\nfunction quoteIdentifier(identifier: string): string {\n return `\"${identifier.replaceAll(`\"`, `\"\"`)}\"`;\n}\n\ninterface ChangeRow extends Record<string, string | number | null> {\n sequence: number;\n update_id: string;\n collection: string;\n scope: string;\n key: string;\n type: SequencedUpdate[\"type\"];\n value: string | null;\n previous_value: string | null;\n client_id: string | null;\n client_created_at: number;\n server_created_at: string;\n}\n","import {\n ProtocolError,\n protocolErrorCodeSchema,\n sendServerMessage,\n type ProtocolErrorPayload,\n type RequestId,\n} from \"@lsync/transport\";\nimport { z } from \"zod\";\n\nexport function sendResult(ws: WebSocket, id: RequestId, payload: unknown): void {\n sendServerMessage(ws, {\n version: 1,\n id,\n type: \"result\",\n payload,\n });\n}\n\nexport function sendProtocolError(ws: WebSocket, id: RequestId | null, error: unknown): void {\n sendServerMessage(ws, {\n version: 1,\n id,\n type: \"error\",\n error: protocolErrorFrom(error),\n });\n}\n\nfunction protocolErrorFrom(error: unknown): ProtocolErrorPayload {\n if (error instanceof ProtocolError) {\n return {\n code: error.code,\n message: error.message,\n ...(error.details !== undefined ? { details: error.details } : {}),\n };\n }\n\n if (error instanceof z.ZodError) {\n return {\n code: \"VALIDATION_FAILED\",\n message: \"The request failed validation\",\n details: error.issues,\n };\n }\n\n const message = error instanceof Error ? error.message : \"Unknown protocol error\";\n if (message.toLowerCase().includes(\"access denied\")) {\n return { code: \"AUTH_DENIED\", message };\n }\n if (message.toLowerCase().includes(\"unknown collection\")) {\n return { code: \"VALIDATION_FAILED\", message };\n }\n if (message.toLowerCase().includes(\"maximum subscriptions\")) {\n return { code: \"CONFLICT\", message };\n }\n if (message.toLowerCase().includes(\"rate limit\")) {\n return { code: \"RATE_LIMITED\", message };\n }\n if (message.toLowerCase().includes(\"unknown api path\")) {\n return { code: \"NOT_FOUND\", message };\n }\n\n const candidate = asRecord(error);\n const code = protocolErrorCodeSchema.safeParse(candidate?.code);\n if (code.success) {\n return {\n code: code.data,\n message,\n ...(candidate?.details !== undefined ? { details: candidate.details } : {}),\n };\n }\n\n return { code: \"INTERNAL_ERROR\", message };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n","import {\n type AccessAuth,\n type CollectionSubscriptionResult,\n type WebSocketAttachment,\n webSocketAttachmentSchema,\n} from \"./types\";\n\nexport function webSocketAttachment(ws: WebSocket): WebSocketAttachment | undefined {\n const result = webSocketAttachmentSchema.safeParse(ws.deserializeAttachment());\n return result.success ? result.data : undefined;\n}\n\nexport function webSocketAuth(ws: WebSocket): AccessAuth {\n const attachment = webSocketAttachment(ws);\n if (!attachment) return {};\n\n return {\n clientId: attachment.clientId,\n ...attachment.auth,\n };\n}\n\nexport function updateSocketSubscriptions(\n ws: WebSocket,\n collection: string,\n normalize: (collection: string) => string,\n update: (subscriptions: Set<string>, collection: string) => void,\n): CollectionSubscriptionResult {\n const attachment = webSocketAttachment(ws);\n if (!attachment) {\n throw new Error(\"Missing WebSocket attachment\");\n }\n\n const normalized = normalize(collection);\n const subscriptions = new Set(attachment.subscriptions);\n update(subscriptions, normalized);\n const next = [...subscriptions];\n ws.serializeAttachment({\n ...attachment,\n subscriptions: next,\n } satisfies WebSocketAttachment);\n\n return {\n collection: normalized,\n subscriptions: next,\n };\n}\n","import type {\n CollectionShardLimits,\n Env,\n RateLimitContext,\n RateLimitHandler,\n} from \"./durable-object-types\";\nimport { webSocketAttachment, webSocketAuth } from \"./socket-attachment\";\n\nexport const DEFAULT_MAX_SUBSCRIPTIONS_PER_WEBSOCKET = 100;\n\nexport function assertSubscriptionAllowed(\n ws: WebSocket,\n collection: string,\n limits: CollectionShardLimits | undefined,\n): void {\n const attachment = webSocketAttachment(ws);\n if (!attachment) {\n throw new Error(\"Missing WebSocket attachment\");\n }\n\n const maximum = limits?.maxSubscriptionsPerWebSocket ?? DEFAULT_MAX_SUBSCRIPTIONS_PER_WEBSOCKET;\n if (maximum === false || attachment.subscriptions.includes(collection)) return;\n assertPositiveInteger(maximum, \"maxSubscriptionsPerWebSocket\");\n\n if (attachment.subscriptions.length >= maximum) {\n throw new Error(`Maximum subscriptions per WebSocket exceeded (${maximum})`);\n }\n}\n\nexport async function enforceRateLimit(\n ws: WebSocket,\n env: Env,\n rateLimit: RateLimitHandler | undefined,\n): Promise<void> {\n if (!rateLimit) return;\n\n const attachment = webSocketAttachment(ws);\n const allowed = await rateLimit({\n auth: webSocketAuth(ws),\n clientId: attachment?.clientId ?? \"unknown\",\n env,\n });\n if (!allowed) throw new Error(\"Rate limit exceeded\");\n}\n\nexport interface CloudflareRateLimiterOptions {\n binding?: string;\n key?: (context: RateLimitContext) => string;\n}\n\ninterface CloudflareRateLimitBinding {\n limit(options: { key: string }): Promise<{ success: boolean }>;\n}\n\nexport function cloudflareRateLimiter(\n options: CloudflareRateLimiterOptions = {},\n): RateLimitHandler {\n const bindingName = options.binding ?? \"RATE_LIMITER\";\n\n return async (context) => {\n const binding = (context.env as Env & Record<string, unknown>)[bindingName] as\n | CloudflareRateLimitBinding\n | undefined;\n if (!binding?.limit) {\n throw new Error(`Missing Cloudflare rate limit binding: ${bindingName}`);\n }\n\n const key = options.key?.(context) ?? context.clientId;\n return (await binding.limit({ key })).success;\n };\n}\n\nfunction assertPositiveInteger(value: number, name: string): void {\n if (!Number.isInteger(value) || value <= 0) {\n throw new Error(`${name} must be a positive integer or false`);\n }\n}\n","import { collectionScope } from \"./collections\";\nimport type { Batch } from \"./types\";\nimport type { ReferenceDependency } from \"./access-expression\";\n\nexport function invalidatesDependency(\n update: Batch[\"updates\"][number],\n dependencies: Array<ReferenceDependency>,\n): boolean {\n return dependencies.some((dependency) => {\n if (collectionScope(update.collection) !== collectionScope(dependency.collection)) return false;\n if (String(update.key) !== String(dependency.key)) return false;\n return fieldChanged(update.previousValue, update.value, dependency.field);\n });\n}\n\nfunction fieldChanged(previous: unknown, next: unknown, field: string): boolean {\n if (!previous || !next) return true;\n return valueAtPath(previous, field) !== valueAtPath(next, field);\n}\n\nfunction valueAtPath(value: unknown, field: string): unknown {\n return field.split(\".\").reduce<unknown>((current, segment) => {\n if (typeof current !== \"object\" || current === null) return undefined;\n return (current as Record<string, unknown>)[segment];\n }, value);\n}\n","import { readAccessDecision, type AccessStore } from \"./access\";\nimport { invalidatesDependency } from \"./access-invalidation\";\nimport type { AccessAuth, Batch, CollectionConfigs, CollectionInvalidation } from \"./types\";\n\nexport function subscribedInvalidations(\n subscriptions: Array<string>,\n batch: Batch,\n collections: CollectionConfigs | undefined,\n auth: AccessAuth,\n store: AccessStore,\n): Array<CollectionInvalidation> {\n const invalidations = new Set<string>();\n for (const collection of subscriptions) {\n const decision = readAccessDecision(collection, collections, auth, store);\n if (decision.dependencies.length === 0) continue;\n\n if (batch.updates.some((update) => invalidatesDependency(update, decision.dependencies))) {\n invalidations.add(collection);\n }\n }\n\n return [...invalidations].map((collection) => ({ collection }));\n}\n","import { z } from \"zod\";\nimport { resolveCollection } from \"./collections\";\nimport type { Batch, CollectionConfigs } from \"./types\";\n\nexport function validateBatch(batch: Batch, collections?: CollectionConfigs): void {\n for (const update of batch.updates) {\n const schema = schemaFor(update.collection, collections);\n\n if (!schema || update.type === \"delete\") {\n continue;\n }\n\n if (update.type === \"update\" && schema instanceof z.ZodObject) {\n schema.partial().parse(update.value);\n continue;\n }\n\n schema.parse(update.value);\n }\n}\n\nfunction schemaFor(collection: string, collections?: CollectionConfigs): z.ZodTypeAny | undefined {\n const configured = resolveCollection(collection, collections);\n\n if (!configured) {\n if (collections && Object.keys(collections).length > 0) {\n throw new Error(`Unknown collection: ${collection}`);\n }\n\n return undefined;\n }\n\n return configured.collection.schema;\n}\n","import { parseClientMessage, readMessageId, sendServerMessage } from \"@lsync/transport\";\nimport {\n authorizeReadQuery,\n authorizeWriteBatch,\n visibleUpdateForAuth,\n type AccessStore,\n} from \"./access\";\nimport { normalizeCollection } from \"./collection-normalize\";\nimport { collectionApiHandlers } from \"./collections\";\nimport { collectionShardOptionsFrom } from \"./definition-builder\";\nimport { callRouter, isResyncRequired } from \"./durable-object-rpc\";\nimport type { CollectionShardOptions, Env } from \"./durable-object-types\";\nimport { persistSQLiteJsonBatchWithHistory, readSQLiteJsonChanges } from \"./history\";\nimport { sendProtocolError, sendResult } from \"./messages\";\nimport { deduplicateMutations } from \"./mutation-dedup\";\nimport { router } from \"./router\";\nimport { assertSubscriptionAllowed, enforceRateLimit } from \"./safeguards\";\nimport { updateSocketSubscriptions, webSocketAttachment, webSocketAuth } from \"./socket-attachment\";\nimport { readSQLiteJsonRow, readSQLiteJsonRows } from \"./storage\";\nimport { subscribedInvalidations } from \"./subscription-invalidation\";\nimport {\n type AccessAuth,\n type ApiCall,\n type ApiHandler,\n type ApiHandlerArgs,\n type Batch,\n type Broadcast,\n type CollectionSubscription,\n type CollectionSubscriptionResult,\n type PushResult,\n type ReadQuery,\n type ReadResult,\n type SequencedBatch,\n type SyncChangesQuery,\n type SyncChangesResult,\n type WebSocketAttachment,\n} from \"./types\";\nimport { validateBatch } from \"./validation\";\n\nexport type { CollectionShardOptions, Env } from \"./durable-object-types\";\n\nexport class CollectionShardDurableObject implements DurableObject {\n static from = collectionShardOptionsFrom;\n\n private readonly apiHandlers: Record<string, ApiHandler>;\n\n constructor(\n private readonly state: DurableObjectState,\n private readonly env: Env,\n private readonly options: CollectionShardOptions = {},\n ) {\n this.apiHandlers = collectionApiHandlers(options.collections);\n }\n\n async fetch(request: Request): Promise<Response> {\n if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n return new Response(\"Expected WebSocket upgrade\", { status: 426 });\n }\n\n const pair = new WebSocketPair();\n const client = pair[0];\n const server = pair[1];\n\n const url = new URL(request.url);\n const clientId = url.searchParams.get(\"clientId\") ?? crypto.randomUUID();\n const auth = (await this.options.authenticate?.({ clientId, request })) ?? { clientId };\n\n this.state.acceptWebSocket(server);\n server.serializeAttachment({\n clientId,\n connectedAt: Date.now(),\n auth,\n subscriptions: [],\n } satisfies WebSocketAttachment);\n\n return new Response(null, { status: 101, webSocket: client });\n }\n\n async webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void> {\n try {\n await enforceRateLimit(ws, this.env, this.options.rateLimit);\n const request = parseClientMessage(message);\n\n const caller = router.createCaller({\n shardId: this.shardId(),\n validate: (input) => this.validate(input),\n persist: (input) => this.persist(input),\n publish: (input) => this.publish(input),\n mutate: (input) => this.mutate(input, webSocketAuth(ws)),\n subscribe: (input) => this.subscribe(ws, input),\n unsubscribe: (input) => this.unsubscribe(ws, input),\n read: (input) => this.read(input, webSocketAuth(ws)),\n changes: (input) => this.readChanges(input, webSocketAuth(ws)),\n callApi: (input) => this.callApi(ws, input),\n });\n\n const result = await callRouter(caller, request);\n if (request.type === \"changes\" && isResyncRequired(result)) {\n sendProtocolError(ws, request.id, {\n code: \"RESYNC_REQUIRED\",\n message: \"The requested change history is no longer available\",\n details: result,\n });\n return;\n }\n\n sendResult(ws, request.id, result);\n } catch (error) {\n sendProtocolError(ws, readMessageId(message), error);\n }\n }\n\n private publish(batch: SequencedBatch): void {\n const payload: Broadcast = {\n type: \"updates\",\n shardId: this.shardId(),\n updates: batch.updates,\n watermark: batch.watermark,\n };\n\n for (const socket of this.state.getWebSockets()) {\n const updates = this.subscribedUpdates(socket, batch);\n const attachment = webSocketAttachment(socket);\n const invalidations = attachment\n ? subscribedInvalidations(\n attachment.subscriptions,\n batch,\n this.options.collections,\n webSocketAuth(socket),\n this.accessStore(),\n )\n : [];\n if (updates.length === 0 && invalidations.length === 0) continue;\n\n sendServerMessage(socket, {\n version: 1,\n type: \"updates\",\n payload: {\n ...payload,\n ...(invalidations.length > 0 ? { invalidations } : {}),\n updates,\n },\n });\n }\n }\n\n protected validate(batch: Batch): void {\n validateBatch(batch, this.options.collections);\n }\n\n protected persist(batch: Batch): SequencedBatch {\n return this.state.storage.transactionSync(() =>\n persistSQLiteJsonBatchWithHistory(\n this.state.storage.sql,\n batch,\n this.options.collections,\n this.options.history,\n ),\n );\n }\n\n protected read(query: ReadQuery, auth: AccessAuth = {}): ReadResult {\n const authorized = authorizeReadQuery(\n query,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return authorized\n ? readSQLiteJsonRows(this.state.storage.sql, authorized, this.options.collections)\n : { rows: [] };\n }\n\n protected readChanges(query: SyncChangesQuery, auth: AccessAuth = {}): SyncChangesResult {\n const result = readSQLiteJsonChanges(this.state.storage.sql, query, this.options.collections);\n if (result.type === \"resyncRequired\") return result;\n\n return {\n ...result,\n updates: result.updates.flatMap((update) => {\n const visible = visibleUpdateForAuth(\n update,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return visible\n ? [{ ...visible, sequence: update.sequence, serverCreatedAt: update.serverCreatedAt }]\n : [];\n }),\n };\n }\n\n private subscribe(ws: WebSocket, input: CollectionSubscription): CollectionSubscriptionResult {\n assertSubscriptionAllowed(\n ws,\n normalizeCollection(input.collection, this.options.collections),\n this.options.limits,\n );\n return this.updateSubscriptions(ws, input.collection, (subscriptions, collection) => {\n subscriptions.add(collection);\n });\n }\n\n private unsubscribe(ws: WebSocket, input: CollectionSubscription): CollectionSubscriptionResult {\n return this.updateSubscriptions(ws, input.collection, (subscriptions, collection) => {\n subscriptions.delete(collection);\n });\n }\n\n private async callApi(ws: WebSocket, call: ApiCall): Promise<unknown> {\n const handler = this.apiHandlers[call.path];\n\n if (!handler) {\n throw new Error(`Unknown API path: ${call.path}`);\n }\n\n const clientId = this.clientId(ws);\n const auth = webSocketAuth(ws);\n const args: ApiHandlerArgs = {\n shardId: this.shardId(),\n input: call.input,\n auth,\n validate: (input) => this.validate(input),\n persist: (input) => this.persist(input),\n publish: (input) => this.publish(input),\n subscribe: (input) => this.subscribe(ws, input),\n unsubscribe: (input) => this.unsubscribe(ws, input),\n mutate: (input) => this.mutate(input, auth),\n read: (input) => this.read(input, auth),\n changes: (input) => this.readChanges(input, auth),\n };\n\n if (clientId) args.clientId = clientId;\n return handler(args);\n }\n\n private mutate(batch: Batch, auth: AccessAuth = {}): PushResult {\n const pending = deduplicateMutations(this.state.storage.sql, batch);\n this.validate(pending);\n authorizeWriteBatch(pending, this.options.collections, auth, this.accessStore());\n const persisted = this.persist(batch);\n this.publish(persisted);\n return { accepted: batch.updates.length, watermark: persisted.watermark };\n }\n\n private clientId(ws: WebSocket): string | undefined {\n return webSocketAttachment(ws)?.clientId;\n }\n\n private updateSubscriptions(\n ws: WebSocket,\n collection: string,\n update: (subscriptions: Set<string>, collection: string) => void,\n ): CollectionSubscriptionResult {\n return updateSocketSubscriptions(\n ws,\n collection,\n (input) => normalizeCollection(input, this.options.collections),\n update,\n );\n }\n\n private subscribedUpdates(ws: WebSocket, batch: SequencedBatch): SequencedBatch[\"updates\"] {\n const attachment = webSocketAttachment(ws);\n if (!attachment || attachment.subscriptions.length === 0) return [];\n\n const subscriptions = new Set(attachment.subscriptions);\n const auth = webSocketAuth(ws);\n return batch.updates.flatMap((update) => {\n if (!subscriptions.has(normalizeCollection(update.collection, this.options.collections))) {\n return [];\n }\n\n const visible = visibleUpdateForAuth(\n update,\n this.options.collections,\n auth,\n this.accessStore(),\n );\n return visible\n ? [{ ...visible, sequence: update.sequence, serverCreatedAt: update.serverCreatedAt }]\n : [];\n });\n }\n\n private accessStore(): AccessStore {\n return {\n read: (collection, key) =>\n readSQLiteJsonRow(this.state.storage.sql, collection, key, this.options.collections),\n };\n }\n\n private shardId(): string {\n return this.state.id.toString();\n }\n}\n","import type { Env } from \"./durable-object\";\n\nexport interface WorkerOptions {\n binding?: keyof Env;\n routePattern?: RegExp;\n}\n\nexport function createWorkerHandler(options: WorkerOptions = {}) {\n const binding = options.binding ?? \"SYNC_SHARDS\";\n const routePattern = options.routePattern ?? /^\\/sync\\/([^/]+)$/;\n\n return {\n fetch(request: Request, env: Env): Promise<Response> | Response {\n const url = new URL(request.url);\n const match = url.pathname.match(routePattern);\n\n if (!match?.[1]) {\n return new Response(\"Not found\", { status: 404 });\n }\n\n const namespace = env[binding] as DurableObjectNamespace | undefined;\n if (!namespace) {\n return new Response(`Missing Durable Object binding: ${String(binding)}`, { status: 500 });\n }\n\n const id = namespace.idFromName(decodeURIComponent(match[1]));\n const stub = namespace.get(id);\n return stub.fetch(request);\n },\n };\n}\n"],"mappings":"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"}
|