@fragno-dev/lofi 0.0.1 → 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.
Files changed (49) hide show
  1. package/dist/adapters/in-memory/adapter.d.ts.map +1 -1
  2. package/dist/adapters/in-memory/adapter.js.map +1 -1
  3. package/dist/adapters/in-memory/query.js +1 -2
  4. package/dist/adapters/in-memory/query.js.map +1 -1
  5. package/dist/adapters/in-memory/store.d.ts.map +1 -1
  6. package/dist/adapters/in-memory/store.js +1 -1
  7. package/dist/adapters/in-memory/store.js.map +1 -1
  8. package/dist/adapters/stacked/adapter.d.ts.map +1 -1
  9. package/dist/adapters/stacked/adapter.js.map +1 -1
  10. package/dist/adapters/stacked/merge.js.map +1 -1
  11. package/dist/cli/client.js +1 -1
  12. package/dist/cli/client.js.map +1 -1
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +2 -2
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/scenario.js +1 -1
  17. package/dist/cli/scenario.js.map +1 -1
  18. package/dist/cli/server.js +1 -1
  19. package/dist/cli/server.js.map +1 -1
  20. package/dist/client/client.d.ts.map +1 -1
  21. package/dist/client/client.js.map +1 -1
  22. package/dist/indexeddb/adapter.d.ts.map +1 -1
  23. package/dist/indexeddb/adapter.js +1 -1
  24. package/dist/indexeddb/adapter.js.map +1 -1
  25. package/dist/optimistic/overlay-manager.d.ts.map +1 -1
  26. package/dist/optimistic/overlay-manager.js +0 -1
  27. package/dist/optimistic/overlay-manager.js.map +1 -1
  28. package/dist/outbox/decode.d.ts.map +1 -1
  29. package/dist/outbox/decode.js.map +1 -1
  30. package/dist/outbox/uow.d.ts.map +1 -1
  31. package/dist/outbox/uow.js.map +1 -1
  32. package/dist/query/conditions.d.ts +2 -1
  33. package/dist/query/conditions.d.ts.map +1 -1
  34. package/dist/query/conditions.js +2 -1
  35. package/dist/query/conditions.js.map +1 -1
  36. package/dist/query/engine.d.ts.map +1 -1
  37. package/dist/query/engine.js +1 -1
  38. package/dist/query/engine.js.map +1 -1
  39. package/dist/scenario.d.ts.map +1 -1
  40. package/dist/scenario.js.map +1 -1
  41. package/dist/submit/client.d.ts.map +1 -1
  42. package/dist/submit/client.js.map +1 -1
  43. package/dist/submit/local-handler-tx.d.ts.map +1 -1
  44. package/dist/submit/local-handler-tx.js.map +1 -1
  45. package/dist/submit/queue.js.map +1 -1
  46. package/dist/submit/rebase.d.ts.map +1 -1
  47. package/dist/submit/rebase.js.map +1 -1
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +23 -26
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","names":["selected: RowSelection","prefixed: RowSelection","output: Record<string, unknown>","columnValues: Record<string, unknown>","relationData: Record<string, Record<string, unknown>>","key: LofiRow[\"key\"]","exhaustiveCheck: never","matches","results: LofiRow[]","source: ReadIndex<TxStores, StoreName, string>","matches: LofiRow[]","outputs: RowSelection[]","nextOutputs: RowSelection[]","filtered: LofiRow[]","results: RowSelection[]","resultSources: LofiRow[]","cursor: Cursor | undefined","cursorRecord: Record<string, unknown>","context: IndexedDbQueryContext"],"sources":["../../src/query/engine.ts"],"sourcesContent":["import type { AnyColumn, AnySchema, AnyTable } from \"@fragno-dev/db/schema\";\nimport { Column, FragnoId, FragnoReference } from \"@fragno-dev/db/schema\";\nimport type { CursorResult } from \"@fragno-dev/db/cursor\";\nimport { Cursor, createCursorFromRecord, decodeCursor } from \"@fragno-dev/db/cursor\";\nimport { FindBuilder } from \"@fragno-dev/db/unit-of-work\";\nimport type { IDBPDatabase, IDBPIndex, IDBPObjectStore } from \"idb\";\nimport type { LofiQueryInterface } from \"../types\";\nimport type { ReferenceTarget } from \"../indexeddb/types\";\nimport { normalizeValue } from \"./normalize\";\nimport { buildCondition, type Condition, type ConditionBuilder } from \"./conditions\";\n\nconst ROWS_STORE = \"lofi_rows\";\nconst INDEX_SCHEMA_TABLE = \"idx_schema_table\";\n\ntype LofiRow = {\n key: [string, string, string, string];\n endpoint: string;\n schema: string;\n table: string;\n id: string;\n data: Record<string, unknown>;\n _lofi: {\n versionstamp: string;\n norm: Record<string, unknown>;\n internalId: number;\n version: number;\n };\n};\n\ntype LofiDb = IDBPDatabase<unknown>;\ntype ReadStore<TxStores extends ArrayLike<string>, StoreName extends string> = IDBPObjectStore<\n unknown,\n TxStores,\n StoreName,\n \"readonly\"\n>;\ntype ReadIndex<\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n IndexName extends string,\n> = IDBPIndex<unknown, TxStores, StoreName, IndexName, \"readonly\">;\n\ntype RowSelection = Record<string, unknown>;\n\nexport type IndexedDbQueryContext = {\n endpointName: string;\n schemaName: string;\n getDb: () => Promise<LofiDb>;\n referenceTargets: Map<string, ReferenceTarget>;\n};\n\ntype QueryContext = IndexedDbQueryContext;\n\ntype CompiledJoin = {\n relation: { name: string; table: AnyTable; on: [string, string][] };\n options:\n | {\n select: unknown;\n where?: Condition;\n orderBy?: [AnyColumn, \"asc\" | \"desc\"][];\n join?: CompiledJoin[];\n limit?: number;\n }\n | false;\n};\n\nconst isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined;\n\nconst toByteArray = (value: unknown): Uint8Array | null => {\n if (value instanceof Uint8Array) {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n if (ArrayBuffer.isView(value)) {\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n }\n return null;\n};\n\nconst compareByteArrays = (left: Uint8Array, right: Uint8Array): number => {\n const minLength = Math.min(left.length, right.length);\n for (let i = 0; i < minLength; i += 1) {\n const diff = left[i]! - right[i]!;\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n }\n if (left.length === right.length) {\n return 0;\n }\n return left.length < right.length ? -1 : 1;\n};\n\nconst bytesToHex = (bytes: Uint8Array): string => {\n let hex = \"\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n};\n\nconst compareNormalizedValues = (left: unknown, right: unknown): number => {\n if (left === right) {\n return 0;\n }\n if (left === undefined) {\n return -1;\n }\n if (right === undefined) {\n return 1;\n }\n if (left === null) {\n return -1;\n }\n if (right === null) {\n return 1;\n }\n const leftBytes = toByteArray(left);\n const rightBytes = toByteArray(right);\n if (leftBytes && rightBytes) {\n return compareByteArrays(leftBytes, rightBytes);\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() - right.getTime();\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n if (typeof left === \"bigint\" && typeof right === \"bigint\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"string\" && typeof right === \"string\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"boolean\" && typeof right === \"boolean\") {\n return left === right ? 0 : left ? 1 : -1;\n }\n const leftString = String(left);\n const rightString = String(right);\n return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;\n};\n\nconst buildIndexName = (schemaName: string, tableName: string, indexName: string): string =>\n `idx__${schemaName}__${tableName}__${indexName}`;\n\ntype DbNow = { tag: \"db-now\" };\n\nconst isDbNow = (value: unknown): value is DbNow =>\n typeof value === \"object\" && value !== null && (value as { tag?: string }).tag === \"db-now\";\n\nconst resolveFragnoIdValue = (value: unknown, col: AnyColumn): unknown => {\n if (value instanceof FragnoReference) {\n return value.internalId;\n }\n\n if (value instanceof FragnoId) {\n if (col.role === \"external-id\") {\n return value.externalId;\n }\n if (col.role === \"internal-id\") {\n if (value.internalId === undefined) {\n throw new Error(`FragnoId must have internalId for internal-id column ${col.name}`);\n }\n return value.internalId;\n }\n if (col.role === \"reference\") {\n return value.databaseId;\n }\n return value.externalId;\n }\n\n return value;\n};\n\nconst buildSelection = (\n table: AnyTable,\n select: undefined | true | readonly string[],\n): Set<string> => {\n const selection = new Set<string>();\n\n if (!select || select === true) {\n for (const columnName of Object.keys(table.columns)) {\n selection.add(columnName);\n }\n } else {\n for (const columnName of select) {\n selection.add(columnName);\n }\n }\n\n selection.add(\"_internalId\");\n selection.add(\"_version\");\n\n return selection;\n};\n\nconst getColumnValue = (row: LofiRow, columnName: string, column: AnyColumn): unknown => {\n if (column.role === \"external-id\") {\n return row.id;\n }\n if (column.role === \"internal-id\") {\n return row._lofi.internalId;\n }\n if (column.role === \"version\") {\n return row._lofi.version;\n }\n\n return row.data[columnName];\n};\n\nconst selectRow = (\n row: LofiRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n): RowSelection => {\n const selection = buildSelection(table, select);\n const selected: RowSelection = {};\n\n for (const columnName of selection) {\n if (columnName === \"_internalId\") {\n selected[columnName] = row._lofi.internalId;\n continue;\n }\n if (columnName === \"_version\") {\n selected[columnName] = row._lofi.version;\n continue;\n }\n\n const column = table.columns[columnName];\n if (!column) {\n continue;\n }\n\n if (column.role === \"reference\") {\n selected[columnName] = row._lofi.norm[columnName];\n continue;\n }\n\n selected[columnName] = getColumnValue(row, columnName, column);\n }\n\n return selected;\n};\n\nconst prefixSelection = (\n row: LofiRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n prefix: string,\n): RowSelection => {\n const selected = selectRow(row, table, select);\n const prefixed: RowSelection = {};\n\n for (const key in selected) {\n prefixed[`${prefix}:${key}`] = selected[key];\n }\n\n return prefixed;\n};\n\nconst buildOutputValueForColumn = (row: LofiRow, column: AnyColumn): unknown => {\n if (column.isHidden) {\n return undefined;\n }\n\n if (column.role === \"external-id\") {\n return new FragnoId({\n externalId: row.id,\n internalId: BigInt(row._lofi.internalId),\n version: row._lofi.version,\n });\n }\n\n if (column.role === \"reference\") {\n const value = row._lofi.norm[column.name];\n return value === null || value === undefined\n ? null\n : FragnoReference.fromInternal(BigInt(value as number));\n }\n\n if (column.role === \"internal-id\") {\n return BigInt(row._lofi.internalId);\n }\n\n if (column.role === \"version\") {\n return row._lofi.version;\n }\n\n return row.data[column.name];\n};\n\nconst decodeRow = (row: RowSelection, table: AnyTable): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n const columnValues: Record<string, unknown> = {};\n const relationData: Record<string, Record<string, unknown>> = {};\n\n for (const key in row) {\n const colonIndex = key.indexOf(\":\");\n if (colonIndex === -1) {\n if (table.columns[key]) {\n columnValues[key] = row[key];\n }\n continue;\n }\n\n const relationName = key.slice(0, colonIndex);\n const remainder = key.slice(colonIndex + 1);\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n\n relationData[relationName] ??= {};\n relationData[relationName][remainder] = row[key];\n }\n\n for (const relationName in relationData) {\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n output[relationName] = decodeRow(relationData[relationName], relation.table);\n }\n\n for (const key in columnValues) {\n const column = table.columns[key];\n if (!column || column.isHidden) {\n continue;\n }\n\n if (column.role === \"external-id\" && columnValues[\"_internalId\"] !== undefined) {\n output[key] = new FragnoId({\n externalId: columnValues[key] as string,\n internalId: BigInt(columnValues[\"_internalId\"] as number),\n version: columnValues[\"_version\"] as number,\n });\n continue;\n }\n\n if (column.role === \"reference\") {\n const value = columnValues[key];\n output[key] =\n value === null || value === undefined\n ? null\n : FragnoReference.fromInternal(BigInt(value as number));\n continue;\n }\n\n output[key] = columnValues[key];\n }\n\n return output;\n};\n\nconst coerceLocalInternalId = (value: unknown): number | unknown => {\n if (typeof value === \"bigint\") {\n const asNumber = Number(value);\n if (!Number.isSafeInteger(asNumber)) {\n throw new Error(`Local internalId is not a safe integer: ${value.toString()}`);\n }\n return asNumber;\n }\n return value;\n};\n\nconst resolveReferenceExternalId = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: string;\n schemaName: string;\n table: AnyTable;\n columnName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<number | null> => {\n const { value, schemaName, table, columnName, endpointName, rowsStore, referenceTargets } =\n options;\n const target = referenceTargets.get(`${schemaName}::${table.name}::${columnName}`);\n if (!target) {\n return null;\n }\n\n const key: LofiRow[\"key\"] = [endpointName, target.schema, target.table, value];\n const referenced = (await rowsStore.get(key)) as LofiRow | undefined;\n if (!referenced) {\n return null;\n }\n return referenced._lofi.internalId;\n};\n\nconst resolveReferenceValue = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: unknown;\n column: AnyColumn;\n table: AnyTable;\n schemaName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<unknown> => {\n const { value, column, table, schemaName, endpointName, rowsStore, referenceTargets } = options;\n\n if (value instanceof FragnoReference) {\n return coerceLocalInternalId(value.internalId);\n }\n\n if (value instanceof FragnoId) {\n if (value.internalId !== undefined) {\n return coerceLocalInternalId(value.internalId);\n }\n return resolveReferenceExternalId({\n value: value.externalId,\n schemaName,\n table,\n columnName: column.name,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n }\n\n if (typeof value === \"string\") {\n return resolveReferenceExternalId({\n value,\n schemaName,\n table,\n columnName: column.name,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n }\n\n return resolveFragnoIdValue(value, column);\n};\n\nconst resolveComparisonValue = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: unknown;\n column: AnyColumn;\n table: AnyTable;\n row: LofiRow;\n schemaName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<{ value: unknown; column: AnyColumn }> => {\n const { value, column, table, row, schemaName, endpointName, rowsStore, referenceTargets } =\n options;\n\n if (value instanceof Column) {\n return { value: row._lofi.norm[value.name], column: value };\n }\n\n if (isDbNow(value)) {\n return { value: new Date(), column };\n }\n\n if (column.role === \"reference\") {\n const resolved = await resolveReferenceValue({\n value,\n column,\n table,\n schemaName,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n return { value: resolved, column };\n }\n\n return { value: resolveFragnoIdValue(value, column), column };\n};\n\nconst normalizeLikeValue = (value: unknown, column: AnyColumn): string | null => {\n const normalized =\n column.role === \"reference\" || column.role === \"internal-id\"\n ? coerceLocalInternalId(value)\n : normalizeValue(value, column);\n if (normalized === null || normalized === undefined) {\n return null;\n }\n const bytes = toByteArray(normalized);\n if (bytes) {\n return bytesToHex(bytes);\n }\n return String(normalized);\n};\n\nconst evaluateCondition = async <TxStores extends ArrayLike<string>, StoreName extends string>(\n condition: Condition | boolean,\n table: AnyTable,\n row: LofiRow,\n context: QueryContext,\n rowsStore: ReadStore<TxStores, StoreName>,\n): Promise<boolean> => {\n if (typeof condition === \"boolean\") {\n return condition;\n }\n\n switch (condition.type) {\n case \"and\": {\n for (const item of condition.items) {\n if (!(await evaluateCondition(item, table, row, context, rowsStore))) {\n return false;\n }\n }\n return true;\n }\n case \"or\": {\n for (const item of condition.items) {\n if (await evaluateCondition(item, table, row, context, rowsStore)) {\n return true;\n }\n }\n return false;\n }\n case \"not\":\n return !(await evaluateCondition(condition.item, table, row, context, rowsStore));\n case \"compare\":\n break;\n default: {\n const exhaustiveCheck: never = condition;\n throw new Error(`Unsupported condition type: ${JSON.stringify(exhaustiveCheck)}`);\n }\n }\n\n const leftColumn = condition.a;\n const leftValue = row._lofi.norm[leftColumn.name];\n const right = await resolveComparisonValue({\n value: condition.b,\n column: leftColumn,\n table,\n row,\n schemaName: context.schemaName,\n endpointName: context.endpointName,\n rowsStore,\n referenceTargets: context.referenceTargets,\n });\n\n const op = condition.operator;\n const rightValue = right.value;\n\n if (op === \"is\" || op === \"is not\") {\n if (isNullish(rightValue)) {\n const matches = isNullish(leftValue);\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue)) {\n return op === \"is not\";\n }\n\n const leftNormalized = leftValue;\n const rightNormalized =\n right.column.role === \"reference\" || right.column.role === \"internal-id\"\n ? coerceLocalInternalId(rightValue)\n : normalizeValue(rightValue, right.column);\n const matches = compareNormalizedValues(leftNormalized, rightNormalized) === 0;\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue) || isNullish(rightValue)) {\n return false;\n }\n\n if (op === \"in\" || op === \"not in\") {\n if (!Array.isArray(rightValue)) {\n throw new Error(`Operator \"${op}\" expects an array value.`);\n }\n\n const leftNormalized = leftValue;\n let hasNull = false;\n let hasMatch = false;\n\n for (const item of rightValue) {\n const resolved = await resolveComparisonValue({\n value: item,\n column: leftColumn,\n table,\n row,\n schemaName: context.schemaName,\n endpointName: context.endpointName,\n rowsStore,\n referenceTargets: context.referenceTargets,\n });\n if (isNullish(resolved.value)) {\n hasNull = true;\n continue;\n }\n\n const normalized =\n resolved.column.role === \"reference\" || resolved.column.role === \"internal-id\"\n ? coerceLocalInternalId(resolved.value)\n : normalizeValue(resolved.value, resolved.column);\n if (compareNormalizedValues(leftNormalized, normalized) === 0) {\n hasMatch = true;\n break;\n }\n }\n\n if (hasMatch) {\n return op === \"in\";\n }\n\n if (hasNull) {\n return false;\n }\n\n return op === \"not in\";\n }\n\n if (\n op === \"contains\" ||\n op === \"starts with\" ||\n op === \"ends with\" ||\n op === \"not contains\" ||\n op === \"not starts with\" ||\n op === \"not ends with\"\n ) {\n const leftLike = normalizeLikeValue(leftValue, leftColumn);\n const rightLike = normalizeLikeValue(rightValue, right.column);\n\n if (leftLike === null || rightLike === null) {\n return false;\n }\n\n const leftText = leftLike.toLowerCase();\n const rightText = rightLike.toLowerCase();\n let matches = false;\n\n if (op.includes(\"contains\")) {\n matches = leftText.includes(rightText);\n } else if (op.includes(\"starts with\")) {\n matches = leftText.startsWith(rightText);\n } else {\n matches = leftText.endsWith(rightText);\n }\n\n if (op.startsWith(\"not \")) {\n return !matches;\n }\n return matches;\n }\n\n const leftNormalized = leftValue;\n const rightNormalized =\n right.column.role === \"reference\" || right.column.role === \"internal-id\"\n ? coerceLocalInternalId(rightValue)\n : normalizeValue(rightValue, right.column);\n const comparison = compareNormalizedValues(leftNormalized, rightNormalized);\n\n switch (op) {\n case \"=\":\n return comparison === 0;\n case \"!=\":\n return comparison !== 0;\n case \">\":\n return comparison > 0;\n case \">=\":\n return comparison >= 0;\n case \"<\":\n return comparison < 0;\n case \"<=\":\n return comparison <= 0;\n default:\n throw new Error(`Unsupported operator \"${op}\".`);\n }\n};\n\nconst orderRows = (\n rows: LofiRow[],\n orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined,\n): LofiRow[] => {\n if (!orderBy || orderBy.length === 0) {\n return rows;\n }\n\n return rows.slice().sort((left, right) => {\n for (const [column, direction] of orderBy) {\n const leftValue = left._lofi.norm[column.name];\n const rightValue = right._lofi.norm[column.name];\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n return direction === \"asc\" ? comparison : -comparison;\n }\n }\n return 0;\n });\n};\n\nconst buildOrderColumns = (table: AnyTable, indexName: string): AnyColumn[] => {\n if (indexName === \"_primary\") {\n return [table.getIdColumn()];\n }\n\n const index = table.indexes[indexName];\n const columns = index ? [...index.columns] : [table.getIdColumn()];\n const idColumn = table.getIdColumn();\n if (!columns.some((col) => col.name === idColumn.name)) {\n columns.push(idColumn);\n }\n return columns;\n};\n\nconst getCursorValue = (value: unknown, column: AnyColumn): unknown => {\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"externalId\" in value &&\n typeof (value as { externalId?: unknown }).externalId === \"string\"\n ) {\n const fragnoLike = value as { externalId: string; internalId?: string | number | bigint };\n if (column.role === \"external-id\") {\n return fragnoLike.externalId;\n }\n if ((column.role === \"internal-id\" || column.role === \"reference\") && fragnoLike.internalId) {\n return coerceLocalInternalId(\n typeof fragnoLike.internalId === \"string\"\n ? BigInt(fragnoLike.internalId)\n : fragnoLike.internalId,\n );\n }\n }\n\n if (value instanceof FragnoId) {\n if (column.role === \"external-id\") {\n return value.externalId;\n }\n if ((column.role === \"internal-id\" || column.role === \"reference\") && value.internalId) {\n return coerceLocalInternalId(value.internalId);\n }\n }\n\n if (value instanceof FragnoReference) {\n return coerceLocalInternalId(value.internalId);\n }\n\n return value;\n};\n\nconst buildCursorValues = (\n cursor: Cursor | string | undefined,\n columns: AnyColumn[],\n): readonly unknown[] | undefined => {\n if (!cursor) {\n return undefined;\n }\n\n const cursorObj = typeof cursor === \"string\" ? decodeCursor(cursor) : cursor;\n return columns.map((column) => {\n const rawValue = getCursorValue(cursorObj.indexValues[column.name], column);\n if (rawValue === undefined) {\n return undefined;\n }\n\n if (column.role === \"reference\" || column.role === \"internal-id\") {\n return coerceLocalInternalId(rawValue);\n }\n\n return normalizeValue(rawValue, column);\n });\n};\n\nconst compareRowToCursor = (\n row: LofiRow,\n columns: AnyColumn[],\n cursorValues: readonly unknown[],\n): number => {\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n const leftValue = row._lofi.norm[column.name];\n const rightValue = cursorValues[i];\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n return comparison;\n }\n }\n return 0;\n};\n\nconst collectRows = async <TxStores extends ArrayLike<string>, StoreName extends string>(options: {\n rowsStore: ReadStore<TxStores, StoreName>;\n endpointName: string;\n schemaName: string;\n tableName: string;\n indexName: string;\n}): Promise<LofiRow[]> => {\n const { rowsStore, endpointName, schemaName, tableName, indexName } = options;\n const results: LofiRow[] = [];\n\n const indexKey =\n indexName === \"_primary\"\n ? INDEX_SCHEMA_TABLE\n : buildIndexName(schemaName, tableName, indexName);\n const source: ReadIndex<TxStores, StoreName, string> = rowsStore.indexNames.contains(indexKey)\n ? rowsStore.index(indexKey)\n : rowsStore.index(INDEX_SCHEMA_TABLE);\n\n const range =\n source.name === INDEX_SCHEMA_TABLE\n ? IDBKeyRange.only([endpointName, schemaName, tableName])\n : undefined;\n\n let cursor = await source.openCursor(range);\n while (cursor) {\n const row = cursor.value as LofiRow;\n if (row.endpoint === endpointName && row.schema === schemaName && row.table === tableName) {\n results.push(row);\n }\n cursor = await cursor.continue();\n }\n\n return results;\n};\n\nconst findJoinMatches = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n parentRow: LofiRow;\n parentTable: AnyTable;\n join: CompiledJoin;\n rowsByTable: Map<string, LofiRow[]>;\n context: QueryContext;\n rowsStore: ReadStore<TxStores, StoreName>;\n}): Promise<LofiRow[]> => {\n const { parentRow, parentTable, join, rowsByTable, context, rowsStore } = options;\n if (join.options === false) {\n return [];\n }\n\n const targetTable = join.relation.table;\n const cacheKey = `${context.schemaName}::${targetTable.name}`;\n let targetRows = rowsByTable.get(cacheKey);\n if (!targetRows) {\n targetRows = await collectRows({\n rowsStore,\n endpointName: context.endpointName,\n schemaName: context.schemaName,\n tableName: targetTable.name,\n indexName: \"_primary\",\n });\n rowsByTable.set(cacheKey, targetRows);\n }\n\n const matches: LofiRow[] = [];\n\n for (const row of targetRows) {\n let matchesJoin = true;\n\n for (const [left, right] of join.relation.on) {\n const leftColumn = parentTable.columns[left];\n if (!leftColumn) {\n throw new Error(`Column \"${left}\" not found on table \"${parentTable.name}\".`);\n }\n\n const rightColumn = targetTable.columns[right];\n if (!rightColumn) {\n throw new Error(`Column \"${right}\" not found on table \"${targetTable.name}\".`);\n }\n\n const actualRight = rightColumn.role === \"external-id\" ? \"_internalId\" : right;\n const actualRightColumn = targetTable.columns[actualRight];\n if (!actualRightColumn) {\n throw new Error(`Column \"${actualRight}\" not found on table \"${targetTable.name}\".`);\n }\n\n const leftValue = parentRow._lofi.norm[leftColumn.name];\n const rightValue = row._lofi.norm[actualRightColumn.name];\n if (isNullish(leftValue) || isNullish(rightValue)) {\n matchesJoin = false;\n break;\n }\n\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n matchesJoin = false;\n break;\n }\n }\n\n if (!matchesJoin) {\n continue;\n }\n\n if (join.options.where) {\n const matchesWhere = await evaluateCondition(\n join.options.where,\n targetTable,\n row,\n context,\n rowsStore,\n );\n if (!matchesWhere) {\n continue;\n }\n }\n\n matches.push(row);\n }\n\n const ordered = orderRows(matches, join.options.orderBy);\n if (join.options.limit !== undefined) {\n return ordered.slice(0, Math.max(0, join.options.limit));\n }\n\n return ordered;\n};\n\nconst applyJoins = async <TxStores extends ArrayLike<string>, StoreName extends string>(options: {\n baseOutput: RowSelection;\n parentRow: LofiRow;\n parentTable: AnyTable;\n joins: CompiledJoin[] | undefined;\n rowsByTable: Map<string, LofiRow[]>;\n context: QueryContext;\n rowsStore: ReadStore<TxStores, StoreName>;\n parentPath?: string;\n}): Promise<RowSelection[]> => {\n const {\n baseOutput,\n parentRow,\n parentTable,\n joins,\n rowsByTable,\n context,\n rowsStore,\n parentPath = \"\",\n } = options;\n\n if (!joins || joins.length === 0) {\n return [baseOutput];\n }\n\n let outputs: RowSelection[] = [baseOutput];\n\n for (const join of joins) {\n if (join.options === false) {\n continue;\n }\n\n const relationPath = parentPath ? `${parentPath}:${join.relation.name}` : join.relation.name;\n const nextOutputs: RowSelection[] = [];\n\n for (const currentOutput of outputs) {\n const matches = await findJoinMatches({\n parentRow,\n parentTable,\n join,\n rowsByTable,\n context,\n rowsStore,\n });\n\n if (matches.length === 0) {\n nextOutputs.push(currentOutput);\n continue;\n }\n\n for (const matchRow of matches) {\n const prefixed = prefixSelection(\n matchRow,\n join.relation.table,\n join.options.select as undefined | true | readonly string[],\n relationPath,\n );\n const merged = { ...currentOutput, ...prefixed };\n\n if (join.options.join && join.options.join.length > 0) {\n nextOutputs.push(\n ...(await applyJoins({\n baseOutput: merged,\n parentRow: matchRow,\n parentTable: join.relation.table,\n joins: join.options.join,\n rowsByTable,\n context,\n rowsStore,\n parentPath: relationPath,\n })),\n );\n } else {\n nextOutputs.push(merged);\n }\n }\n }\n\n outputs = nextOutputs;\n }\n\n return outputs;\n};\n\nconst buildFindBuilder = <TTable extends AnyTable>(tableName: string, table: TTable) =>\n new FindBuilder<TTable>(tableName, table);\n\ntype IndexedDbFindOptions<TTable extends AnyTable = AnyTable> = {\n useIndex: string;\n select?: unknown;\n where?: ((builder: ConditionBuilder<TTable[\"columns\"]>) => Condition | boolean) | Condition;\n orderByIndex?: {\n indexName: string;\n direction: \"asc\" | \"desc\";\n };\n after?: Cursor | string;\n before?: Cursor | string;\n pageSize?: number;\n joins?: CompiledJoin[];\n};\n\ntype IndexedDbRetrievalOperation =\n | {\n type: \"find\";\n table: AnyTable;\n indexName: string;\n options: IndexedDbFindOptions;\n withCursor: boolean;\n }\n | {\n type: \"count\";\n table: AnyTable;\n indexName: string;\n options: Pick<IndexedDbFindOptions, \"where\">;\n };\n\nconst resolveFindCondition = <TTable extends AnyTable>(\n table: TTable,\n input: IndexedDbFindOptions<TTable>[\"where\"],\n): Condition | undefined | false => {\n if (!input) {\n return undefined;\n }\n if (typeof input === \"function\") {\n const built = buildCondition(table.columns, input);\n if (built === true) {\n return undefined;\n }\n return built;\n }\n return input;\n};\n\nexport const executeIndexedDbRetrievalOperation = async (options: {\n operation: IndexedDbRetrievalOperation;\n context: IndexedDbQueryContext;\n}): Promise<Record<string, unknown>[] | CursorResult<Record<string, unknown>> | number> => {\n const { operation, context } = options;\n const db = await context.getDb();\n const tx = db.transaction(ROWS_STORE, \"readonly\");\n const rowsStore = tx.objectStore(ROWS_STORE);\n\n const rows = await collectRows({\n rowsStore,\n endpointName: context.endpointName,\n schemaName: context.schemaName,\n tableName: operation.table.name,\n indexName: operation.indexName,\n });\n\n const condition =\n operation.options.where !== undefined\n ? resolveFindCondition(operation.table, operation.options.where)\n : undefined;\n\n if (condition === false) {\n await tx.done;\n if (operation.type === \"count\") {\n return 0;\n }\n return operation.withCursor ? { items: [], hasNextPage: false } : [];\n }\n\n if (operation.type === \"count\") {\n let count = 0;\n for (const row of rows) {\n if (\n condition &&\n !(await evaluateCondition(condition, operation.table, row, context, rowsStore))\n ) {\n continue;\n }\n count += 1;\n }\n await tx.done;\n return count;\n }\n\n const filtered: LofiRow[] = [];\n for (const row of rows) {\n if (\n condition &&\n !(await evaluateCondition(condition, operation.table, row, context, rowsStore))\n ) {\n continue;\n }\n filtered.push(row);\n }\n\n const orderIndexName = operation.options.orderByIndex?.indexName ?? operation.indexName;\n const direction = operation.options.orderByIndex?.direction ?? \"asc\";\n const orderColumns = buildOrderColumns(operation.table, orderIndexName);\n\n let ordered = orderRows(\n filtered,\n orderColumns.map((col) => [col, direction]),\n );\n ordered = applyCursorFilters({\n rows: ordered,\n orderColumns,\n direction,\n after: operation.options.after,\n before: operation.options.before,\n });\n\n const limit =\n operation.withCursor && operation.options.pageSize !== undefined\n ? operation.options.pageSize + 1\n : operation.options.pageSize;\n\n const results: RowSelection[] = [];\n const resultSources: LofiRow[] = [];\n const rowsByTable = new Map<string, LofiRow[]>();\n\n for (const row of ordered) {\n const select = operation.options.select as undefined | true | readonly string[];\n const baseOutput = selectRow(row, operation.table, select);\n\n if (operation.options.joins && operation.options.joins.length > 0) {\n const joined = await applyJoins({\n baseOutput,\n parentRow: row,\n parentTable: operation.table,\n joins: operation.options.joins,\n rowsByTable,\n context,\n rowsStore,\n });\n for (const joinedRow of joined) {\n results.push(joinedRow);\n resultSources.push(row);\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n } else {\n results.push(baseOutput);\n resultSources.push(row);\n }\n\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n\n await tx.done;\n\n const decoded = results.map((row) => decodeRow(row, operation.table));\n\n if (!operation.withCursor) {\n return decoded;\n }\n\n let cursor: Cursor | undefined;\n let hasNextPage = false;\n let items = decoded;\n\n if (\n operation.options.pageSize &&\n operation.options.pageSize > 0 &&\n decoded.length > operation.options.pageSize\n ) {\n hasNextPage = true;\n items = decoded.slice(0, operation.options.pageSize);\n\n const lastRow = items[items.length - 1];\n if (lastRow) {\n const cursorRecord: Record<string, unknown> = { ...lastRow };\n const sourceRow = resultSources[operation.options.pageSize - 1];\n for (const column of orderColumns) {\n if (cursorRecord[column.name] === undefined) {\n cursorRecord[column.name] = sourceRow\n ? buildOutputValueForColumn(sourceRow, column)\n : cursorRecord[column.name];\n }\n }\n\n cursor = createCursorFromRecord(cursorRecord, orderColumns, {\n indexName: orderIndexName,\n orderDirection: direction,\n pageSize: operation.options.pageSize,\n });\n }\n }\n\n return { items, cursor, hasNextPage };\n};\n\nconst applyCursorFilters = (options: {\n rows: LofiRow[];\n orderColumns: AnyColumn[];\n direction: \"asc\" | \"desc\";\n after?: Cursor | string;\n before?: Cursor | string;\n}): LofiRow[] => {\n const { rows, orderColumns, direction, after, before } = options;\n\n const afterValues = buildCursorValues(after, orderColumns);\n const beforeValues = buildCursorValues(before, orderColumns);\n\n return rows.filter((row) => {\n if (afterValues) {\n const comparison = compareRowToCursor(row, orderColumns, afterValues);\n if (direction === \"asc\" ? comparison <= 0 : comparison >= 0) {\n return false;\n }\n }\n\n if (beforeValues) {\n const comparison = compareRowToCursor(row, orderColumns, beforeValues);\n if (direction === \"asc\" ? comparison >= 0 : comparison <= 0) {\n return false;\n }\n }\n\n return true;\n });\n};\n\nexport const createIndexedDbQueryEngine = <T extends AnySchema>(options: {\n schema: T;\n endpointName: string;\n getDb: () => Promise<LofiDb>;\n referenceTargets: Map<string, ReferenceTarget>;\n schemaName?: string;\n}): LofiQueryInterface<T> => {\n const schemaName = options.schemaName ?? options.schema.name;\n const context: IndexedDbQueryContext = {\n endpointName: options.endpointName,\n schemaName,\n getDb: options.getDb,\n referenceTargets: options.referenceTargets,\n };\n\n const runFind = async (\n tableName: string,\n builderFn: ((builder: FindBuilder<AnyTable>) => unknown) | undefined,\n withCursor: boolean,\n ): Promise<Record<string, unknown>[] | CursorResult<Record<string, unknown>> | number> => {\n const tableMap = options.schema.tables as Record<string, AnyTable>;\n const table = tableMap[tableName];\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n const builder = buildFindBuilder(tableName, table);\n if (builderFn) {\n builderFn(builder);\n } else {\n builder.whereIndex(\"primary\");\n }\n\n const built = builder.build();\n if (built.type === \"count\") {\n return executeIndexedDbRetrievalOperation({\n operation: {\n type: \"count\",\n table,\n indexName: built.indexName,\n options: { where: built.options.where },\n },\n context,\n });\n }\n\n return executeIndexedDbRetrievalOperation({\n operation: {\n type: \"find\",\n table,\n indexName: built.indexName,\n options: built.options,\n withCursor,\n },\n context,\n });\n };\n\n const queryEngine = {\n async find(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn as unknown as (builder: FindBuilder<AnyTable>) => unknown,\n false,\n );\n return result as Record<string, unknown>[] | number;\n },\n\n async findWithCursor(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn as unknown as (builder: FindBuilder<AnyTable>) => unknown,\n true,\n );\n return result as CursorResult<Record<string, unknown>>;\n },\n\n async findFirst(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn\n ? (builder: FindBuilder<AnyTable>) => {\n (builderFn as unknown as (b: FindBuilder<AnyTable>) => unknown)(builder);\n builder.pageSize(1);\n return builder;\n }\n : (builder: FindBuilder<AnyTable>) => builder.whereIndex(\"primary\").pageSize(1),\n false,\n );\n\n if (typeof result === \"number\") {\n return null;\n }\n\n return (result as Record<string, unknown>[])[0] ?? null;\n },\n } as LofiQueryInterface<T>;\n\n return queryEngine;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"engine.js","names":["selected: RowSelection","prefixed: RowSelection","output: Record<string, unknown>","columnValues: Record<string, unknown>","relationData: Record<string, Record<string, unknown>>","key: LofiRow[\"key\"]","exhaustiveCheck: never","matches","results: LofiRow[]","source: ReadIndex<TxStores, StoreName, string>","matches: LofiRow[]","outputs: RowSelection[]","nextOutputs: RowSelection[]","filtered: LofiRow[]","results: RowSelection[]","resultSources: LofiRow[]","cursor: Cursor | undefined","cursorRecord: Record<string, unknown>","context: IndexedDbQueryContext"],"sources":["../../src/query/engine.ts"],"sourcesContent":["import type { CursorResult } from \"@fragno-dev/db/cursor\";\nimport { Cursor, createCursorFromRecord, decodeCursor } from \"@fragno-dev/db/cursor\";\nimport type { AnyColumn, AnySchema, AnyTable } from \"@fragno-dev/db/schema\";\nimport { Column, FragnoId, FragnoReference } from \"@fragno-dev/db/schema\";\nimport { FindBuilder } from \"@fragno-dev/db/unit-of-work\";\nimport type { IDBPDatabase, IDBPIndex, IDBPObjectStore } from \"idb\";\n\nimport type { ReferenceTarget } from \"../indexeddb/types\";\nimport type { LofiQueryInterface } from \"../types\";\nimport { buildCondition, type Condition, type ConditionBuilder } from \"./conditions\";\nimport { normalizeValue } from \"./normalize\";\n\nconst ROWS_STORE = \"lofi_rows\";\nconst INDEX_SCHEMA_TABLE = \"idx_schema_table\";\n\ntype LofiRow = {\n key: [string, string, string, string];\n endpoint: string;\n schema: string;\n table: string;\n id: string;\n data: Record<string, unknown>;\n _lofi: {\n versionstamp: string;\n norm: Record<string, unknown>;\n internalId: number;\n version: number;\n };\n};\n\ntype LofiDb = IDBPDatabase<unknown>;\ntype ReadStore<TxStores extends ArrayLike<string>, StoreName extends string> = IDBPObjectStore<\n unknown,\n TxStores,\n StoreName,\n \"readonly\"\n>;\ntype ReadIndex<\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n IndexName extends string,\n> = IDBPIndex<unknown, TxStores, StoreName, IndexName, \"readonly\">;\n\ntype RowSelection = Record<string, unknown>;\n\nexport type IndexedDbQueryContext = {\n endpointName: string;\n schemaName: string;\n getDb: () => Promise<LofiDb>;\n referenceTargets: Map<string, ReferenceTarget>;\n};\n\ntype QueryContext = IndexedDbQueryContext;\n\ntype CompiledJoin = {\n relation: { name: string; table: AnyTable; on: [string, string][] };\n options:\n | {\n select: unknown;\n where?: Condition;\n orderBy?: [AnyColumn, \"asc\" | \"desc\"][];\n join?: CompiledJoin[];\n limit?: number;\n }\n | false;\n};\n\nconst isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined;\n\nconst toByteArray = (value: unknown): Uint8Array | null => {\n if (value instanceof Uint8Array) {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n if (ArrayBuffer.isView(value)) {\n return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);\n }\n return null;\n};\n\nconst compareByteArrays = (left: Uint8Array, right: Uint8Array): number => {\n const minLength = Math.min(left.length, right.length);\n for (let i = 0; i < minLength; i += 1) {\n const diff = left[i]! - right[i]!;\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n }\n if (left.length === right.length) {\n return 0;\n }\n return left.length < right.length ? -1 : 1;\n};\n\nconst bytesToHex = (bytes: Uint8Array): string => {\n let hex = \"\";\n for (const byte of bytes) {\n hex += byte.toString(16).padStart(2, \"0\");\n }\n return hex;\n};\n\nconst compareNormalizedValues = (left: unknown, right: unknown): number => {\n if (left === right) {\n return 0;\n }\n if (left === undefined) {\n return -1;\n }\n if (right === undefined) {\n return 1;\n }\n if (left === null) {\n return -1;\n }\n if (right === null) {\n return 1;\n }\n const leftBytes = toByteArray(left);\n const rightBytes = toByteArray(right);\n if (leftBytes && rightBytes) {\n return compareByteArrays(leftBytes, rightBytes);\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() - right.getTime();\n }\n if (typeof left === \"number\" && typeof right === \"number\") {\n return left - right;\n }\n if (typeof left === \"bigint\" && typeof right === \"bigint\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"string\" && typeof right === \"string\") {\n return left < right ? -1 : 1;\n }\n if (typeof left === \"boolean\" && typeof right === \"boolean\") {\n return left === right ? 0 : left ? 1 : -1;\n }\n const leftString = String(left);\n const rightString = String(right);\n return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;\n};\n\nconst buildIndexName = (schemaName: string, tableName: string, indexName: string): string =>\n `idx__${schemaName}__${tableName}__${indexName}`;\n\ntype DbNow = { tag: \"db-now\" };\n\nconst isDbNow = (value: unknown): value is DbNow =>\n typeof value === \"object\" && value !== null && (value as { tag?: string }).tag === \"db-now\";\n\nconst resolveFragnoIdValue = (value: unknown, col: AnyColumn): unknown => {\n if (value instanceof FragnoReference) {\n return value.internalId;\n }\n\n if (value instanceof FragnoId) {\n if (col.role === \"external-id\") {\n return value.externalId;\n }\n if (col.role === \"internal-id\") {\n if (value.internalId === undefined) {\n throw new Error(`FragnoId must have internalId for internal-id column ${col.name}`);\n }\n return value.internalId;\n }\n if (col.role === \"reference\") {\n return value.databaseId;\n }\n return value.externalId;\n }\n\n return value;\n};\n\nconst buildSelection = (\n table: AnyTable,\n select: undefined | true | readonly string[],\n): Set<string> => {\n const selection = new Set<string>();\n\n if (!select || select === true) {\n for (const columnName of Object.keys(table.columns)) {\n selection.add(columnName);\n }\n } else {\n for (const columnName of select) {\n selection.add(columnName);\n }\n }\n\n selection.add(\"_internalId\");\n selection.add(\"_version\");\n\n return selection;\n};\n\nconst getColumnValue = (row: LofiRow, columnName: string, column: AnyColumn): unknown => {\n if (column.role === \"external-id\") {\n return row.id;\n }\n if (column.role === \"internal-id\") {\n return row._lofi.internalId;\n }\n if (column.role === \"version\") {\n return row._lofi.version;\n }\n\n return row.data[columnName];\n};\n\nconst selectRow = (\n row: LofiRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n): RowSelection => {\n const selection = buildSelection(table, select);\n const selected: RowSelection = {};\n\n for (const columnName of selection) {\n if (columnName === \"_internalId\") {\n selected[columnName] = row._lofi.internalId;\n continue;\n }\n if (columnName === \"_version\") {\n selected[columnName] = row._lofi.version;\n continue;\n }\n\n const column = table.columns[columnName];\n if (!column) {\n continue;\n }\n\n if (column.role === \"reference\") {\n selected[columnName] = row._lofi.norm[columnName];\n continue;\n }\n\n selected[columnName] = getColumnValue(row, columnName, column);\n }\n\n return selected;\n};\n\nconst prefixSelection = (\n row: LofiRow,\n table: AnyTable,\n select: undefined | true | readonly string[],\n prefix: string,\n): RowSelection => {\n const selected = selectRow(row, table, select);\n const prefixed: RowSelection = {};\n\n for (const key in selected) {\n prefixed[`${prefix}:${key}`] = selected[key];\n }\n\n return prefixed;\n};\n\nconst buildOutputValueForColumn = (row: LofiRow, column: AnyColumn): unknown => {\n if (column.isHidden) {\n return undefined;\n }\n\n if (column.role === \"external-id\") {\n return new FragnoId({\n externalId: row.id,\n internalId: BigInt(row._lofi.internalId),\n version: row._lofi.version,\n });\n }\n\n if (column.role === \"reference\") {\n const value = row._lofi.norm[column.name];\n return value === null || value === undefined\n ? null\n : FragnoReference.fromInternal(BigInt(value as number));\n }\n\n if (column.role === \"internal-id\") {\n return BigInt(row._lofi.internalId);\n }\n\n if (column.role === \"version\") {\n return row._lofi.version;\n }\n\n return row.data[column.name];\n};\n\nconst decodeRow = (row: RowSelection, table: AnyTable): Record<string, unknown> => {\n const output: Record<string, unknown> = {};\n const columnValues: Record<string, unknown> = {};\n const relationData: Record<string, Record<string, unknown>> = {};\n\n for (const key in row) {\n const colonIndex = key.indexOf(\":\");\n if (colonIndex === -1) {\n if (table.columns[key]) {\n columnValues[key] = row[key];\n }\n continue;\n }\n\n const relationName = key.slice(0, colonIndex);\n const remainder = key.slice(colonIndex + 1);\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n\n relationData[relationName] ??= {};\n relationData[relationName][remainder] = row[key];\n }\n\n for (const relationName in relationData) {\n const relation = table.relations[relationName];\n if (!relation) {\n continue;\n }\n output[relationName] = decodeRow(relationData[relationName], relation.table);\n }\n\n for (const key in columnValues) {\n const column = table.columns[key];\n if (!column || column.isHidden) {\n continue;\n }\n\n if (column.role === \"external-id\" && columnValues[\"_internalId\"] !== undefined) {\n output[key] = new FragnoId({\n externalId: columnValues[key] as string,\n internalId: BigInt(columnValues[\"_internalId\"] as number),\n version: columnValues[\"_version\"] as number,\n });\n continue;\n }\n\n if (column.role === \"reference\") {\n const value = columnValues[key];\n output[key] =\n value === null || value === undefined\n ? null\n : FragnoReference.fromInternal(BigInt(value as number));\n continue;\n }\n\n output[key] = columnValues[key];\n }\n\n return output;\n};\n\nconst coerceLocalInternalId = (value: unknown): number | unknown => {\n if (typeof value === \"bigint\") {\n const asNumber = Number(value);\n if (!Number.isSafeInteger(asNumber)) {\n throw new Error(`Local internalId is not a safe integer: ${value.toString()}`);\n }\n return asNumber;\n }\n return value;\n};\n\nconst resolveReferenceExternalId = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: string;\n schemaName: string;\n table: AnyTable;\n columnName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<number | null> => {\n const { value, schemaName, table, columnName, endpointName, rowsStore, referenceTargets } =\n options;\n const target = referenceTargets.get(`${schemaName}::${table.name}::${columnName}`);\n if (!target) {\n return null;\n }\n\n const key: LofiRow[\"key\"] = [endpointName, target.schema, target.table, value];\n const referenced = (await rowsStore.get(key)) as LofiRow | undefined;\n if (!referenced) {\n return null;\n }\n return referenced._lofi.internalId;\n};\n\nconst resolveReferenceValue = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: unknown;\n column: AnyColumn;\n table: AnyTable;\n schemaName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<unknown> => {\n const { value, column, table, schemaName, endpointName, rowsStore, referenceTargets } = options;\n\n if (value instanceof FragnoReference) {\n return coerceLocalInternalId(value.internalId);\n }\n\n if (value instanceof FragnoId) {\n if (value.internalId !== undefined) {\n return coerceLocalInternalId(value.internalId);\n }\n return resolveReferenceExternalId({\n value: value.externalId,\n schemaName,\n table,\n columnName: column.name,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n }\n\n if (typeof value === \"string\") {\n return resolveReferenceExternalId({\n value,\n schemaName,\n table,\n columnName: column.name,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n }\n\n return resolveFragnoIdValue(value, column);\n};\n\nconst resolveComparisonValue = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n value: unknown;\n column: AnyColumn;\n table: AnyTable;\n row: LofiRow;\n schemaName: string;\n endpointName: string;\n rowsStore: ReadStore<TxStores, StoreName>;\n referenceTargets: Map<string, ReferenceTarget>;\n}): Promise<{ value: unknown; column: AnyColumn }> => {\n const { value, column, table, row, schemaName, endpointName, rowsStore, referenceTargets } =\n options;\n\n if (value instanceof Column) {\n return { value: row._lofi.norm[value.name], column: value };\n }\n\n if (isDbNow(value)) {\n return { value: new Date(), column };\n }\n\n if (column.role === \"reference\") {\n const resolved = await resolveReferenceValue({\n value,\n column,\n table,\n schemaName,\n endpointName,\n rowsStore,\n referenceTargets,\n });\n return { value: resolved, column };\n }\n\n return { value: resolveFragnoIdValue(value, column), column };\n};\n\nconst normalizeLikeValue = (value: unknown, column: AnyColumn): string | null => {\n const normalized =\n column.role === \"reference\" || column.role === \"internal-id\"\n ? coerceLocalInternalId(value)\n : normalizeValue(value, column);\n if (normalized === null || normalized === undefined) {\n return null;\n }\n const bytes = toByteArray(normalized);\n if (bytes) {\n return bytesToHex(bytes);\n }\n return String(normalized);\n};\n\nconst evaluateCondition = async <TxStores extends ArrayLike<string>, StoreName extends string>(\n condition: Condition | boolean,\n table: AnyTable,\n row: LofiRow,\n context: QueryContext,\n rowsStore: ReadStore<TxStores, StoreName>,\n): Promise<boolean> => {\n if (typeof condition === \"boolean\") {\n return condition;\n }\n\n switch (condition.type) {\n case \"and\": {\n for (const item of condition.items) {\n if (!(await evaluateCondition(item, table, row, context, rowsStore))) {\n return false;\n }\n }\n return true;\n }\n case \"or\": {\n for (const item of condition.items) {\n if (await evaluateCondition(item, table, row, context, rowsStore)) {\n return true;\n }\n }\n return false;\n }\n case \"not\":\n return !(await evaluateCondition(condition.item, table, row, context, rowsStore));\n case \"compare\":\n break;\n default: {\n const exhaustiveCheck: never = condition;\n throw new Error(`Unsupported condition type: ${JSON.stringify(exhaustiveCheck)}`);\n }\n }\n\n const leftColumn = condition.a;\n const leftValue = row._lofi.norm[leftColumn.name];\n const right = await resolveComparisonValue({\n value: condition.b,\n column: leftColumn,\n table,\n row,\n schemaName: context.schemaName,\n endpointName: context.endpointName,\n rowsStore,\n referenceTargets: context.referenceTargets,\n });\n\n const op = condition.operator;\n const rightValue = right.value;\n\n if (op === \"is\" || op === \"is not\") {\n if (isNullish(rightValue)) {\n const matches = isNullish(leftValue);\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue)) {\n return op === \"is not\";\n }\n\n const leftNormalized = leftValue;\n const rightNormalized =\n right.column.role === \"reference\" || right.column.role === \"internal-id\"\n ? coerceLocalInternalId(rightValue)\n : normalizeValue(rightValue, right.column);\n const matches = compareNormalizedValues(leftNormalized, rightNormalized) === 0;\n return op === \"is\" ? matches : !matches;\n }\n\n if (isNullish(leftValue) || isNullish(rightValue)) {\n return false;\n }\n\n if (op === \"in\" || op === \"not in\") {\n if (!Array.isArray(rightValue)) {\n throw new Error(`Operator \"${op}\" expects an array value.`);\n }\n\n const leftNormalized = leftValue;\n let hasNull = false;\n let hasMatch = false;\n\n for (const item of rightValue) {\n const resolved = await resolveComparisonValue({\n value: item,\n column: leftColumn,\n table,\n row,\n schemaName: context.schemaName,\n endpointName: context.endpointName,\n rowsStore,\n referenceTargets: context.referenceTargets,\n });\n if (isNullish(resolved.value)) {\n hasNull = true;\n continue;\n }\n\n const normalized =\n resolved.column.role === \"reference\" || resolved.column.role === \"internal-id\"\n ? coerceLocalInternalId(resolved.value)\n : normalizeValue(resolved.value, resolved.column);\n if (compareNormalizedValues(leftNormalized, normalized) === 0) {\n hasMatch = true;\n break;\n }\n }\n\n if (hasMatch) {\n return op === \"in\";\n }\n\n if (hasNull) {\n return false;\n }\n\n return op === \"not in\";\n }\n\n if (\n op === \"contains\" ||\n op === \"starts with\" ||\n op === \"ends with\" ||\n op === \"not contains\" ||\n op === \"not starts with\" ||\n op === \"not ends with\"\n ) {\n const leftLike = normalizeLikeValue(leftValue, leftColumn);\n const rightLike = normalizeLikeValue(rightValue, right.column);\n\n if (leftLike === null || rightLike === null) {\n return false;\n }\n\n const leftText = leftLike.toLowerCase();\n const rightText = rightLike.toLowerCase();\n let matches = false;\n\n if (op.includes(\"contains\")) {\n matches = leftText.includes(rightText);\n } else if (op.includes(\"starts with\")) {\n matches = leftText.startsWith(rightText);\n } else {\n matches = leftText.endsWith(rightText);\n }\n\n if (op.startsWith(\"not \")) {\n return !matches;\n }\n return matches;\n }\n\n const leftNormalized = leftValue;\n const rightNormalized =\n right.column.role === \"reference\" || right.column.role === \"internal-id\"\n ? coerceLocalInternalId(rightValue)\n : normalizeValue(rightValue, right.column);\n const comparison = compareNormalizedValues(leftNormalized, rightNormalized);\n\n switch (op) {\n case \"=\":\n return comparison === 0;\n case \"!=\":\n return comparison !== 0;\n case \">\":\n return comparison > 0;\n case \">=\":\n return comparison >= 0;\n case \"<\":\n return comparison < 0;\n case \"<=\":\n return comparison <= 0;\n default:\n throw new Error(`Unsupported operator \"${op}\".`);\n }\n};\n\nconst orderRows = (\n rows: LofiRow[],\n orderBy: [AnyColumn, \"asc\" | \"desc\"][] | undefined,\n): LofiRow[] => {\n if (!orderBy || orderBy.length === 0) {\n return rows;\n }\n\n return rows.slice().sort((left, right) => {\n for (const [column, direction] of orderBy) {\n const leftValue = left._lofi.norm[column.name];\n const rightValue = right._lofi.norm[column.name];\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n return direction === \"asc\" ? comparison : -comparison;\n }\n }\n return 0;\n });\n};\n\nconst buildOrderColumns = (table: AnyTable, indexName: string): AnyColumn[] => {\n if (indexName === \"_primary\") {\n return [table.getIdColumn()];\n }\n\n const index = table.indexes[indexName];\n const columns = index ? [...index.columns] : [table.getIdColumn()];\n const idColumn = table.getIdColumn();\n if (!columns.some((col) => col.name === idColumn.name)) {\n columns.push(idColumn);\n }\n return columns;\n};\n\nconst getCursorValue = (value: unknown, column: AnyColumn): unknown => {\n if (\n typeof value === \"object\" &&\n value !== null &&\n \"externalId\" in value &&\n typeof (value as { externalId?: unknown }).externalId === \"string\"\n ) {\n const fragnoLike = value as { externalId: string; internalId?: string | number | bigint };\n if (column.role === \"external-id\") {\n return fragnoLike.externalId;\n }\n if ((column.role === \"internal-id\" || column.role === \"reference\") && fragnoLike.internalId) {\n return coerceLocalInternalId(\n typeof fragnoLike.internalId === \"string\"\n ? BigInt(fragnoLike.internalId)\n : fragnoLike.internalId,\n );\n }\n }\n\n if (value instanceof FragnoId) {\n if (column.role === \"external-id\") {\n return value.externalId;\n }\n if ((column.role === \"internal-id\" || column.role === \"reference\") && value.internalId) {\n return coerceLocalInternalId(value.internalId);\n }\n }\n\n if (value instanceof FragnoReference) {\n return coerceLocalInternalId(value.internalId);\n }\n\n return value;\n};\n\nconst buildCursorValues = (\n cursor: Cursor | string | undefined,\n columns: AnyColumn[],\n): readonly unknown[] | undefined => {\n if (!cursor) {\n return undefined;\n }\n\n const cursorObj = typeof cursor === \"string\" ? decodeCursor(cursor) : cursor;\n return columns.map((column) => {\n const rawValue = getCursorValue(cursorObj.indexValues[column.name], column);\n if (rawValue === undefined) {\n return undefined;\n }\n\n if (column.role === \"reference\" || column.role === \"internal-id\") {\n return coerceLocalInternalId(rawValue);\n }\n\n return normalizeValue(rawValue, column);\n });\n};\n\nconst compareRowToCursor = (\n row: LofiRow,\n columns: AnyColumn[],\n cursorValues: readonly unknown[],\n): number => {\n for (let i = 0; i < columns.length; i += 1) {\n const column = columns[i];\n const leftValue = row._lofi.norm[column.name];\n const rightValue = cursorValues[i];\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n return comparison;\n }\n }\n return 0;\n};\n\nconst collectRows = async <TxStores extends ArrayLike<string>, StoreName extends string>(options: {\n rowsStore: ReadStore<TxStores, StoreName>;\n endpointName: string;\n schemaName: string;\n tableName: string;\n indexName: string;\n}): Promise<LofiRow[]> => {\n const { rowsStore, endpointName, schemaName, tableName, indexName } = options;\n const results: LofiRow[] = [];\n\n const indexKey =\n indexName === \"_primary\"\n ? INDEX_SCHEMA_TABLE\n : buildIndexName(schemaName, tableName, indexName);\n const source: ReadIndex<TxStores, StoreName, string> = rowsStore.indexNames.contains(indexKey)\n ? rowsStore.index(indexKey)\n : rowsStore.index(INDEX_SCHEMA_TABLE);\n\n const range =\n source.name === INDEX_SCHEMA_TABLE\n ? IDBKeyRange.only([endpointName, schemaName, tableName])\n : undefined;\n\n let cursor = await source.openCursor(range);\n while (cursor) {\n const row = cursor.value as LofiRow;\n if (row.endpoint === endpointName && row.schema === schemaName && row.table === tableName) {\n results.push(row);\n }\n cursor = await cursor.continue();\n }\n\n return results;\n};\n\nconst findJoinMatches = async <\n TxStores extends ArrayLike<string>,\n StoreName extends string,\n>(options: {\n parentRow: LofiRow;\n parentTable: AnyTable;\n join: CompiledJoin;\n rowsByTable: Map<string, LofiRow[]>;\n context: QueryContext;\n rowsStore: ReadStore<TxStores, StoreName>;\n}): Promise<LofiRow[]> => {\n const { parentRow, parentTable, join, rowsByTable, context, rowsStore } = options;\n if (join.options === false) {\n return [];\n }\n\n const targetTable = join.relation.table;\n const cacheKey = `${context.schemaName}::${targetTable.name}`;\n let targetRows = rowsByTable.get(cacheKey);\n if (!targetRows) {\n targetRows = await collectRows({\n rowsStore,\n endpointName: context.endpointName,\n schemaName: context.schemaName,\n tableName: targetTable.name,\n indexName: \"_primary\",\n });\n rowsByTable.set(cacheKey, targetRows);\n }\n\n const matches: LofiRow[] = [];\n\n for (const row of targetRows) {\n let matchesJoin = true;\n\n for (const [left, right] of join.relation.on) {\n const leftColumn = parentTable.columns[left];\n if (!leftColumn) {\n throw new Error(`Column \"${left}\" not found on table \"${parentTable.name}\".`);\n }\n\n const rightColumn = targetTable.columns[right];\n if (!rightColumn) {\n throw new Error(`Column \"${right}\" not found on table \"${targetTable.name}\".`);\n }\n\n const actualRight = rightColumn.role === \"external-id\" ? \"_internalId\" : right;\n const actualRightColumn = targetTable.columns[actualRight];\n if (!actualRightColumn) {\n throw new Error(`Column \"${actualRight}\" not found on table \"${targetTable.name}\".`);\n }\n\n const leftValue = parentRow._lofi.norm[leftColumn.name];\n const rightValue = row._lofi.norm[actualRightColumn.name];\n if (isNullish(leftValue) || isNullish(rightValue)) {\n matchesJoin = false;\n break;\n }\n\n const comparison = compareNormalizedValues(leftValue, rightValue);\n if (comparison !== 0) {\n matchesJoin = false;\n break;\n }\n }\n\n if (!matchesJoin) {\n continue;\n }\n\n if (join.options.where) {\n const matchesWhere = await evaluateCondition(\n join.options.where,\n targetTable,\n row,\n context,\n rowsStore,\n );\n if (!matchesWhere) {\n continue;\n }\n }\n\n matches.push(row);\n }\n\n const ordered = orderRows(matches, join.options.orderBy);\n if (join.options.limit !== undefined) {\n return ordered.slice(0, Math.max(0, join.options.limit));\n }\n\n return ordered;\n};\n\nconst applyJoins = async <TxStores extends ArrayLike<string>, StoreName extends string>(options: {\n baseOutput: RowSelection;\n parentRow: LofiRow;\n parentTable: AnyTable;\n joins: CompiledJoin[] | undefined;\n rowsByTable: Map<string, LofiRow[]>;\n context: QueryContext;\n rowsStore: ReadStore<TxStores, StoreName>;\n parentPath?: string;\n}): Promise<RowSelection[]> => {\n const {\n baseOutput,\n parentRow,\n parentTable,\n joins,\n rowsByTable,\n context,\n rowsStore,\n parentPath = \"\",\n } = options;\n\n if (!joins || joins.length === 0) {\n return [baseOutput];\n }\n\n let outputs: RowSelection[] = [baseOutput];\n\n for (const join of joins) {\n if (join.options === false) {\n continue;\n }\n\n const relationPath = parentPath ? `${parentPath}:${join.relation.name}` : join.relation.name;\n const nextOutputs: RowSelection[] = [];\n\n for (const currentOutput of outputs) {\n const matches = await findJoinMatches({\n parentRow,\n parentTable,\n join,\n rowsByTable,\n context,\n rowsStore,\n });\n\n if (matches.length === 0) {\n nextOutputs.push(currentOutput);\n continue;\n }\n\n for (const matchRow of matches) {\n const prefixed = prefixSelection(\n matchRow,\n join.relation.table,\n join.options.select as undefined | true | readonly string[],\n relationPath,\n );\n const merged = { ...currentOutput, ...prefixed };\n\n if (join.options.join && join.options.join.length > 0) {\n nextOutputs.push(\n ...(await applyJoins({\n baseOutput: merged,\n parentRow: matchRow,\n parentTable: join.relation.table,\n joins: join.options.join,\n rowsByTable,\n context,\n rowsStore,\n parentPath: relationPath,\n })),\n );\n } else {\n nextOutputs.push(merged);\n }\n }\n }\n\n outputs = nextOutputs;\n }\n\n return outputs;\n};\n\nconst buildFindBuilder = <TTable extends AnyTable>(tableName: string, table: TTable) =>\n new FindBuilder<TTable>(tableName, table);\n\ntype IndexedDbFindOptions<TTable extends AnyTable = AnyTable> = {\n useIndex: string;\n select?: unknown;\n where?: ((builder: ConditionBuilder<TTable[\"columns\"]>) => Condition | boolean) | Condition;\n orderByIndex?: {\n indexName: string;\n direction: \"asc\" | \"desc\";\n };\n after?: Cursor | string;\n before?: Cursor | string;\n pageSize?: number;\n joins?: CompiledJoin[];\n};\n\ntype IndexedDbRetrievalOperation =\n | {\n type: \"find\";\n table: AnyTable;\n indexName: string;\n options: IndexedDbFindOptions;\n withCursor: boolean;\n }\n | {\n type: \"count\";\n table: AnyTable;\n indexName: string;\n options: Pick<IndexedDbFindOptions, \"where\">;\n };\n\nconst resolveFindCondition = <TTable extends AnyTable>(\n table: TTable,\n input: IndexedDbFindOptions<TTable>[\"where\"],\n): Condition | undefined | false => {\n if (!input) {\n return undefined;\n }\n if (typeof input === \"function\") {\n const built = buildCondition(table.columns, input);\n if (built === true) {\n return undefined;\n }\n return built;\n }\n return input;\n};\n\nexport const executeIndexedDbRetrievalOperation = async (options: {\n operation: IndexedDbRetrievalOperation;\n context: IndexedDbQueryContext;\n}): Promise<Record<string, unknown>[] | CursorResult<Record<string, unknown>> | number> => {\n const { operation, context } = options;\n const db = await context.getDb();\n const tx = db.transaction(ROWS_STORE, \"readonly\");\n const rowsStore = tx.objectStore(ROWS_STORE);\n\n const rows = await collectRows({\n rowsStore,\n endpointName: context.endpointName,\n schemaName: context.schemaName,\n tableName: operation.table.name,\n indexName: operation.indexName,\n });\n\n const condition =\n operation.options.where !== undefined\n ? resolveFindCondition(operation.table, operation.options.where)\n : undefined;\n\n if (condition === false) {\n await tx.done;\n if (operation.type === \"count\") {\n return 0;\n }\n return operation.withCursor ? { items: [], hasNextPage: false } : [];\n }\n\n if (operation.type === \"count\") {\n let count = 0;\n for (const row of rows) {\n if (\n condition &&\n !(await evaluateCondition(condition, operation.table, row, context, rowsStore))\n ) {\n continue;\n }\n count += 1;\n }\n await tx.done;\n return count;\n }\n\n const filtered: LofiRow[] = [];\n for (const row of rows) {\n if (\n condition &&\n !(await evaluateCondition(condition, operation.table, row, context, rowsStore))\n ) {\n continue;\n }\n filtered.push(row);\n }\n\n const orderIndexName = operation.options.orderByIndex?.indexName ?? operation.indexName;\n const direction = operation.options.orderByIndex?.direction ?? \"asc\";\n const orderColumns = buildOrderColumns(operation.table, orderIndexName);\n\n let ordered = orderRows(\n filtered,\n orderColumns.map((col) => [col, direction]),\n );\n ordered = applyCursorFilters({\n rows: ordered,\n orderColumns,\n direction,\n after: operation.options.after,\n before: operation.options.before,\n });\n\n const limit =\n operation.withCursor && operation.options.pageSize !== undefined\n ? operation.options.pageSize + 1\n : operation.options.pageSize;\n\n const results: RowSelection[] = [];\n const resultSources: LofiRow[] = [];\n const rowsByTable = new Map<string, LofiRow[]>();\n\n for (const row of ordered) {\n const select = operation.options.select as undefined | true | readonly string[];\n const baseOutput = selectRow(row, operation.table, select);\n\n if (operation.options.joins && operation.options.joins.length > 0) {\n const joined = await applyJoins({\n baseOutput,\n parentRow: row,\n parentTable: operation.table,\n joins: operation.options.joins,\n rowsByTable,\n context,\n rowsStore,\n });\n for (const joinedRow of joined) {\n results.push(joinedRow);\n resultSources.push(row);\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n } else {\n results.push(baseOutput);\n resultSources.push(row);\n }\n\n if (limit !== undefined && results.length >= limit) {\n break;\n }\n }\n\n await tx.done;\n\n const decoded = results.map((row) => decodeRow(row, operation.table));\n\n if (!operation.withCursor) {\n return decoded;\n }\n\n let cursor: Cursor | undefined;\n let hasNextPage = false;\n let items = decoded;\n\n if (\n operation.options.pageSize &&\n operation.options.pageSize > 0 &&\n decoded.length > operation.options.pageSize\n ) {\n hasNextPage = true;\n items = decoded.slice(0, operation.options.pageSize);\n\n const lastRow = items[items.length - 1];\n if (lastRow) {\n const cursorRecord: Record<string, unknown> = { ...lastRow };\n const sourceRow = resultSources[operation.options.pageSize - 1];\n for (const column of orderColumns) {\n if (cursorRecord[column.name] === undefined) {\n cursorRecord[column.name] = sourceRow\n ? buildOutputValueForColumn(sourceRow, column)\n : cursorRecord[column.name];\n }\n }\n\n cursor = createCursorFromRecord(cursorRecord, orderColumns, {\n indexName: orderIndexName,\n orderDirection: direction,\n pageSize: operation.options.pageSize,\n });\n }\n }\n\n return { items, cursor, hasNextPage };\n};\n\nconst applyCursorFilters = (options: {\n rows: LofiRow[];\n orderColumns: AnyColumn[];\n direction: \"asc\" | \"desc\";\n after?: Cursor | string;\n before?: Cursor | string;\n}): LofiRow[] => {\n const { rows, orderColumns, direction, after, before } = options;\n\n const afterValues = buildCursorValues(after, orderColumns);\n const beforeValues = buildCursorValues(before, orderColumns);\n\n return rows.filter((row) => {\n if (afterValues) {\n const comparison = compareRowToCursor(row, orderColumns, afterValues);\n if (direction === \"asc\" ? comparison <= 0 : comparison >= 0) {\n return false;\n }\n }\n\n if (beforeValues) {\n const comparison = compareRowToCursor(row, orderColumns, beforeValues);\n if (direction === \"asc\" ? comparison >= 0 : comparison <= 0) {\n return false;\n }\n }\n\n return true;\n });\n};\n\nexport const createIndexedDbQueryEngine = <T extends AnySchema>(options: {\n schema: T;\n endpointName: string;\n getDb: () => Promise<LofiDb>;\n referenceTargets: Map<string, ReferenceTarget>;\n schemaName?: string;\n}): LofiQueryInterface<T> => {\n const schemaName = options.schemaName ?? options.schema.name;\n const context: IndexedDbQueryContext = {\n endpointName: options.endpointName,\n schemaName,\n getDb: options.getDb,\n referenceTargets: options.referenceTargets,\n };\n\n const runFind = async (\n tableName: string,\n builderFn: ((builder: FindBuilder<AnyTable>) => unknown) | undefined,\n withCursor: boolean,\n ): Promise<Record<string, unknown>[] | CursorResult<Record<string, unknown>> | number> => {\n const tableMap = options.schema.tables as Record<string, AnyTable>;\n const table = tableMap[tableName];\n if (!table) {\n throw new Error(`Table ${tableName} not found in schema`);\n }\n\n const builder = buildFindBuilder(tableName, table);\n if (builderFn) {\n builderFn(builder);\n } else {\n builder.whereIndex(\"primary\");\n }\n\n const built = builder.build();\n if (built.type === \"count\") {\n return executeIndexedDbRetrievalOperation({\n operation: {\n type: \"count\",\n table,\n indexName: built.indexName,\n options: { where: built.options.where },\n },\n context,\n });\n }\n\n return executeIndexedDbRetrievalOperation({\n operation: {\n type: \"find\",\n table,\n indexName: built.indexName,\n options: built.options,\n withCursor,\n },\n context,\n });\n };\n\n const queryEngine = {\n async find(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn as unknown as (builder: FindBuilder<AnyTable>) => unknown,\n false,\n );\n return result as Record<string, unknown>[] | number;\n },\n\n async findWithCursor(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn as unknown as (builder: FindBuilder<AnyTable>) => unknown,\n true,\n );\n return result as CursorResult<Record<string, unknown>>;\n },\n\n async findFirst(tableName, builderFn) {\n const result = await runFind(\n tableName,\n builderFn\n ? (builder: FindBuilder<AnyTable>) => {\n (builderFn as unknown as (b: FindBuilder<AnyTable>) => unknown)(builder);\n builder.pageSize(1);\n return builder;\n }\n : (builder: FindBuilder<AnyTable>) => builder.whereIndex(\"primary\").pageSize(1),\n false,\n );\n\n if (typeof result === \"number\") {\n return null;\n }\n\n return (result as Record<string, unknown>[])[0] ?? null;\n },\n } as LofiQueryInterface<T>;\n\n return queryEngine;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scenario.d.ts","names":[],"sources":["../src/scenario.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"scenario.d.ts","names":[],"sources":["../src/scenario.ts"],"sourcesContent":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scenario.js","names":["read","command","adapter: InMemoryAdapter | undefined","fragment: ScenarioFragment","fetcher: typeof fetch","closeServer: (() => Promise<void>) | undefined","context: ScenarioContext<TSchema, TCommandContext, TVars>","adapters: ScenarioClientAdapters<TCommandContext>","_exhaustive: never","submit","sync"],"sources":["../src/scenario.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { defineFragment, instantiate, type AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport { toNodeHandler } from \"@fragno-dev/node\";\nimport { InMemoryAdapter, withDatabase, type SyncCommandRegistry } from \"@fragno-dev/db\";\nimport type { AnySchema } from \"@fragno-dev/db/schema\";\nimport { LofiClient } from \"./client/client\";\nimport { LofiSubmitClient } from \"./submit/client\";\nimport type {\n LofiAdapter,\n LofiQueryInterface,\n LofiQueryableAdapter,\n LofiSubmitCommandDefinition,\n LofiSubmitCommandTarget,\n LofiSubmitResponse,\n LofiSyncResult,\n} from \"./types\";\nimport { IndexedDbAdapter } from \"./indexeddb/adapter\";\nimport { InMemoryLofiAdapter } from \"./adapters/in-memory/adapter\";\nimport { StackedLofiAdapter } from \"./adapters/stacked/adapter\";\nimport { LofiOverlayManager } from \"./optimistic/overlay-manager\";\nimport type { InMemoryLofiStore } from \"./adapters/in-memory/store\";\n\nexport type ScenarioServerConfig<TSchema extends AnySchema = AnySchema> =\n | {\n fragmentName: string;\n schema: TSchema;\n syncCommands: SyncCommandRegistry;\n port?: number;\n baseUrl?: string;\n }\n | {\n fragment: AnyFragnoInstantiatedFragment;\n schema: TSchema;\n port?: number;\n baseUrl?: string;\n };\n\nexport type ScenarioClientConfig = {\n endpointName: string;\n adapter?: ScenarioClientAdapterConfig;\n};\n\nexport type ScenarioClientAdapterConfig =\n | {\n type: \"indexeddb\";\n dbName?: string;\n }\n | {\n type: \"in-memory\";\n store?: InMemoryLofiStore;\n }\n | {\n type: \"stacked\";\n base?: \"indexeddb\" | \"in-memory\";\n baseDbName?: string;\n baseStore?: InMemoryLofiStore;\n overlayStore?: InMemoryLofiStore;\n };\n\ntype NoInfer<T> = [T][T extends T ? 0 : never];\ntype BivariantCallback<T extends (...args: never[]) => unknown> = {\n bivarianceHack: T;\n}[\"bivarianceHack\"];\ntype ScenarioVars = Record<string, unknown>;\ntype KeysMatching<T, V> = {\n [K in keyof T]-?: Extract<T[K], V> extends never ? never : K;\n}[keyof T];\n\nexport type ScenarioIndexedDbGlobals = {\n indexedDB: unknown;\n IDBCursor?: unknown;\n IDBDatabase?: unknown;\n IDBIndex?: unknown;\n IDBKeyRange?: unknown;\n IDBObjectStore?: unknown;\n IDBOpenDBRequest?: unknown;\n IDBRequest?: unknown;\n IDBTransaction?: unknown;\n};\n\ntype ScenarioGlobalRestore = () => void;\n\nconst installIndexedDbGlobals = (\n globals?: ScenarioIndexedDbGlobals,\n): ScenarioGlobalRestore | undefined => {\n if (!globals) {\n return undefined;\n }\n const entries = Object.entries(globals) as Array<[keyof ScenarioIndexedDbGlobals, unknown]>;\n const previous = entries.map(([key]) => ({\n key,\n hadKey: key in globalThis,\n value: (globalThis as Record<string, unknown>)[key as string],\n }));\n\n for (const [key, value] of entries) {\n if (value !== undefined) {\n (globalThis as Record<string, unknown>)[key as string] = value;\n }\n }\n\n return () => {\n for (const entry of previous) {\n if (!entry.hadKey) {\n delete (globalThis as Record<string, unknown>)[entry.key as string];\n continue;\n }\n (globalThis as Record<string, unknown>)[entry.key as string] = entry.value;\n }\n };\n};\n\nexport type ScenarioDefinition<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TCommands extends\n ReadonlyArray<LofiSubmitCommandDefinition> = ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n name: string;\n server: ScenarioServerConfig<TSchema>;\n clientCommands: TCommands;\n clients: Record<string, ScenarioClientConfig>;\n steps: ScenarioStep<NoInfer<TSchema>, NoInfer<TCommandContext>, NoInfer<TVars>>[];\n createClientContext?: (clientName: string) => TCommandContext;\n};\n\nexport type RunScenarioOptions = {\n indexedDbGlobals?: ScenarioIndexedDbGlobals;\n};\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\ntype ScenarioFragment = {\n handler: (req: Request) => Promise<Response>;\n callRouteRaw: (method: HTTPMethod, path: string, inputOptions?: unknown) => Promise<Response>;\n};\n\nexport type ScenarioContext<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n name: string;\n server: {\n adapter?: InMemoryAdapter;\n fragment: ScenarioFragment;\n baseUrl: string;\n };\n clients: Record<string, ScenarioClient<TSchema, TCommandContext>>;\n vars: Partial<TVars>;\n lastSubmit: Record<string, LofiSubmitResponse | undefined>;\n lastSync: Record<string, LofiSyncResult | undefined>;\n cleanup: () => Promise<void>;\n};\n\nexport type ScenarioClient<TSchema extends AnySchema = AnySchema, TCommandContext = unknown> = {\n name: string;\n endpointName: string;\n adapter: LofiAdapter & LofiQueryableAdapter;\n submit: LofiSubmitClient<TCommandContext>;\n sync: LofiClient;\n query: LofiQueryInterface<TSchema>;\n baseQuery: LofiQueryInterface<TSchema>;\n overlayQuery?: LofiQueryInterface<TSchema>;\n adapters: {\n base: LofiAdapter & LofiQueryableAdapter;\n overlay?: InMemoryLofiAdapter;\n stacked?: StackedLofiAdapter;\n };\n stores: {\n base?: InMemoryLofiStore;\n overlay?: InMemoryLofiStore;\n };\n overlayManager?: LofiOverlayManager<TCommandContext>;\n};\n\ntype CommandInput<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = unknown | CommandInputFn<TSchema, TCommandContext, TVars>;\ntype CommandInputFn<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => unknown | Promise<unknown>;\ntype ReadFn<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n T = unknown,\n> =\n | BivariantCallback<(ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => T | Promise<T>>\n | BivariantCallback<\n (\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n ) => T | Promise<T>\n >;\n\nexport type ScenarioCommandStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"command\";\n client: string;\n name: string;\n input: CommandInput<TSchema, TCommandContext, TVars>;\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n};\n\nexport type ScenarioSubmitStep = {\n type: \"submit\";\n client: string;\n};\n\nexport type ScenarioSyncStep = {\n type: \"sync\";\n client: string;\n};\n\nexport type ScenarioReadStepWithStore<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n K extends keyof TVars = keyof TVars,\n> = {\n type: \"read\";\n client: string;\n read: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>;\n storeAs: K;\n};\n\nexport type ScenarioReadStepNoStore<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"read\";\n client: string;\n read: ReadFn<TSchema, TCommandContext, TVars>;\n storeAs?: undefined;\n};\n\nexport type ScenarioReadStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> =\n | ScenarioReadStepWithStore<TSchema, TCommandContext, TVars>\n | ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\n\nexport type ScenarioAssertStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"assert\";\n assert: BivariantCallback<\n (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => void | Promise<void>\n >;\n};\n\nexport type ScenarioStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> =\n | ScenarioCommandStep<TSchema, TCommandContext, TVars>\n | ScenarioSubmitStep\n | ScenarioSyncStep\n | ScenarioReadStep<TSchema, TCommandContext, TVars>\n | ScenarioAssertStep<TSchema, TCommandContext, TVars>;\n\nexport function defineScenario<\n TSchema extends AnySchema,\n TCommandContext,\n TCommands extends\n ReadonlyArray<LofiSubmitCommandDefinition> = ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars> & {\n createClientContext: (clientName: string) => TCommandContext;\n },\n): ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>;\nexport function defineScenario<\n TSchema extends AnySchema,\n TCommandContext = unknown,\n TCommands extends\n ReadonlyArray<LofiSubmitCommandDefinition> = ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>,\n): ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>;\nexport function defineScenario(scenario: ScenarioDefinition): ScenarioDefinition {\n return scenario;\n}\n\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: CommandInputFn<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: unknown,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: CommandInput<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars> {\n return {\n type: \"command\",\n client,\n name,\n input,\n target: options?.target,\n optimistic: options?.optimistic,\n submit: options?.submit,\n storeCommandIdAs: options?.storeCommandIdAs,\n };\n}\n\nconst submit = (client: string): ScenarioSubmitStep => ({ type: \"submit\", client });\nconst sync = (client: string): ScenarioSyncStep => ({ type: \"sync\", client });\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n K extends keyof TVars = keyof TVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n): ScenarioReadStepWithStore<TSchema, TCommandContext, TVars, K>;\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: undefined,\n): ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: keyof TVars,\n): ScenarioReadStep<TSchema, TCommandContext, TVars> {\n if (storeAs === undefined) {\n return { type: \"read\", client, read } as ScenarioReadStepNoStore<\n TSchema,\n TCommandContext,\n TVars\n >;\n }\n return { type: \"read\", client, read, storeAs } as ScenarioReadStepWithStore<\n TSchema,\n TCommandContext,\n TVars\n >;\n}\nfunction assert<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n assert: ScenarioAssertStep<TSchema, TCommandContext, TVars>[\"assert\"],\n): ScenarioAssertStep<TSchema, TCommandContext, TVars> {\n return {\n type: \"assert\",\n assert,\n };\n}\nexport const createScenarioSteps = <\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>() => ({\n command: (() => {\n function commandStep(\n client: string,\n name: string,\n input: CommandInputFn<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\n function commandStep(\n client: string,\n name: string,\n input: unknown,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\n function commandStep(\n client: string,\n name: string,\n input: CommandInput<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars> {\n return command<TSchema, TCommandContext, TVars>(client, name, input, options);\n }\n return commandStep;\n })(),\n submit,\n sync,\n read: (<K extends keyof TVars>(\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n ) => read<TSchema, TCommandContext, TVars, K>(client, readFn, storeAs)) as {\n <K extends keyof TVars>(\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n ): ScenarioReadStepWithStore<TSchema, TCommandContext, TVars, K>;\n (\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: undefined,\n ): ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\n },\n assert: (assertFn: ScenarioAssertStep<TSchema, TCommandContext, TVars>[\"assert\"]) =>\n assert<TSchema, TCommandContext, TVars>(assertFn),\n});\n\nexport const steps = createScenarioSteps();\n\nconst createServerFetch = (fragment: ScenarioFragment) => {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url = new URL(typeof input === \"string\" ? input : input.toString());\n const method = ((init?.method ?? \"GET\").toUpperCase() as HTTPMethod) ?? \"GET\";\n const headers = init?.headers ? new Headers(init.headers) : undefined;\n const body = init?.body ? JSON.parse(init.body as string) : undefined;\n\n return fragment.callRouteRaw(method, url.pathname, {\n query: url.searchParams,\n body,\n headers,\n });\n };\n};\n\nconst resolveCommandInput = async <\n TSchema extends AnySchema,\n TCommandContext,\n TVars extends ScenarioVars,\n>(\n input: CommandInput<TSchema, TCommandContext, TVars>,\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n): Promise<unknown> => {\n if (typeof input === \"function\") {\n return await input(ctx);\n }\n return input;\n};\n\nconst resolveReadResult = async <\n TSchema extends AnySchema,\n TCommandContext,\n TVars extends ScenarioVars,\n T = unknown,\n>(\n read: ReadFn<TSchema, TCommandContext, TVars, T>,\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n): Promise<T> => {\n if (read.length >= 2) {\n return await (\n read as (\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n ) => T\n )(ctx, client);\n }\n return await (read as (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => T)(ctx);\n};\n\ntype ScenarioClientAdapters<TCommandContext = unknown> = {\n adapter: LofiAdapter & LofiQueryableAdapter;\n baseAdapter: LofiAdapter & LofiQueryableAdapter;\n overlayAdapter?: InMemoryLofiAdapter;\n stackedAdapter?: StackedLofiAdapter;\n overlayManager?: LofiOverlayManager<TCommandContext>;\n baseStore?: InMemoryLofiStore;\n overlayStore?: InMemoryLofiStore;\n};\n\nconst startScenarioServer = async (\n fragment: ScenarioFragment,\n port: number,\n): Promise<{ baseUrl: string; close: () => Promise<void> }> => {\n const server = createServer(toNodeHandler(fragment.handler));\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address() as AddressInfo;\n const baseUrl = `http://127.0.0.1:${address.port}`;\n\n return {\n baseUrl,\n close: async () =>\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n }),\n };\n};\n\nconst resolveMountRoute = (fragment: ScenarioFragment): string | undefined => {\n if (\"mountRoute\" in fragment && typeof fragment.mountRoute === \"string\") {\n return fragment.mountRoute;\n }\n return undefined;\n};\n\nconst resolveCommandTarget = <TCommandContext = unknown>(\n commandName: string,\n commands: ReadonlyArray<LofiSubmitCommandDefinition<unknown, TCommandContext>>,\n): LofiSubmitCommandTarget | undefined => {\n for (const command of commands) {\n if (command.name === commandName) {\n return command.target;\n }\n }\n return undefined;\n};\n\nconst isScenarioDefinitionConfig = <TSchema extends AnySchema>(\n config: ScenarioServerConfig<TSchema>,\n): config is Extract<\n ScenarioServerConfig<TSchema>,\n { fragmentName: string; schema: TSchema; syncCommands: SyncCommandRegistry }\n> => \"fragmentName\" in config;\n\nconst isScenarioFragmentConfig = <TSchema extends AnySchema>(\n config: ScenarioServerConfig<TSchema>,\n): config is Extract<ScenarioServerConfig<TSchema>, { fragment: AnyFragnoInstantiatedFragment }> =>\n \"fragment\" in config;\n\nexport const runScenario = async <\n TSchema extends AnySchema,\n TCommandContext = unknown,\n TCommands extends\n ReadonlyArray<LofiSubmitCommandDefinition> = ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>,\n options?: RunScenarioOptions,\n): Promise<ScenarioContext<TSchema, TCommandContext, TVars>> => {\n let adapter: InMemoryAdapter | undefined;\n let fragment: ScenarioFragment;\n\n const restoreGlobals = installIndexedDbGlobals(options?.indexedDbGlobals);\n\n if (isScenarioDefinitionConfig(scenario.server)) {\n adapter = new InMemoryAdapter({ idSeed: `lofi-scenario-${scenario.name}` });\n const fragmentDef = defineFragment(scenario.server.fragmentName)\n .extend(withDatabase(scenario.server.schema))\n .withSyncCommands(scenario.server.syncCommands)\n .build();\n\n fragment = instantiate(fragmentDef)\n .withConfig({})\n .withRoutes([])\n .withOptions({ databaseAdapter: adapter, outbox: { enabled: true } })\n .build() as unknown as ScenarioFragment;\n } else if (isScenarioFragmentConfig(scenario.server)) {\n fragment = scenario.server.fragment as unknown as ScenarioFragment;\n } else {\n throw new Error(\"Scenario server must include fragment configuration.\");\n }\n\n const shouldStartServer = typeof scenario.server.port === \"number\";\n const baseUrlOverride = scenario.server.baseUrl;\n let fetcher: typeof fetch = createServerFetch(fragment);\n let baseUrl = baseUrlOverride ?? \"http://lofi-scenario.test\";\n let closeServer: (() => Promise<void>) | undefined;\n\n if (shouldStartServer) {\n const { baseUrl: serverUrl, close } = await startScenarioServer(\n fragment,\n scenario.server.port as number,\n );\n const mountRoute = resolveMountRoute(fragment);\n baseUrl = baseUrlOverride ?? `${serverUrl}${mountRoute ?? \"\"}`;\n fetcher = fetch.bind(globalThis);\n closeServer = close;\n }\n\n const context: ScenarioContext<TSchema, TCommandContext, TVars> = {\n name: scenario.name,\n server: {\n adapter,\n fragment,\n baseUrl,\n },\n clients: {},\n vars: {},\n lastSubmit: {},\n lastSync: {},\n cleanup: async () => {\n if (closeServer) {\n await closeServer();\n }\n if (adapter) {\n await adapter.close();\n }\n if (restoreGlobals) {\n restoreGlobals();\n }\n },\n };\n try {\n const clientCommands = Array.from(scenario.clientCommands) as Array<\n LofiSubmitCommandDefinition<unknown, TCommandContext>\n >;\n\n for (const [name, clientConfig] of Object.entries(scenario.clients)) {\n const dbName = `lofi-scenario-${scenario.name}-${name}-${Math.random().toString(16).slice(2)}`;\n const createClientContext = scenario.createClientContext;\n const createCommandContext = createClientContext\n ? (_command: LofiSubmitCommandDefinition<unknown, TCommandContext>) =>\n createClientContext(name)\n : undefined;\n const adapterConfig = clientConfig.adapter;\n const schema = scenario.server.schema;\n\n const adapters: ScenarioClientAdapters<TCommandContext> = (() => {\n if (!adapterConfig || adapterConfig.type === \"indexeddb\") {\n const baseAdapter = new IndexedDbAdapter({\n dbName: adapterConfig?.dbName ?? dbName,\n endpointName: clientConfig.endpointName,\n schemas: [{ schema }],\n });\n return {\n adapter: baseAdapter,\n baseAdapter,\n };\n }\n\n if (adapterConfig.type === \"in-memory\") {\n const baseAdapter = new InMemoryLofiAdapter({\n endpointName: clientConfig.endpointName,\n schemas: [schema],\n ...(adapterConfig.store ? { store: adapterConfig.store } : {}),\n });\n return {\n adapter: baseAdapter,\n baseAdapter,\n baseStore: baseAdapter.store,\n };\n }\n\n if (adapterConfig.type === \"stacked\") {\n const baseKind = adapterConfig.base ?? \"indexeddb\";\n const baseAdapter =\n baseKind === \"in-memory\"\n ? new InMemoryLofiAdapter({\n endpointName: clientConfig.endpointName,\n schemas: [schema],\n ...(adapterConfig.baseStore ? { store: adapterConfig.baseStore } : {}),\n })\n : new IndexedDbAdapter({\n dbName: adapterConfig.baseDbName ?? dbName,\n endpointName: clientConfig.endpointName,\n schemas: [{ schema }],\n });\n\n const overlayManager = new LofiOverlayManager({\n endpointName: clientConfig.endpointName,\n adapter: baseAdapter,\n schemas: [schema],\n commands: clientCommands,\n ...(createCommandContext ? { createCommandContext } : {}),\n ...(adapterConfig.overlayStore ? { store: adapterConfig.overlayStore } : {}),\n });\n\n return {\n adapter: overlayManager.stackedAdapter,\n baseAdapter,\n overlayAdapter: overlayManager.overlayAdapter,\n stackedAdapter: overlayManager.stackedAdapter,\n overlayManager,\n baseStore: baseAdapter instanceof InMemoryLofiAdapter ? baseAdapter.store : undefined,\n overlayStore: overlayManager.store,\n };\n }\n\n const _exhaustive: never = adapterConfig;\n throw new Error(`Unsupported scenario adapter config: ${String(_exhaustive)}`);\n })();\n\n const submit = new LofiSubmitClient<TCommandContext>({\n endpointName: clientConfig.endpointName,\n submitUrl: `${baseUrl}/_internal/sync`,\n internalUrl: `${baseUrl}/_internal`,\n adapter: adapters.adapter,\n schemas: [schema],\n commands: clientCommands,\n fetch: fetcher,\n ...(createCommandContext ? { createCommandContext } : {}),\n ...(adapters.overlayManager ? { overlay: adapters.overlayManager } : {}),\n });\n\n const sync = new LofiClient({\n endpointName: clientConfig.endpointName,\n outboxUrl: `${baseUrl}/_internal/outbox`,\n adapter: adapters.adapter,\n fetch: fetcher,\n });\n\n const queryAdapter = adapters.stackedAdapter ?? adapters.baseAdapter;\n\n context.clients[name] = {\n name,\n endpointName: clientConfig.endpointName,\n adapter: adapters.adapter,\n submit,\n sync,\n query: queryAdapter.createQueryEngine(schema),\n baseQuery: adapters.baseAdapter.createQueryEngine(schema),\n overlayQuery: adapters.overlayAdapter\n ? adapters.overlayAdapter.createQueryEngine(schema)\n : undefined,\n adapters: {\n base: adapters.baseAdapter,\n overlay: adapters.overlayAdapter,\n stacked: adapters.stackedAdapter,\n },\n stores: {\n base: adapters.baseStore,\n overlay: adapters.overlayStore,\n },\n overlayManager: adapters.overlayManager,\n };\n }\n\n for (const step of scenario.steps) {\n if (step.type === \"assert\") {\n await step.assert(context);\n continue;\n }\n\n const client = context.clients[step.client];\n if (!client) {\n throw new Error(`Unknown scenario client: ${step.client}`);\n }\n\n if (step.type === \"command\") {\n const input = await resolveCommandInput(step.input, context);\n const target = step.target ?? resolveCommandTarget(step.name, clientCommands) ?? null;\n if (!target) {\n throw new Error(`Unknown scenario command target: ${step.name}`);\n }\n\n const commandId = await client.submit.queueCommand({\n name: step.name,\n target,\n input,\n optimistic: step.optimistic,\n });\n\n if (step.storeCommandIdAs !== undefined) {\n context.vars[step.storeCommandIdAs] = commandId as TVars[KeysMatching<TVars, string> &\n string];\n }\n\n if (step.submit) {\n context.lastSubmit[step.client] = await client.submit.submitOnce();\n }\n\n continue;\n }\n\n if (step.type === \"submit\") {\n context.lastSubmit[step.client] = await client.submit.submitOnce();\n continue;\n }\n\n if (step.type === \"sync\") {\n context.lastSync[step.client] = await client.sync.syncOnce();\n continue;\n }\n\n if (step.type === \"read\") {\n const result = await resolveReadResult(step.read, context, client);\n if (step.storeAs !== undefined) {\n context.vars[step.storeAs] = result as TVars[keyof TVars];\n }\n continue;\n }\n }\n\n return context;\n } catch (error) {\n await context.cleanup();\n throw error;\n }\n};\n"],"mappings":";;;;;;;;;;;;AAmFA,MAAM,2BACJ,YACsC;AACtC,KAAI,CAAC,QACH;CAEF,MAAM,UAAU,OAAO,QAAQ,QAAQ;CACvC,MAAM,WAAW,QAAQ,KAAK,CAAC,UAAU;EACvC;EACA,QAAQ,OAAO;EACf,OAAQ,WAAuC;EAChD,EAAE;AAEH,MAAK,MAAM,CAAC,KAAK,UAAU,QACzB,KAAI,UAAU,OACZ,CAAC,WAAuC,OAAiB;AAI7D,cAAa;AACX,OAAK,MAAM,SAAS,UAAU;AAC5B,OAAI,CAAC,MAAM,QAAQ;AACjB,WAAQ,WAAuC,MAAM;AACrD;;AAEF,GAAC,WAAuC,MAAM,OAAiB,MAAM;;;;AAgM3E,SAAgB,eAAe,UAAkD;AAC/E,QAAO;;AAiCT,SAAS,QAKP,QACA,MACA,OACA,SAMsD;AACtD,QAAO;EACL,MAAM;EACN;EACA;EACA;EACA,QAAQ,SAAS;EACjB,YAAY,SAAS;EACrB,QAAQ,SAAS;EACjB,kBAAkB,SAAS;EAC5B;;AAGH,MAAM,UAAU,YAAwC;CAAE,MAAM;CAAU;CAAQ;AAClF,MAAM,QAAQ,YAAsC;CAAE,MAAM;CAAQ;CAAQ;AAoB5E,SAAS,KAKP,QACA,QACA,SACmD;AACnD,KAAI,YAAY,OACd,QAAO;EAAE,MAAM;EAAQ;EAAQ;EAAM;AAMvC,QAAO;EAAE,MAAM;EAAQ;EAAQ;EAAM;EAAS;;AAMhD,SAAS,OAKP,UACqD;AACrD,QAAO;EACL,MAAM;EACN;EACD;;AAEH,MAAa,6BAIL;CACN,gBAAgB;EAuBd,SAAS,YACP,QACA,MACA,OACA,SAMsD;AACtD,UAAO,QAAyC,QAAQ,MAAM,OAAO,QAAQ;;AAE/E,SAAO;KACL;CACJ;CACA;CACA,QACE,QACA,QACA,YACG,KAAyC,QAAQ,QAAQ,QAAQ;CAYtE,SAAS,aACP,OAAwC,SAAS;CACpD;AAED,MAAa,QAAQ,qBAAqB;AAE1C,MAAM,qBAAqB,aAA+B;AACxD,QAAO,OAAO,OAA0B,SAA0C;EAChF,MAAM,MAAM,IAAI,IAAI,OAAO,UAAU,WAAW,QAAQ,MAAM,UAAU,CAAC;EACzE,MAAM,UAAW,MAAM,UAAU,OAAO,aAAa,IAAmB;EACxE,MAAM,UAAU,MAAM,UAAU,IAAI,QAAQ,KAAK,QAAQ,GAAG;EAC5D,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,KAAK,KAAe,GAAG;AAE5D,SAAO,SAAS,aAAa,QAAQ,IAAI,UAAU;GACjD,OAAO,IAAI;GACX;GACA;GACD,CAAC;;;AAIN,MAAM,sBAAsB,OAK1B,OACA,QACqB;AACrB,KAAI,OAAO,UAAU,WACnB,QAAO,MAAM,MAAM,IAAI;AAEzB,QAAO;;AAGT,MAAM,oBAAoB,OAMxB,QACA,KACA,WACe;AACf,KAAIA,OAAK,UAAU,EACjB,QAAO,MACLA,OAIA,KAAK,OAAO;AAEhB,QAAO,MAAOA,OAAsE,IAAI;;AAa1F,MAAM,sBAAsB,OAC1B,UACA,SAC6D;CAC7D,MAAM,SAAS,aAAa,cAAc,SAAS,QAAQ,CAAC;AAE5D,OAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,SAAO,KAAK,SAAS,OAAO;AAC5B,SAAO,OAAO,MAAM,mBAAmB,SAAS,CAAC;GACjD;AAKF,QAAO;EACL,SAHc,oBADA,OAAO,SAAS,CACY;EAI1C,OAAO,YACL,MAAM,IAAI,SAAe,SAAS,WAAW;AAC3C,UAAO,OAAO,QAAQ;AACpB,QAAI,KAAK;AACP,YAAO,IAAI;AACX;;AAEF,aAAS;KACT;IACF;EACL;;AAGH,MAAM,qBAAqB,aAAmD;AAC5E,KAAI,gBAAgB,YAAY,OAAO,SAAS,eAAe,SAC7D,QAAO,SAAS;;AAKpB,MAAM,wBACJ,aACA,aACwC;AACxC,MAAK,MAAMC,aAAW,SACpB,KAAIA,UAAQ,SAAS,YACnB,QAAOA,UAAQ;;AAMrB,MAAM,8BACJ,WAIG,kBAAkB;AAEvB,MAAM,4BACJ,WAEA,cAAc;AAEhB,MAAa,cAAc,OAOzB,UACA,YAC8D;CAC9D,IAAIC;CACJ,IAAIC;CAEJ,MAAM,iBAAiB,wBAAwB,SAAS,iBAAiB;AAEzE,KAAI,2BAA2B,SAAS,OAAO,EAAE;AAC/C,YAAU,IAAI,gBAAgB,EAAE,QAAQ,iBAAiB,SAAS,QAAQ,CAAC;AAM3E,aAAW,YALS,eAAe,SAAS,OAAO,aAAa,CAC7D,OAAO,aAAa,SAAS,OAAO,OAAO,CAAC,CAC5C,iBAAiB,SAAS,OAAO,aAAa,CAC9C,OAAO,CAEyB,CAChC,WAAW,EAAE,CAAC,CACd,WAAW,EAAE,CAAC,CACd,YAAY;GAAE,iBAAiB;GAAS,QAAQ,EAAE,SAAS,MAAM;GAAE,CAAC,CACpE,OAAO;YACD,yBAAyB,SAAS,OAAO,CAClD,YAAW,SAAS,OAAO;KAE3B,OAAM,IAAI,MAAM,uDAAuD;CAGzE,MAAM,oBAAoB,OAAO,SAAS,OAAO,SAAS;CAC1D,MAAM,kBAAkB,SAAS,OAAO;CACxC,IAAIC,UAAwB,kBAAkB,SAAS;CACvD,IAAI,UAAU,mBAAmB;CACjC,IAAIC;AAEJ,KAAI,mBAAmB;EACrB,MAAM,EAAE,SAAS,WAAW,UAAU,MAAM,oBAC1C,UACA,SAAS,OAAO,KACjB;EACD,MAAM,aAAa,kBAAkB,SAAS;AAC9C,YAAU,mBAAmB,GAAG,YAAY,cAAc;AAC1D,YAAU,MAAM,KAAK,WAAW;AAChC,gBAAc;;CAGhB,MAAMC,UAA4D;EAChE,MAAM,SAAS;EACf,QAAQ;GACN;GACA;GACA;GACD;EACD,SAAS,EAAE;EACX,MAAM,EAAE;EACR,YAAY,EAAE;EACd,UAAU,EAAE;EACZ,SAAS,YAAY;AACnB,OAAI,YACF,OAAM,aAAa;AAErB,OAAI,QACF,OAAM,QAAQ,OAAO;AAEvB,OAAI,eACF,iBAAgB;;EAGrB;AACD,KAAI;EACF,MAAM,iBAAiB,MAAM,KAAK,SAAS,eAAe;AAI1D,OAAK,MAAM,CAAC,MAAM,iBAAiB,OAAO,QAAQ,SAAS,QAAQ,EAAE;GACnE,MAAM,SAAS,iBAAiB,SAAS,KAAK,GAAG,KAAK,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;GAC5F,MAAM,sBAAsB,SAAS;GACrC,MAAM,uBAAuB,uBACxB,aACC,oBAAoB,KAAK,GAC3B;GACJ,MAAM,gBAAgB,aAAa;GACnC,MAAM,SAAS,SAAS,OAAO;GAE/B,MAAMC,kBAA2D;AAC/D,QAAI,CAAC,iBAAiB,cAAc,SAAS,aAAa;KACxD,MAAM,cAAc,IAAI,iBAAiB;MACvC,QAAQ,eAAe,UAAU;MACjC,cAAc,aAAa;MAC3B,SAAS,CAAC,EAAE,QAAQ,CAAC;MACtB,CAAC;AACF,YAAO;MACL,SAAS;MACT;MACD;;AAGH,QAAI,cAAc,SAAS,aAAa;KACtC,MAAM,cAAc,IAAI,oBAAoB;MAC1C,cAAc,aAAa;MAC3B,SAAS,CAAC,OAAO;MACjB,GAAI,cAAc,QAAQ,EAAE,OAAO,cAAc,OAAO,GAAG,EAAE;MAC9D,CAAC;AACF,YAAO;MACL,SAAS;MACT;MACA,WAAW,YAAY;MACxB;;AAGH,QAAI,cAAc,SAAS,WAAW;KAEpC,MAAM,eADW,cAAc,QAAQ,iBAExB,cACT,IAAI,oBAAoB;MACtB,cAAc,aAAa;MAC3B,SAAS,CAAC,OAAO;MACjB,GAAI,cAAc,YAAY,EAAE,OAAO,cAAc,WAAW,GAAG,EAAE;MACtE,CAAC,GACF,IAAI,iBAAiB;MACnB,QAAQ,cAAc,cAAc;MACpC,cAAc,aAAa;MAC3B,SAAS,CAAC,EAAE,QAAQ,CAAC;MACtB,CAAC;KAER,MAAM,iBAAiB,IAAI,mBAAmB;MAC5C,cAAc,aAAa;MAC3B,SAAS;MACT,SAAS,CAAC,OAAO;MACjB,UAAU;MACV,GAAI,uBAAuB,EAAE,sBAAsB,GAAG,EAAE;MACxD,GAAI,cAAc,eAAe,EAAE,OAAO,cAAc,cAAc,GAAG,EAAE;MAC5E,CAAC;AAEF,YAAO;MACL,SAAS,eAAe;MACxB;MACA,gBAAgB,eAAe;MAC/B,gBAAgB,eAAe;MAC/B;MACA,WAAW,uBAAuB,sBAAsB,YAAY,QAAQ;MAC5E,cAAc,eAAe;MAC9B;;IAGH,MAAMC,cAAqB;AAC3B,UAAM,IAAI,MAAM,wCAAwC,OAAO,YAAY,GAAG;OAC5E;GAEJ,MAAMC,WAAS,IAAI,iBAAkC;IACnD,cAAc,aAAa;IAC3B,WAAW,GAAG,QAAQ;IACtB,aAAa,GAAG,QAAQ;IACxB,SAAS,SAAS;IAClB,SAAS,CAAC,OAAO;IACjB,UAAU;IACV,OAAO;IACP,GAAI,uBAAuB,EAAE,sBAAsB,GAAG,EAAE;IACxD,GAAI,SAAS,iBAAiB,EAAE,SAAS,SAAS,gBAAgB,GAAG,EAAE;IACxE,CAAC;GAEF,MAAMC,SAAO,IAAI,WAAW;IAC1B,cAAc,aAAa;IAC3B,WAAW,GAAG,QAAQ;IACtB,SAAS,SAAS;IAClB,OAAO;IACR,CAAC;GAEF,MAAM,eAAe,SAAS,kBAAkB,SAAS;AAEzD,WAAQ,QAAQ,QAAQ;IACtB;IACA,cAAc,aAAa;IAC3B,SAAS,SAAS;IAClB;IACA;IACA,OAAO,aAAa,kBAAkB,OAAO;IAC7C,WAAW,SAAS,YAAY,kBAAkB,OAAO;IACzD,cAAc,SAAS,iBACnB,SAAS,eAAe,kBAAkB,OAAO,GACjD;IACJ,UAAU;KACR,MAAM,SAAS;KACf,SAAS,SAAS;KAClB,SAAS,SAAS;KACnB;IACD,QAAQ;KACN,MAAM,SAAS;KACf,SAAS,SAAS;KACnB;IACD,gBAAgB,SAAS;IAC1B;;AAGH,OAAK,MAAM,QAAQ,SAAS,OAAO;AACjC,OAAI,KAAK,SAAS,UAAU;AAC1B,UAAM,KAAK,OAAO,QAAQ;AAC1B;;GAGF,MAAM,SAAS,QAAQ,QAAQ,KAAK;AACpC,OAAI,CAAC,OACH,OAAM,IAAI,MAAM,4BAA4B,KAAK,SAAS;AAG5D,OAAI,KAAK,SAAS,WAAW;IAC3B,MAAM,QAAQ,MAAM,oBAAoB,KAAK,OAAO,QAAQ;IAC5D,MAAM,SAAS,KAAK,UAAU,qBAAqB,KAAK,MAAM,eAAe,IAAI;AACjF,QAAI,CAAC,OACH,OAAM,IAAI,MAAM,oCAAoC,KAAK,OAAO;IAGlE,MAAM,YAAY,MAAM,OAAO,OAAO,aAAa;KACjD,MAAM,KAAK;KACX;KACA;KACA,YAAY,KAAK;KAClB,CAAC;AAEF,QAAI,KAAK,qBAAqB,OAC5B,SAAQ,KAAK,KAAK,oBAAoB;AAIxC,QAAI,KAAK,OACP,SAAQ,WAAW,KAAK,UAAU,MAAM,OAAO,OAAO,YAAY;AAGpE;;AAGF,OAAI,KAAK,SAAS,UAAU;AAC1B,YAAQ,WAAW,KAAK,UAAU,MAAM,OAAO,OAAO,YAAY;AAClE;;AAGF,OAAI,KAAK,SAAS,QAAQ;AACxB,YAAQ,SAAS,KAAK,UAAU,MAAM,OAAO,KAAK,UAAU;AAC5D;;AAGF,OAAI,KAAK,SAAS,QAAQ;IACxB,MAAM,SAAS,MAAM,kBAAkB,KAAK,MAAM,SAAS,OAAO;AAClE,QAAI,KAAK,YAAY,OACnB,SAAQ,KAAK,KAAK,WAAW;AAE/B;;;AAIJ,SAAO;UACA,OAAO;AACd,QAAM,QAAQ,SAAS;AACvB,QAAM"}
1
+ {"version":3,"file":"scenario.js","names":["read","command","adapter: InMemoryAdapter | undefined","fragment: ScenarioFragment","fetcher: typeof fetch","closeServer: (() => Promise<void>) | undefined","context: ScenarioContext<TSchema, TCommandContext, TVars>","adapters: ScenarioClientAdapters<TCommandContext>","_exhaustive: never","submit","sync"],"sources":["../src/scenario.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\n\nimport type { AnySchema } from \"@fragno-dev/db/schema\";\n\nimport { defineFragment, instantiate, type AnyFragnoInstantiatedFragment } from \"@fragno-dev/core\";\nimport { InMemoryAdapter, withDatabase, type SyncCommandRegistry } from \"@fragno-dev/db\";\nimport { toNodeHandler } from \"@fragno-dev/node\";\n\nimport { InMemoryLofiAdapter } from \"./adapters/in-memory/adapter\";\nimport type { InMemoryLofiStore } from \"./adapters/in-memory/store\";\nimport { StackedLofiAdapter } from \"./adapters/stacked/adapter\";\nimport { LofiClient } from \"./client/client\";\nimport { IndexedDbAdapter } from \"./indexeddb/adapter\";\nimport { LofiOverlayManager } from \"./optimistic/overlay-manager\";\nimport { LofiSubmitClient } from \"./submit/client\";\nimport type {\n LofiAdapter,\n LofiQueryInterface,\n LofiQueryableAdapter,\n LofiSubmitCommandDefinition,\n LofiSubmitCommandTarget,\n LofiSubmitResponse,\n LofiSyncResult,\n} from \"./types\";\n\nexport type ScenarioServerConfig<TSchema extends AnySchema = AnySchema> =\n | {\n fragmentName: string;\n schema: TSchema;\n syncCommands: SyncCommandRegistry;\n port?: number;\n baseUrl?: string;\n }\n | {\n fragment: AnyFragnoInstantiatedFragment;\n schema: TSchema;\n port?: number;\n baseUrl?: string;\n };\n\nexport type ScenarioClientConfig = {\n endpointName: string;\n adapter?: ScenarioClientAdapterConfig;\n};\n\nexport type ScenarioClientAdapterConfig =\n | {\n type: \"indexeddb\";\n dbName?: string;\n }\n | {\n type: \"in-memory\";\n store?: InMemoryLofiStore;\n }\n | {\n type: \"stacked\";\n base?: \"indexeddb\" | \"in-memory\";\n baseDbName?: string;\n baseStore?: InMemoryLofiStore;\n overlayStore?: InMemoryLofiStore;\n };\n\ntype NoInfer<T> = [T][T extends T ? 0 : never];\ntype BivariantCallback<T extends (...args: never[]) => unknown> = {\n bivarianceHack: T;\n}[\"bivarianceHack\"];\ntype ScenarioVars = Record<string, unknown>;\ntype KeysMatching<T, V> = {\n [K in keyof T]-?: Extract<T[K], V> extends never ? never : K;\n}[keyof T];\n\nexport type ScenarioIndexedDbGlobals = {\n indexedDB: unknown;\n IDBCursor?: unknown;\n IDBDatabase?: unknown;\n IDBIndex?: unknown;\n IDBKeyRange?: unknown;\n IDBObjectStore?: unknown;\n IDBOpenDBRequest?: unknown;\n IDBRequest?: unknown;\n IDBTransaction?: unknown;\n};\n\ntype ScenarioGlobalRestore = () => void;\n\nconst installIndexedDbGlobals = (\n globals?: ScenarioIndexedDbGlobals,\n): ScenarioGlobalRestore | undefined => {\n if (!globals) {\n return undefined;\n }\n const entries = Object.entries(globals) as Array<[keyof ScenarioIndexedDbGlobals, unknown]>;\n const previous = entries.map(([key]) => ({\n key,\n hadKey: key in globalThis,\n value: (globalThis as Record<string, unknown>)[key as string],\n }));\n\n for (const [key, value] of entries) {\n if (value !== undefined) {\n (globalThis as Record<string, unknown>)[key as string] = value;\n }\n }\n\n return () => {\n for (const entry of previous) {\n if (!entry.hadKey) {\n delete (globalThis as Record<string, unknown>)[entry.key as string];\n continue;\n }\n (globalThis as Record<string, unknown>)[entry.key as string] = entry.value;\n }\n };\n};\n\nexport type ScenarioDefinition<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TCommands extends ReadonlyArray<LofiSubmitCommandDefinition> =\n ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n name: string;\n server: ScenarioServerConfig<TSchema>;\n clientCommands: TCommands;\n clients: Record<string, ScenarioClientConfig>;\n steps: ScenarioStep<NoInfer<TSchema>, NoInfer<TCommandContext>, NoInfer<TVars>>[];\n createClientContext?: (clientName: string) => TCommandContext;\n};\n\nexport type RunScenarioOptions = {\n indexedDbGlobals?: ScenarioIndexedDbGlobals;\n};\n\ntype HTTPMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\";\n\ntype ScenarioFragment = {\n handler: (req: Request) => Promise<Response>;\n callRouteRaw: (method: HTTPMethod, path: string, inputOptions?: unknown) => Promise<Response>;\n};\n\nexport type ScenarioContext<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n name: string;\n server: {\n adapter?: InMemoryAdapter;\n fragment: ScenarioFragment;\n baseUrl: string;\n };\n clients: Record<string, ScenarioClient<TSchema, TCommandContext>>;\n vars: Partial<TVars>;\n lastSubmit: Record<string, LofiSubmitResponse | undefined>;\n lastSync: Record<string, LofiSyncResult | undefined>;\n cleanup: () => Promise<void>;\n};\n\nexport type ScenarioClient<TSchema extends AnySchema = AnySchema, TCommandContext = unknown> = {\n name: string;\n endpointName: string;\n adapter: LofiAdapter & LofiQueryableAdapter;\n submit: LofiSubmitClient<TCommandContext>;\n sync: LofiClient;\n query: LofiQueryInterface<TSchema>;\n baseQuery: LofiQueryInterface<TSchema>;\n overlayQuery?: LofiQueryInterface<TSchema>;\n adapters: {\n base: LofiAdapter & LofiQueryableAdapter;\n overlay?: InMemoryLofiAdapter;\n stacked?: StackedLofiAdapter;\n };\n stores: {\n base?: InMemoryLofiStore;\n overlay?: InMemoryLofiStore;\n };\n overlayManager?: LofiOverlayManager<TCommandContext>;\n};\n\ntype CommandInput<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = unknown | CommandInputFn<TSchema, TCommandContext, TVars>;\ntype CommandInputFn<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => unknown | Promise<unknown>;\ntype ReadFn<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n T = unknown,\n> =\n | BivariantCallback<(ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => T | Promise<T>>\n | BivariantCallback<\n (\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n ) => T | Promise<T>\n >;\n\nexport type ScenarioCommandStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"command\";\n client: string;\n name: string;\n input: CommandInput<TSchema, TCommandContext, TVars>;\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n};\n\nexport type ScenarioSubmitStep = {\n type: \"submit\";\n client: string;\n};\n\nexport type ScenarioSyncStep = {\n type: \"sync\";\n client: string;\n};\n\nexport type ScenarioReadStepWithStore<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n K extends keyof TVars = keyof TVars,\n> = {\n type: \"read\";\n client: string;\n read: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>;\n storeAs: K;\n};\n\nexport type ScenarioReadStepNoStore<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"read\";\n client: string;\n read: ReadFn<TSchema, TCommandContext, TVars>;\n storeAs?: undefined;\n};\n\nexport type ScenarioReadStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> =\n | ScenarioReadStepWithStore<TSchema, TCommandContext, TVars>\n | ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\n\nexport type ScenarioAssertStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> = {\n type: \"assert\";\n assert: BivariantCallback<\n (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => void | Promise<void>\n >;\n};\n\nexport type ScenarioStep<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n> =\n | ScenarioCommandStep<TSchema, TCommandContext, TVars>\n | ScenarioSubmitStep\n | ScenarioSyncStep\n | ScenarioReadStep<TSchema, TCommandContext, TVars>\n | ScenarioAssertStep<TSchema, TCommandContext, TVars>;\n\nexport function defineScenario<\n TSchema extends AnySchema,\n TCommandContext,\n TCommands extends ReadonlyArray<LofiSubmitCommandDefinition> =\n ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars> & {\n createClientContext: (clientName: string) => TCommandContext;\n },\n): ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>;\nexport function defineScenario<\n TSchema extends AnySchema,\n TCommandContext = unknown,\n TCommands extends ReadonlyArray<LofiSubmitCommandDefinition> =\n ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>,\n): ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>;\nexport function defineScenario(scenario: ScenarioDefinition): ScenarioDefinition {\n return scenario;\n}\n\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: CommandInputFn<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: unknown,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\nfunction command<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n name: string,\n input: CommandInput<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n): ScenarioCommandStep<TSchema, TCommandContext, TVars> {\n return {\n type: \"command\",\n client,\n name,\n input,\n target: options?.target,\n optimistic: options?.optimistic,\n submit: options?.submit,\n storeCommandIdAs: options?.storeCommandIdAs,\n };\n}\n\nconst submit = (client: string): ScenarioSubmitStep => ({ type: \"submit\", client });\nconst sync = (client: string): ScenarioSyncStep => ({ type: \"sync\", client });\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n K extends keyof TVars = keyof TVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n): ScenarioReadStepWithStore<TSchema, TCommandContext, TVars, K>;\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: undefined,\n): ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\nfunction read<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n client: string,\n read: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: keyof TVars,\n): ScenarioReadStep<TSchema, TCommandContext, TVars> {\n if (storeAs === undefined) {\n return { type: \"read\", client, read } as ScenarioReadStepNoStore<\n TSchema,\n TCommandContext,\n TVars\n >;\n }\n return { type: \"read\", client, read, storeAs } as ScenarioReadStepWithStore<\n TSchema,\n TCommandContext,\n TVars\n >;\n}\nfunction assert<\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n assert: ScenarioAssertStep<TSchema, TCommandContext, TVars>[\"assert\"],\n): ScenarioAssertStep<TSchema, TCommandContext, TVars> {\n return {\n type: \"assert\",\n assert,\n };\n}\nexport const createScenarioSteps = <\n TSchema extends AnySchema = AnySchema,\n TCommandContext = unknown,\n TVars extends ScenarioVars = ScenarioVars,\n>() => ({\n command: (() => {\n function commandStep(\n client: string,\n name: string,\n input: CommandInputFn<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\n function commandStep(\n client: string,\n name: string,\n input: unknown,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars>;\n function commandStep(\n client: string,\n name: string,\n input: CommandInput<TSchema, TCommandContext, TVars>,\n options?: {\n target?: LofiSubmitCommandTarget;\n optimistic?: boolean;\n submit?: boolean;\n storeCommandIdAs?: (KeysMatching<TVars, string> & string) | undefined;\n },\n ): ScenarioCommandStep<TSchema, TCommandContext, TVars> {\n return command<TSchema, TCommandContext, TVars>(client, name, input, options);\n }\n return commandStep;\n })(),\n submit,\n sync,\n read: (<K extends keyof TVars>(\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n ) => read<TSchema, TCommandContext, TVars, K>(client, readFn, storeAs)) as {\n <K extends keyof TVars>(\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars, TVars[K]>,\n storeAs: K,\n ): ScenarioReadStepWithStore<TSchema, TCommandContext, TVars, K>;\n (\n client: string,\n readFn: ReadFn<TSchema, TCommandContext, TVars>,\n storeAs?: undefined,\n ): ScenarioReadStepNoStore<TSchema, TCommandContext, TVars>;\n },\n assert: (assertFn: ScenarioAssertStep<TSchema, TCommandContext, TVars>[\"assert\"]) =>\n assert<TSchema, TCommandContext, TVars>(assertFn),\n});\n\nexport const steps = createScenarioSteps();\n\nconst createServerFetch = (fragment: ScenarioFragment) => {\n return async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const url = new URL(typeof input === \"string\" ? input : input.toString());\n const method = ((init?.method ?? \"GET\").toUpperCase() as HTTPMethod) ?? \"GET\";\n const headers = init?.headers ? new Headers(init.headers) : undefined;\n const body = init?.body ? JSON.parse(init.body as string) : undefined;\n\n return fragment.callRouteRaw(method, url.pathname, {\n query: url.searchParams,\n body,\n headers,\n });\n };\n};\n\nconst resolveCommandInput = async <\n TSchema extends AnySchema,\n TCommandContext,\n TVars extends ScenarioVars,\n>(\n input: CommandInput<TSchema, TCommandContext, TVars>,\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n): Promise<unknown> => {\n if (typeof input === \"function\") {\n return await input(ctx);\n }\n return input;\n};\n\nconst resolveReadResult = async <\n TSchema extends AnySchema,\n TCommandContext,\n TVars extends ScenarioVars,\n T = unknown,\n>(\n read: ReadFn<TSchema, TCommandContext, TVars, T>,\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n): Promise<T> => {\n if (read.length >= 2) {\n return await (\n read as (\n ctx: ScenarioContext<TSchema, TCommandContext, TVars>,\n client: ScenarioClient<TSchema, TCommandContext>,\n ) => T\n )(ctx, client);\n }\n return await (read as (ctx: ScenarioContext<TSchema, TCommandContext, TVars>) => T)(ctx);\n};\n\ntype ScenarioClientAdapters<TCommandContext = unknown> = {\n adapter: LofiAdapter & LofiQueryableAdapter;\n baseAdapter: LofiAdapter & LofiQueryableAdapter;\n overlayAdapter?: InMemoryLofiAdapter;\n stackedAdapter?: StackedLofiAdapter;\n overlayManager?: LofiOverlayManager<TCommandContext>;\n baseStore?: InMemoryLofiStore;\n overlayStore?: InMemoryLofiStore;\n};\n\nconst startScenarioServer = async (\n fragment: ScenarioFragment,\n port: number,\n): Promise<{ baseUrl: string; close: () => Promise<void> }> => {\n const server = createServer(toNodeHandler(fragment.handler));\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(port, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address() as AddressInfo;\n const baseUrl = `http://127.0.0.1:${address.port}`;\n\n return {\n baseUrl,\n close: async () =>\n await new Promise<void>((resolve, reject) => {\n server.close((err) => {\n if (err) {\n reject(err);\n return;\n }\n resolve();\n });\n }),\n };\n};\n\nconst resolveMountRoute = (fragment: ScenarioFragment): string | undefined => {\n if (\"mountRoute\" in fragment && typeof fragment.mountRoute === \"string\") {\n return fragment.mountRoute;\n }\n return undefined;\n};\n\nconst resolveCommandTarget = <TCommandContext = unknown>(\n commandName: string,\n commands: ReadonlyArray<LofiSubmitCommandDefinition<unknown, TCommandContext>>,\n): LofiSubmitCommandTarget | undefined => {\n for (const command of commands) {\n if (command.name === commandName) {\n return command.target;\n }\n }\n return undefined;\n};\n\nconst isScenarioDefinitionConfig = <TSchema extends AnySchema>(\n config: ScenarioServerConfig<TSchema>,\n): config is Extract<\n ScenarioServerConfig<TSchema>,\n { fragmentName: string; schema: TSchema; syncCommands: SyncCommandRegistry }\n> => \"fragmentName\" in config;\n\nconst isScenarioFragmentConfig = <TSchema extends AnySchema>(\n config: ScenarioServerConfig<TSchema>,\n): config is Extract<ScenarioServerConfig<TSchema>, { fragment: AnyFragnoInstantiatedFragment }> =>\n \"fragment\" in config;\n\nexport const runScenario = async <\n TSchema extends AnySchema,\n TCommandContext = unknown,\n TCommands extends ReadonlyArray<LofiSubmitCommandDefinition> =\n ReadonlyArray<LofiSubmitCommandDefinition>,\n TVars extends ScenarioVars = ScenarioVars,\n>(\n scenario: ScenarioDefinition<TSchema, TCommandContext, TCommands, TVars>,\n options?: RunScenarioOptions,\n): Promise<ScenarioContext<TSchema, TCommandContext, TVars>> => {\n let adapter: InMemoryAdapter | undefined;\n let fragment: ScenarioFragment;\n\n const restoreGlobals = installIndexedDbGlobals(options?.indexedDbGlobals);\n\n if (isScenarioDefinitionConfig(scenario.server)) {\n adapter = new InMemoryAdapter({ idSeed: `lofi-scenario-${scenario.name}` });\n const fragmentDef = defineFragment(scenario.server.fragmentName)\n .extend(withDatabase(scenario.server.schema))\n .withSyncCommands(scenario.server.syncCommands)\n .build();\n\n fragment = instantiate(fragmentDef)\n .withConfig({})\n .withRoutes([])\n .withOptions({ databaseAdapter: adapter, outbox: { enabled: true } })\n .build() as unknown as ScenarioFragment;\n } else if (isScenarioFragmentConfig(scenario.server)) {\n fragment = scenario.server.fragment as unknown as ScenarioFragment;\n } else {\n throw new Error(\"Scenario server must include fragment configuration.\");\n }\n\n const shouldStartServer = typeof scenario.server.port === \"number\";\n const baseUrlOverride = scenario.server.baseUrl;\n let fetcher: typeof fetch = createServerFetch(fragment);\n let baseUrl = baseUrlOverride ?? \"http://lofi-scenario.test\";\n let closeServer: (() => Promise<void>) | undefined;\n\n if (shouldStartServer) {\n const { baseUrl: serverUrl, close } = await startScenarioServer(\n fragment,\n scenario.server.port as number,\n );\n const mountRoute = resolveMountRoute(fragment);\n baseUrl = baseUrlOverride ?? `${serverUrl}${mountRoute ?? \"\"}`;\n fetcher = fetch.bind(globalThis);\n closeServer = close;\n }\n\n const context: ScenarioContext<TSchema, TCommandContext, TVars> = {\n name: scenario.name,\n server: {\n adapter,\n fragment,\n baseUrl,\n },\n clients: {},\n vars: {},\n lastSubmit: {},\n lastSync: {},\n cleanup: async () => {\n if (closeServer) {\n await closeServer();\n }\n if (adapter) {\n await adapter.close();\n }\n if (restoreGlobals) {\n restoreGlobals();\n }\n },\n };\n try {\n const clientCommands = Array.from(scenario.clientCommands) as Array<\n LofiSubmitCommandDefinition<unknown, TCommandContext>\n >;\n\n for (const [name, clientConfig] of Object.entries(scenario.clients)) {\n const dbName = `lofi-scenario-${scenario.name}-${name}-${Math.random().toString(16).slice(2)}`;\n const createClientContext = scenario.createClientContext;\n const createCommandContext = createClientContext\n ? (_command: LofiSubmitCommandDefinition<unknown, TCommandContext>) =>\n createClientContext(name)\n : undefined;\n const adapterConfig = clientConfig.adapter;\n const schema = scenario.server.schema;\n\n const adapters: ScenarioClientAdapters<TCommandContext> = (() => {\n if (!adapterConfig || adapterConfig.type === \"indexeddb\") {\n const baseAdapter = new IndexedDbAdapter({\n dbName: adapterConfig?.dbName ?? dbName,\n endpointName: clientConfig.endpointName,\n schemas: [{ schema }],\n });\n return {\n adapter: baseAdapter,\n baseAdapter,\n };\n }\n\n if (adapterConfig.type === \"in-memory\") {\n const baseAdapter = new InMemoryLofiAdapter({\n endpointName: clientConfig.endpointName,\n schemas: [schema],\n ...(adapterConfig.store ? { store: adapterConfig.store } : {}),\n });\n return {\n adapter: baseAdapter,\n baseAdapter,\n baseStore: baseAdapter.store,\n };\n }\n\n if (adapterConfig.type === \"stacked\") {\n const baseKind = adapterConfig.base ?? \"indexeddb\";\n const baseAdapter =\n baseKind === \"in-memory\"\n ? new InMemoryLofiAdapter({\n endpointName: clientConfig.endpointName,\n schemas: [schema],\n ...(adapterConfig.baseStore ? { store: adapterConfig.baseStore } : {}),\n })\n : new IndexedDbAdapter({\n dbName: adapterConfig.baseDbName ?? dbName,\n endpointName: clientConfig.endpointName,\n schemas: [{ schema }],\n });\n\n const overlayManager = new LofiOverlayManager({\n endpointName: clientConfig.endpointName,\n adapter: baseAdapter,\n schemas: [schema],\n commands: clientCommands,\n ...(createCommandContext ? { createCommandContext } : {}),\n ...(adapterConfig.overlayStore ? { store: adapterConfig.overlayStore } : {}),\n });\n\n return {\n adapter: overlayManager.stackedAdapter,\n baseAdapter,\n overlayAdapter: overlayManager.overlayAdapter,\n stackedAdapter: overlayManager.stackedAdapter,\n overlayManager,\n baseStore: baseAdapter instanceof InMemoryLofiAdapter ? baseAdapter.store : undefined,\n overlayStore: overlayManager.store,\n };\n }\n\n const _exhaustive: never = adapterConfig;\n throw new Error(`Unsupported scenario adapter config: ${String(_exhaustive)}`);\n })();\n\n const submit = new LofiSubmitClient<TCommandContext>({\n endpointName: clientConfig.endpointName,\n submitUrl: `${baseUrl}/_internal/sync`,\n internalUrl: `${baseUrl}/_internal`,\n adapter: adapters.adapter,\n schemas: [schema],\n commands: clientCommands,\n fetch: fetcher,\n ...(createCommandContext ? { createCommandContext } : {}),\n ...(adapters.overlayManager ? { overlay: adapters.overlayManager } : {}),\n });\n\n const sync = new LofiClient({\n endpointName: clientConfig.endpointName,\n outboxUrl: `${baseUrl}/_internal/outbox`,\n adapter: adapters.adapter,\n fetch: fetcher,\n });\n\n const queryAdapter = adapters.stackedAdapter ?? adapters.baseAdapter;\n\n context.clients[name] = {\n name,\n endpointName: clientConfig.endpointName,\n adapter: adapters.adapter,\n submit,\n sync,\n query: queryAdapter.createQueryEngine(schema),\n baseQuery: adapters.baseAdapter.createQueryEngine(schema),\n overlayQuery: adapters.overlayAdapter\n ? adapters.overlayAdapter.createQueryEngine(schema)\n : undefined,\n adapters: {\n base: adapters.baseAdapter,\n overlay: adapters.overlayAdapter,\n stacked: adapters.stackedAdapter,\n },\n stores: {\n base: adapters.baseStore,\n overlay: adapters.overlayStore,\n },\n overlayManager: adapters.overlayManager,\n };\n }\n\n for (const step of scenario.steps) {\n if (step.type === \"assert\") {\n await step.assert(context);\n continue;\n }\n\n const client = context.clients[step.client];\n if (!client) {\n throw new Error(`Unknown scenario client: ${step.client}`);\n }\n\n if (step.type === \"command\") {\n const input = await resolveCommandInput(step.input, context);\n const target = step.target ?? resolveCommandTarget(step.name, clientCommands) ?? null;\n if (!target) {\n throw new Error(`Unknown scenario command target: ${step.name}`);\n }\n\n const commandId = await client.submit.queueCommand({\n name: step.name,\n target,\n input,\n optimistic: step.optimistic,\n });\n\n if (step.storeCommandIdAs !== undefined) {\n context.vars[step.storeCommandIdAs] = commandId as TVars[KeysMatching<TVars, string> &\n string];\n }\n\n if (step.submit) {\n context.lastSubmit[step.client] = await client.submit.submitOnce();\n }\n\n continue;\n }\n\n if (step.type === \"submit\") {\n context.lastSubmit[step.client] = await client.submit.submitOnce();\n continue;\n }\n\n if (step.type === \"sync\") {\n context.lastSync[step.client] = await client.sync.syncOnce();\n continue;\n }\n\n if (step.type === \"read\") {\n const result = await resolveReadResult(step.read, context, client);\n if (step.storeAs !== undefined) {\n context.vars[step.storeAs] = result as TVars[keyof TVars];\n }\n continue;\n }\n }\n\n return context;\n } catch (error) {\n await context.cleanup();\n throw error;\n }\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","names":[],"sources":["../../src/submit/client.ts"],"sourcesContent":[],"mappings":";;;;KAiBK,iBAAA;0BACqB,sBAAsB;EAD3C,OAAA,EAAA,CAAA,OAE2B,CAF3B,EAAiB;IACI,KAAA,CAAA,EACM,iBADN,EAAA;IAAsB,WAAA,CAAA,EAAA,MAAA,EAAA;EAChB,CAAA,EAAA,GAAkD,OAAlD,CAAA,IAAA,CAAA;CAAkD;KAG7E,mBAHoF,CAAA,QAAA,CAAA,GAAA;EAGpF,YAAA,EAAA,MAAA;EAIM,SAAA,EAAA,MAAA;EAAc,WAAA,EAAA,MAAA;EACd,OAAA,EADA,WACA,GADc,oBACd;EAC4C,OAAA,EAD5C,SAC4C,EAAA;EAArC,QAAA,EAAN,KAAM,CAAA,2BAAA,CAAA,OAAA,EAAqC,QAArC,CAAA,CAAA;EAAN,KAAA,CAAA,EAAA,OACK,KADL;EACK,SAAA,CAAA,EAAA,MAAA;EAIuD,QAAA,CAAA,EAAA,MAAA;EAArC,0BAAA,CAAA,EAAA,QAAA,GAAA,UAAA;EAAmD,oBAAA,CAAA,EAAA,CAAA,OAAA,EAAnD,2BAAmD,CAAA,OAAA,EAAd,QAAc,CAAA,EAAA,GAAA,QAAA;EAC1E,OAAA,CAAA,EAAA,iBAAA;CAAiB;AAGhB,cAAA,gBAAgB,CAAA,WAAA,OAAA,CAAA,CAAA;EAgBc,iBAAA,OAAA;EAApB,iBAAA,YAAA;EAqBX,iBAAA,SAAA;EAIN,iBAAA,WAAA;EA6BkC,iBAAA,OAAA;EAAwB,iBAAA,SAAA;EAAR,iBAAA,QAAA;EAAO,iBAAA,0BAAA;;;;;;;uBAtDxC,oBAAoB;;;YAqB/B;;;;MAIN;;aA6BkC;MAAgB,QAAQ"}
1
+ {"version":3,"file":"client.d.ts","names":[],"sources":["../../src/submit/client.ts"],"sourcesContent":[],"mappings":";;;;KAkBK,iBAAA;0BACqB,sBAAsB;EAD3C,OAAA,EAAA,CAAA,OAE2B,CAF3B,EAAiB;IACI,KAAA,CAAA,EACM,iBADN,EAAA;IAAsB,WAAA,CAAA,EAAA,MAAA,EAAA;EAChB,CAAA,EAAA,GAAkD,OAAlD,CAAA,IAAA,CAAA;CAAkD;KAG7E,mBAHoF,CAAA,QAAA,CAAA,GAAA;EAGpF,YAAA,EAAA,MAAA;EAIM,SAAA,EAAA,MAAA;EAAc,WAAA,EAAA,MAAA;EACd,OAAA,EADA,WACA,GADc,oBACd;EAC4C,OAAA,EAD5C,SAC4C,EAAA;EAArC,QAAA,EAAN,KAAM,CAAA,2BAAA,CAAA,OAAA,EAAqC,QAArC,CAAA,CAAA;EAAN,KAAA,CAAA,EAAA,OACK,KADL;EACK,SAAA,CAAA,EAAA,MAAA;EAIuD,QAAA,CAAA,EAAA,MAAA;EAArC,0BAAA,CAAA,EAAA,QAAA,GAAA,UAAA;EAAmD,oBAAA,CAAA,EAAA,CAAA,OAAA,EAAnD,2BAAmD,CAAA,OAAA,EAAd,QAAc,CAAA,EAAA,GAAA,QAAA;EAC1E,OAAA,CAAA,EAAA,iBAAA;CAAiB;AAGhB,cAAA,gBAAgB,CAAA,WAAA,OAAA,CAAA,CAAA;EAgBc,iBAAA,OAAA;EAApB,iBAAA,YAAA;EAqBX,iBAAA,SAAA;EAIN,iBAAA,WAAA;EA6BkC,iBAAA,OAAA;EAAwB,iBAAA,SAAA;EAAR,iBAAA,QAAA;EAAO,iBAAA,0BAAA;;;;;;;uBAtDxC,oBAAoB;;;YAqB/B;;;;MAIN;;aA6BkC;MAAgB,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["command: LofiSubmitCommand","resolveSubmitting!: () => void","request: LofiSubmitRequest"],"sources":["../../src/submit/client.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\nimport type {\n LofiAdapter,\n LofiSubmitCommand,\n LofiSubmitCommandDefinition,\n LofiSubmitRequest,\n LofiSubmitResponse,\n LofiQueryableAdapter,\n} from \"../types\";\nimport { createLocalHandlerTx } from \"./local-handler-tx\";\nimport { rebaseSubmitQueue } from \"./rebase\";\nimport { buildCommandKey, defaultQueueKey, loadSubmitQueue, storeSubmitQueue } from \"./queue\";\n\ntype InternalDescribeResponse = {\n adapterIdentity?: string;\n};\n\ntype OptimisticOverlay = {\n applyCommand: (command: LofiSubmitCommand) => Promise<void>;\n rebuild: (options?: { queue?: LofiSubmitCommand[]; schemaNames?: string[] }) => Promise<void>;\n};\n\ntype SubmitClientOptions<TContext> = {\n endpointName: string;\n submitUrl: string;\n internalUrl: string;\n adapter: LofiAdapter & LofiQueryableAdapter;\n schemas: AnySchema[];\n commands: Array<LofiSubmitCommandDefinition<unknown, TContext>>;\n fetch?: typeof fetch;\n cursorKey?: string;\n queueKey?: string;\n conflictResolutionStrategy?: \"server\" | \"disabled\";\n createCommandContext?: (command: LofiSubmitCommandDefinition<unknown, TContext>) => TContext;\n overlay?: OptimisticOverlay;\n};\n\nexport class LofiSubmitClient<TContext = unknown> {\n private readonly adapter: SubmitClientOptions<TContext>[\"adapter\"];\n private readonly endpointName: string;\n private readonly submitUrl: string;\n private readonly internalUrl: string;\n private readonly fetcher: typeof fetch;\n private readonly cursorKey: string;\n private readonly queueKey: string;\n private readonly conflictResolutionStrategy: \"server\" | \"disabled\";\n private readonly commands: Map<string, LofiSubmitCommandDefinition<unknown, TContext>>;\n private readonly createCommandContext?: SubmitClientOptions<TContext>[\"createCommandContext\"];\n private readonly overlay?: OptimisticOverlay;\n private adapterIdentity?: string;\n private submitting?: Promise<void>;\n private readonly localTx: ReturnType<typeof createLocalHandlerTx>;\n\n constructor(options: SubmitClientOptions<TContext>) {\n this.adapter = options.adapter;\n this.endpointName = options.endpointName;\n this.submitUrl = options.submitUrl;\n this.internalUrl = options.internalUrl;\n const defaultFetch = fetch.bind(globalThis);\n this.fetcher = options.fetch ?? defaultFetch;\n this.cursorKey = options.cursorKey ?? `${options.endpointName}::outbox`;\n this.queueKey = options.queueKey ?? defaultQueueKey(options.endpointName);\n this.conflictResolutionStrategy = options.conflictResolutionStrategy ?? \"server\";\n this.createCommandContext = options.createCommandContext;\n this.commands = new Map(options.commands.map((command) => [buildCommandKey(command), command]));\n this.overlay = options.overlay;\n this.localTx = createLocalHandlerTx({\n adapter: options.adapter,\n schemas: options.schemas,\n });\n }\n\n async queueCommand(options: {\n name: string;\n target: LofiSubmitCommand[\"target\"];\n input: unknown;\n id?: string;\n optimistic?: boolean;\n }): Promise<string> {\n const id = options.id ?? crypto.randomUUID();\n const command: LofiSubmitCommand = {\n id,\n name: options.name,\n target: options.target,\n input: options.input,\n };\n\n if (this.submitting) {\n await this.submitting;\n }\n\n const queue = await loadSubmitQueue(this.adapter, this.queueKey);\n queue.push(command);\n await storeSubmitQueue(this.adapter, this.queueKey, queue);\n\n if (options.optimistic !== false) {\n try {\n await this.runOptimisticCommand(command);\n } catch (error) {\n // Optimistic execution failed; command remains queued for submission.\n console.warn(\"Optimistic command failed\", error);\n }\n }\n\n return id;\n }\n\n async submitOnce(options?: { signal?: AbortSignal }): Promise<LofiSubmitResponse> {\n if (this.submitting) {\n throw new Error(\"Submit already in progress\");\n }\n let resolveSubmitting!: () => void;\n this.submitting = new Promise<void>((resolve) => {\n resolveSubmitting = resolve;\n });\n\n try {\n const queue = await loadSubmitQueue(this.adapter, this.queueKey);\n const adapterIdentity = await this.getAdapterIdentity(options?.signal);\n const baseVersionstamp = await this.adapter.getMeta(this.cursorKey);\n\n const requestId = crypto.randomUUID();\n const request: LofiSubmitRequest = {\n baseVersionstamp: baseVersionstamp ?? undefined,\n requestId,\n conflictResolutionStrategy: this.conflictResolutionStrategy,\n adapterIdentity,\n commands: queue,\n };\n\n const response = await this.fetcher(this.submitUrl, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Submit request failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as LofiSubmitResponse;\n\n const rebased = await rebaseSubmitQueue({\n adapter: this.adapter,\n entries: payload.entries,\n cursorKey: this.cursorKey,\n confirmedCommandIds: payload.confirmedCommandIds,\n queue,\n overlay: this.overlay,\n });\n\n await storeSubmitQueue(this.adapter, this.queueKey, rebased.queue);\n return payload;\n } finally {\n resolveSubmitting();\n this.submitting = undefined;\n }\n }\n\n private async runOptimisticCommand(command: LofiSubmitCommand): Promise<void> {\n if (this.overlay) {\n await this.overlay.applyCommand(command);\n return;\n }\n await this.runCommand(command);\n }\n\n private async runCommand(command: LofiSubmitCommand): Promise<void> {\n const key = buildCommandKey(command);\n const definition = this.commands.get(key);\n if (!definition) {\n throw new Error(`Unknown sync command: ${key}`);\n }\n\n if (!this.createCommandContext) {\n throw new Error(\n \"createCommandContext is required to run optimistic commands without an overlay.\",\n );\n }\n\n const ctx = this.createCommandContext(definition);\n\n await definition.handler({\n input: command.input,\n ctx,\n tx: this.localTx,\n });\n }\n\n private async getAdapterIdentity(signal?: AbortSignal): Promise<string> {\n if (this.adapterIdentity) {\n return this.adapterIdentity;\n }\n\n const response = await this.fetcher(this.internalUrl, { signal });\n if (!response.ok) {\n throw new Error(`Internal preflight failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as InternalDescribeResponse;\n if (!payload.adapterIdentity) {\n throw new Error(\"Internal preflight missing adapterIdentity\");\n }\n\n this.adapterIdentity = payload.adapterIdentity;\n return payload.adapterIdentity;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["command: LofiSubmitCommand","resolveSubmitting!: () => void","request: LofiSubmitRequest"],"sources":["../../src/submit/client.ts"],"sourcesContent":["import type { AnySchema } from \"@fragno-dev/db/schema\";\n\nimport type {\n LofiAdapter,\n LofiSubmitCommand,\n LofiSubmitCommandDefinition,\n LofiSubmitRequest,\n LofiSubmitResponse,\n LofiQueryableAdapter,\n} from \"../types\";\nimport { createLocalHandlerTx } from \"./local-handler-tx\";\nimport { buildCommandKey, defaultQueueKey, loadSubmitQueue, storeSubmitQueue } from \"./queue\";\nimport { rebaseSubmitQueue } from \"./rebase\";\n\ntype InternalDescribeResponse = {\n adapterIdentity?: string;\n};\n\ntype OptimisticOverlay = {\n applyCommand: (command: LofiSubmitCommand) => Promise<void>;\n rebuild: (options?: { queue?: LofiSubmitCommand[]; schemaNames?: string[] }) => Promise<void>;\n};\n\ntype SubmitClientOptions<TContext> = {\n endpointName: string;\n submitUrl: string;\n internalUrl: string;\n adapter: LofiAdapter & LofiQueryableAdapter;\n schemas: AnySchema[];\n commands: Array<LofiSubmitCommandDefinition<unknown, TContext>>;\n fetch?: typeof fetch;\n cursorKey?: string;\n queueKey?: string;\n conflictResolutionStrategy?: \"server\" | \"disabled\";\n createCommandContext?: (command: LofiSubmitCommandDefinition<unknown, TContext>) => TContext;\n overlay?: OptimisticOverlay;\n};\n\nexport class LofiSubmitClient<TContext = unknown> {\n private readonly adapter: SubmitClientOptions<TContext>[\"adapter\"];\n private readonly endpointName: string;\n private readonly submitUrl: string;\n private readonly internalUrl: string;\n private readonly fetcher: typeof fetch;\n private readonly cursorKey: string;\n private readonly queueKey: string;\n private readonly conflictResolutionStrategy: \"server\" | \"disabled\";\n private readonly commands: Map<string, LofiSubmitCommandDefinition<unknown, TContext>>;\n private readonly createCommandContext?: SubmitClientOptions<TContext>[\"createCommandContext\"];\n private readonly overlay?: OptimisticOverlay;\n private adapterIdentity?: string;\n private submitting?: Promise<void>;\n private readonly localTx: ReturnType<typeof createLocalHandlerTx>;\n\n constructor(options: SubmitClientOptions<TContext>) {\n this.adapter = options.adapter;\n this.endpointName = options.endpointName;\n this.submitUrl = options.submitUrl;\n this.internalUrl = options.internalUrl;\n const defaultFetch = fetch.bind(globalThis);\n this.fetcher = options.fetch ?? defaultFetch;\n this.cursorKey = options.cursorKey ?? `${options.endpointName}::outbox`;\n this.queueKey = options.queueKey ?? defaultQueueKey(options.endpointName);\n this.conflictResolutionStrategy = options.conflictResolutionStrategy ?? \"server\";\n this.createCommandContext = options.createCommandContext;\n this.commands = new Map(options.commands.map((command) => [buildCommandKey(command), command]));\n this.overlay = options.overlay;\n this.localTx = createLocalHandlerTx({\n adapter: options.adapter,\n schemas: options.schemas,\n });\n }\n\n async queueCommand(options: {\n name: string;\n target: LofiSubmitCommand[\"target\"];\n input: unknown;\n id?: string;\n optimistic?: boolean;\n }): Promise<string> {\n const id = options.id ?? crypto.randomUUID();\n const command: LofiSubmitCommand = {\n id,\n name: options.name,\n target: options.target,\n input: options.input,\n };\n\n if (this.submitting) {\n await this.submitting;\n }\n\n const queue = await loadSubmitQueue(this.adapter, this.queueKey);\n queue.push(command);\n await storeSubmitQueue(this.adapter, this.queueKey, queue);\n\n if (options.optimistic !== false) {\n try {\n await this.runOptimisticCommand(command);\n } catch (error) {\n // Optimistic execution failed; command remains queued for submission.\n console.warn(\"Optimistic command failed\", error);\n }\n }\n\n return id;\n }\n\n async submitOnce(options?: { signal?: AbortSignal }): Promise<LofiSubmitResponse> {\n if (this.submitting) {\n throw new Error(\"Submit already in progress\");\n }\n let resolveSubmitting!: () => void;\n this.submitting = new Promise<void>((resolve) => {\n resolveSubmitting = resolve;\n });\n\n try {\n const queue = await loadSubmitQueue(this.adapter, this.queueKey);\n const adapterIdentity = await this.getAdapterIdentity(options?.signal);\n const baseVersionstamp = await this.adapter.getMeta(this.cursorKey);\n\n const requestId = crypto.randomUUID();\n const request: LofiSubmitRequest = {\n baseVersionstamp: baseVersionstamp ?? undefined,\n requestId,\n conflictResolutionStrategy: this.conflictResolutionStrategy,\n adapterIdentity,\n commands: queue,\n };\n\n const response = await this.fetcher(this.submitUrl, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(request),\n signal: options?.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Submit request failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as LofiSubmitResponse;\n\n const rebased = await rebaseSubmitQueue({\n adapter: this.adapter,\n entries: payload.entries,\n cursorKey: this.cursorKey,\n confirmedCommandIds: payload.confirmedCommandIds,\n queue,\n overlay: this.overlay,\n });\n\n await storeSubmitQueue(this.adapter, this.queueKey, rebased.queue);\n return payload;\n } finally {\n resolveSubmitting();\n this.submitting = undefined;\n }\n }\n\n private async runOptimisticCommand(command: LofiSubmitCommand): Promise<void> {\n if (this.overlay) {\n await this.overlay.applyCommand(command);\n return;\n }\n await this.runCommand(command);\n }\n\n private async runCommand(command: LofiSubmitCommand): Promise<void> {\n const key = buildCommandKey(command);\n const definition = this.commands.get(key);\n if (!definition) {\n throw new Error(`Unknown sync command: ${key}`);\n }\n\n if (!this.createCommandContext) {\n throw new Error(\n \"createCommandContext is required to run optimistic commands without an overlay.\",\n );\n }\n\n const ctx = this.createCommandContext(definition);\n\n await definition.handler({\n input: command.input,\n ctx,\n tx: this.localTx,\n });\n }\n\n private async getAdapterIdentity(signal?: AbortSignal): Promise<string> {\n if (this.adapterIdentity) {\n return this.adapterIdentity;\n }\n\n const response = await this.fetcher(this.internalUrl, { signal });\n if (!response.ok) {\n throw new Error(`Internal preflight failed: ${response.status} ${response.statusText}`);\n }\n\n const payload = (await response.json()) as InternalDescribeResponse;\n if (!payload.adapterIdentity) {\n throw new Error(\"Internal preflight missing adapterIdentity\");\n }\n\n this.adapterIdentity = payload.adapterIdentity;\n return payload.adapterIdentity;\n }\n}\n"],"mappings":";;;;;AAsCA,IAAa,mBAAb,MAAkD;CAChD,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ;CACR,AAAQ;CACR,AAAiB;CAEjB,YAAY,SAAwC;AAClD,OAAK,UAAU,QAAQ;AACvB,OAAK,eAAe,QAAQ;AAC5B,OAAK,YAAY,QAAQ;AACzB,OAAK,cAAc,QAAQ;EAC3B,MAAM,eAAe,MAAM,KAAK,WAAW;AAC3C,OAAK,UAAU,QAAQ,SAAS;AAChC,OAAK,YAAY,QAAQ,aAAa,GAAG,QAAQ,aAAa;AAC9D,OAAK,WAAW,QAAQ,YAAY,gBAAgB,QAAQ,aAAa;AACzE,OAAK,6BAA6B,QAAQ,8BAA8B;AACxE,OAAK,uBAAuB,QAAQ;AACpC,OAAK,WAAW,IAAI,IAAI,QAAQ,SAAS,KAAK,YAAY,CAAC,gBAAgB,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/F,OAAK,UAAU,QAAQ;AACvB,OAAK,UAAU,qBAAqB;GAClC,SAAS,QAAQ;GACjB,SAAS,QAAQ;GAClB,CAAC;;CAGJ,MAAM,aAAa,SAMC;EAClB,MAAM,KAAK,QAAQ,MAAM,OAAO,YAAY;EAC5C,MAAMA,UAA6B;GACjC;GACA,MAAM,QAAQ;GACd,QAAQ,QAAQ;GAChB,OAAO,QAAQ;GAChB;AAED,MAAI,KAAK,WACP,OAAM,KAAK;EAGb,MAAM,QAAQ,MAAM,gBAAgB,KAAK,SAAS,KAAK,SAAS;AAChE,QAAM,KAAK,QAAQ;AACnB,QAAM,iBAAiB,KAAK,SAAS,KAAK,UAAU,MAAM;AAE1D,MAAI,QAAQ,eAAe,MACzB,KAAI;AACF,SAAM,KAAK,qBAAqB,QAAQ;WACjC,OAAO;AAEd,WAAQ,KAAK,6BAA6B,MAAM;;AAIpD,SAAO;;CAGT,MAAM,WAAW,SAAiE;AAChF,MAAI,KAAK,WACP,OAAM,IAAI,MAAM,6BAA6B;EAE/C,IAAIC;AACJ,OAAK,aAAa,IAAI,SAAe,YAAY;AAC/C,uBAAoB;IACpB;AAEF,MAAI;GACF,MAAM,QAAQ,MAAM,gBAAgB,KAAK,SAAS,KAAK,SAAS;GAChE,MAAM,kBAAkB,MAAM,KAAK,mBAAmB,SAAS,OAAO;GACtE,MAAM,mBAAmB,MAAM,KAAK,QAAQ,QAAQ,KAAK,UAAU;GAEnE,MAAM,YAAY,OAAO,YAAY;GACrC,MAAMC,UAA6B;IACjC,kBAAkB,oBAAoB;IACtC;IACA,4BAA4B,KAAK;IACjC;IACA,UAAU;IACX;GAED,MAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,WAAW;IAClD,QAAQ;IACR,SAAS,EACP,gBAAgB,oBACjB;IACD,MAAM,KAAK,UAAU,QAAQ;IAC7B,QAAQ,SAAS;IAClB,CAAC;AAEF,OAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,0BAA0B,SAAS,OAAO,GAAG,SAAS,aAAa;GAGrF,MAAM,UAAW,MAAM,SAAS,MAAM;GAEtC,MAAM,UAAU,MAAM,kBAAkB;IACtC,SAAS,KAAK;IACd,SAAS,QAAQ;IACjB,WAAW,KAAK;IAChB,qBAAqB,QAAQ;IAC7B;IACA,SAAS,KAAK;IACf,CAAC;AAEF,SAAM,iBAAiB,KAAK,SAAS,KAAK,UAAU,QAAQ,MAAM;AAClE,UAAO;YACC;AACR,sBAAmB;AACnB,QAAK,aAAa;;;CAItB,MAAc,qBAAqB,SAA2C;AAC5E,MAAI,KAAK,SAAS;AAChB,SAAM,KAAK,QAAQ,aAAa,QAAQ;AACxC;;AAEF,QAAM,KAAK,WAAW,QAAQ;;CAGhC,MAAc,WAAW,SAA2C;EAClE,MAAM,MAAM,gBAAgB,QAAQ;EACpC,MAAM,aAAa,KAAK,SAAS,IAAI,IAAI;AACzC,MAAI,CAAC,WACH,OAAM,IAAI,MAAM,yBAAyB,MAAM;AAGjD,MAAI,CAAC,KAAK,qBACR,OAAM,IAAI,MACR,kFACD;EAGH,MAAM,MAAM,KAAK,qBAAqB,WAAW;AAEjD,QAAM,WAAW,QAAQ;GACvB,OAAO,QAAQ;GACf;GACA,IAAI,KAAK;GACV,CAAC;;CAGJ,MAAc,mBAAmB,QAAuC;AACtE,MAAI,KAAK,gBACP,QAAO,KAAK;EAGd,MAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,aAAa,EAAE,QAAQ,CAAC;AACjE,MAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,8BAA8B,SAAS,OAAO,GAAG,SAAS,aAAa;EAGzF,MAAM,UAAW,MAAM,SAAS,MAAM;AACtC,MAAI,CAAC,QAAQ,gBACX,OAAM,IAAI,MAAM,6CAA6C;AAG/D,OAAK,kBAAkB,QAAQ;AAC/B,SAAO,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"local-handler-tx.d.ts","names":[],"sources":["../../src/submit/local-handler-tx.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"local-handler-tx.d.ts","names":[],"sources":["../../src/submit/local-handler-tx.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAsBK,gBAAA,GAAmB,kBAAkB;KAE9B,qBAAA,cACA,KAAK,0CACZ;AAJA,KAMO,6BAN8B,CAAA,SAAA,OAAA,EAAlB,WAAU,OAAA,CAAA,GAAA;EAEtB,IAAA,EAAA,MAAA;EACK,OAAA,EAAA,CAAA,IAAA,EAAA;IAAL,KAAA,EAKe,MALf;IACP,EAAA,EAIkC,qBAJlC;IAAgB,GAAA,EAI8C,QAJ9C;EAET,CAAA,EAAA,GAEsE,OAFtE,CAAA,OAAA,CAAA;CAEe;KAGtB,qBAAA,GAHkC;EAA4B,cAAA,EAAA,SAAA,EAItC,YAJsC,EAAA,CAAA,EAIrB,OAJqB,CAAA,IAAA,CAAA;EAAe,kBAAA,CAAA,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,GAKnC,qBALmC;EAAO,iBAAA,CAAA,EAMnE,oBANmE,CAAA,mBAAA,CAAA;AACvF,CAAA;KAQG,uBAAA,GALwB;EAAiB,IAAA,EAAA,MAAA;EACC,KAAA,EAOlC,QAPkC;EACzB,SAAA,EAAA,MAAA;EAAoB,OAAA,EAAA;IAGrC,QAAA,EAAA,MAAA;IAGQ,MAAA,CAAA,EAAA,OAAA;IAM0C,KAAA,CAAA,EAAA,CAAA,CAAA,OAAA,EAAhC,gBAAgC,CAAf,MAAe,CAAA,MAAA,EAAA,SAAA,CAAA,CAAA,EAAA,GAAgB,SAAhB,GAAA,OAAA,CAAA,GAC3C,SAD2C;IAAf,YAAA,CAAA,EAAA;MAAjB,SAAA,EAAA,MAAA;MAAgD,SAAA,EAAA,KAAA,GAAA,MAAA;IAC3D,CAAA;IAKI,KAAA,CAAA,EAAA,MAAA,GAAA,MAAA;IACC,MAAA,CAAA,EAAA,MAAA,GAAA,MAAA;IAED,QAAA,CAAA,EAAA,MAAA;IAMH,KAAA,CAAA,EANG,YAMH,EAAA;EAI0C,CAAA;EAAf,UAAA,EAAA,OAAA;CAAjB,GAAA;EAAgD,IAAA,EAAA,OAAA;EAC3D,KAAA,EALC,QAKD;EAAS,SAAA,EAAA,MAAA;EAIhB,OAAA,EAAA;IAC8B,KAAA,CAAA,EAAA,CAAA,CAAA,OAAA,EANZ,gBAMY,CANK,MAML,CAAA,MAAA,EANoB,SAMpB,CAAA,CAAA,EAAA,GANoC,SAMpC,GAAA,OAAA,CAAA,GALvB,SAKuB;EAInB,CAAA;CACG;KANd,YAAA,GAOU;EAAY,QAAA,EAAA;IAMf,IAAA,EAAA,MAAA;IACkC,KAAA,EAbX,QAaW;IAE/B,EAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA;EACF,CAAA;EACL,OAAA,EAAA;IAAO,MAAA,EAAA,OAAA;IAGH,KAAA,CAAA,EAhBI,SAgBJ;IAAiC,OAAA,CAAA,EAAA,CAf1B,SAe0B,EAAA,KAAA,GAAA,MAAA,CAAA,EAAA;IAClC,IAAA,CAAA,EAfI,YAeJ,EAAA;IACA,KAAA,CAAA,EAAA,MAAA;EACiC,CAAA,GAAA,KAAA;CAA1B;AAAyB,KAX/B,yBAW+B,CAAA,QAAA,CAAA,GAAA;EAiX9B,kBAAA,EAAA,CAAA,UAgKZ,EAAA,MAAA,EAAA,GA3hB6C,QA2hB7C;EA/JgC,yBAAA,EAAA,CAAA,OAAA,EAAA;IAAtB,SAAA,EA1XI,uBA0XJ;IACR,OAAA,EA1XU,QA0XV;EA8JF,CAAA,EAAA,GAvhBO,OAuhBP,CAAA,OAAA,CAAA;AAED,CAAA;AACyC,KAvhB7B,qBAuhB6B,CAAA,WAvhBI,qBAuhBJ,CAAA,GAAA;EAAQ,OAAA,EAthBtC,qBAshBsC;EAAtC,OAAA,EArhBA,SAqhBA,EAAA;EACF,aAAA,CAAA,EArhBS,yBAqhBT,CArhBmC,QAqhBnC,CAAA;CACF;AACD,cAtKO,oBAsKP,EAAA,CAAA,QAAA,CAAA,CAAA,OAAA,EArKK,qBAqKL,CArK2B,QAqK3B,CAAA,EAAA,GApKH,qBAoKG;AACF,cALS,sBAKT,EAAA,CAAA,MAAA,EAAA,QAAA,CAAA,CAAA,OAAA,EAAA;EAAO,OAAA,EAJA,6BAIA,CAJ8B,MAI9B,EAJsC,QAItC,CAAA;SAHF;OACF;MACD;MACF"}