@sixb/sqlite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/action-run-storage.d.ts +29 -0
- package/dist/action-run-storage.d.ts.map +1 -0
- package/dist/agents/agent-storage.d.ts +25 -0
- package/dist/agents/agent-storage.d.ts.map +1 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/messages.d.ts +14 -0
- package/dist/agents/messages.d.ts.map +1 -0
- package/dist/agents/rows.d.ts +77 -0
- package/dist/agents/rows.d.ts.map +1 -0
- package/dist/agents/runs.d.ts +26 -0
- package/dist/agents/runs.d.ts.map +1 -0
- package/dist/agents/threads.d.ts +14 -0
- package/dist/agents/threads.d.ts.map +1 -0
- package/dist/auth-storage/access-tokens.d.ts +33 -0
- package/dist/auth-storage/access-tokens.d.ts.map +1 -0
- package/dist/auth-storage/auth-storage.d.ts +46 -0
- package/dist/auth-storage/auth-storage.d.ts.map +1 -0
- package/dist/auth-storage/group-memberships.d.ts +21 -0
- package/dist/auth-storage/group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/identities.d.ts +17 -0
- package/dist/auth-storage/identities.d.ts.map +1 -0
- package/dist/auth-storage/index.d.ts +3 -0
- package/dist/auth-storage/index.d.ts.map +1 -0
- package/dist/auth-storage/invitations.d.ts +28 -0
- package/dist/auth-storage/invitations.d.ts.map +1 -0
- package/dist/auth-storage/magic-links.d.ts +28 -0
- package/dist/auth-storage/magic-links.d.ts.map +1 -0
- package/dist/auth-storage/oidc-attempts.d.ts +18 -0
- package/dist/auth-storage/oidc-attempts.d.ts.map +1 -0
- package/dist/auth-storage/rows.d.ts +134 -0
- package/dist/auth-storage/rows.d.ts.map +1 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts +17 -0
- package/dist/auth-storage/service-account-group-memberships.d.ts.map +1 -0
- package/dist/auth-storage/service-accounts.d.ts +14 -0
- package/dist/auth-storage/service-accounts.d.ts.map +1 -0
- package/dist/auth-storage/sessions.d.ts +55 -0
- package/dist/auth-storage/sessions.d.ts.map +1 -0
- package/dist/auth-storage/shared.d.ts +131 -0
- package/dist/auth-storage/shared.d.ts.map +1 -0
- package/dist/auth-storage/users.d.ts +19 -0
- package/dist/auth-storage/users.d.ts.map +1 -0
- package/dist/index.d.ts +71 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10204 -0
- package/dist/index.js.map +54 -0
- package/dist/latest-run-query.d.ts +22 -0
- package/dist/latest-run-query.d.ts.map +1 -0
- package/dist/migrations.d.ts +18 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/object-query-compiler.d.ts +44 -0
- package/dist/object-query-compiler.d.ts.map +1 -0
- package/dist/object-storage.d.ts +93 -0
- package/dist/object-storage.d.ts.map +1 -0
- package/dist/ontology-storage/commits.d.ts +14 -0
- package/dist/ontology-storage/commits.d.ts.map +1 -0
- package/dist/ontology-storage/index.d.ts +22 -0
- package/dist/ontology-storage/index.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-session.d.ts +49 -0
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-state.d.ts +63 -0
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -0
- package/dist/ontology-storage/materialization-writer.d.ts +15 -0
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -0
- package/dist/ontology-storage/materializations.d.ts +32 -0
- package/dist/ontology-storage/materializations.d.ts.map +1 -0
- package/dist/ontology-storage/outbox.d.ts +14 -0
- package/dist/ontology-storage/outbox.d.ts.map +1 -0
- package/dist/ontology-storage/shared.d.ts +91 -0
- package/dist/ontology-storage/shared.d.ts.map +1 -0
- package/dist/ontology-storage/sources.d.ts +26 -0
- package/dist/ontology-storage/sources.d.ts.map +1 -0
- package/dist/pipeline-run-storage.d.ts +26 -0
- package/dist/pipeline-run-storage.d.ts.map +1 -0
- package/dist/projection-run-storage.d.ts +32 -0
- package/dist/projection-run-storage.d.ts.map +1 -0
- package/dist/rules-storage.d.ts +33 -0
- package/dist/rules-storage.d.ts.map +1 -0
- package/dist/run-list-query.d.ts +27 -0
- package/dist/run-list-query.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +2 -0
- package/dist/storage-errors.d.ts.map +1 -0
- package/dist/sync-run-storage.d.ts +23 -0
- package/dist/sync-run-storage.d.ts.map +1 -0
- package/dist/timeseries-storage.d.ts +41 -0
- package/dist/timeseries-storage.d.ts.map +1 -0
- package/dist/transactions.d.ts +15 -0
- package/dist/transactions.d.ts.map +1 -0
- package/dist/tsconfig.json +5 -0
- package/dist/validation.d.ts +5 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/webhook-delivery-storage.d.ts +27 -0
- package/dist/webhook-delivery-storage.d.ts.map +1 -0
- package/dist/webhook-run-storage.d.ts +22 -0
- package/dist/webhook-run-storage.d.ts.map +1 -0
- package/dist/workflow-intervention-storage.d.ts +26 -0
- package/dist/workflow-intervention-storage.d.ts.map +1 -0
- package/dist/workflow-run-storage.d.ts +63 -0
- package/dist/workflow-run-storage.d.ts.map +1 -0
- package/package.json +58 -0
- package/src/action-run-storage.ts +761 -0
- package/src/agents/agent-storage.ts +46 -0
- package/src/agents/index.ts +5 -0
- package/src/agents/messages.ts +162 -0
- package/src/agents/rows.ts +205 -0
- package/src/agents/runs.ts +389 -0
- package/src/agents/threads.ts +133 -0
- package/src/auth-storage/access-tokens.ts +289 -0
- package/src/auth-storage/auth-storage.ts +784 -0
- package/src/auth-storage/group-memberships.ts +52 -0
- package/src/auth-storage/identities.ts +98 -0
- package/src/auth-storage/index.ts +2 -0
- package/src/auth-storage/invitations.ts +258 -0
- package/src/auth-storage/magic-links.ts +149 -0
- package/src/auth-storage/oidc-attempts.ts +109 -0
- package/src/auth-storage/rows.ts +338 -0
- package/src/auth-storage/service-account-group-memberships.ts +161 -0
- package/src/auth-storage/service-accounts.ts +168 -0
- package/src/auth-storage/sessions.ts +230 -0
- package/src/auth-storage/shared.ts +707 -0
- package/src/auth-storage/users.ts +226 -0
- package/src/index.ts +292 -0
- package/src/latest-run-query.ts +49 -0
- package/src/migrations/001-initial-schema.sql +1068 -0
- package/src/migrations.ts +245 -0
- package/src/object-query-compiler.ts +1198 -0
- package/src/object-storage.ts +605 -0
- package/src/ontology-storage/commits.ts +127 -0
- package/src/ontology-storage/index.ts +35 -0
- package/src/ontology-storage/materialization-session.ts +393 -0
- package/src/ontology-storage/materialization-state.ts +901 -0
- package/src/ontology-storage/materialization-writer.ts +394 -0
- package/src/ontology-storage/materializations.ts +838 -0
- package/src/ontology-storage/outbox.ts +237 -0
- package/src/ontology-storage/shared.ts +269 -0
- package/src/ontology-storage/sources.ts +653 -0
- package/src/pipeline-run-storage.ts +506 -0
- package/src/projection-run-storage.ts +592 -0
- package/src/rules-storage.ts +375 -0
- package/src/run-list-query.ts +98 -0
- package/src/sql.d.ts +4 -0
- package/src/storage-errors.ts +3 -0
- package/src/sync-run-storage.ts +299 -0
- package/src/timeseries-storage.ts +212 -0
- package/src/transactions.ts +96 -0
- package/src/validation.ts +30 -0
- package/src/webhook-delivery-storage.ts +272 -0
- package/src/webhook-run-storage.ts +240 -0
- package/src/workflow-intervention-storage.ts +398 -0
- package/src/workflow-run-storage.ts +1148 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/action-run-storage.ts", "../src/migrations.ts", "../src/transactions.ts", "../src/agents/messages.ts", "../src/storage-errors.ts", "../src/agents/rows.ts", "../src/agents/runs.ts", "../src/run-list-query.ts", "../src/agents/threads.ts", "../src/agents/agent-storage.ts", "../src/auth-storage/auth-storage.ts", "../src/auth-storage/access-tokens.ts", "../src/auth-storage/rows.ts", "../src/auth-storage/shared.ts", "../src/auth-storage/group-memberships.ts", "../src/auth-storage/identities.ts", "../src/auth-storage/invitations.ts", "../src/auth-storage/magic-links.ts", "../src/auth-storage/oidc-attempts.ts", "../src/auth-storage/service-account-group-memberships.ts", "../src/auth-storage/service-accounts.ts", "../src/auth-storage/sessions.ts", "../src/auth-storage/users.ts", "../src/object-query-compiler.ts", "../src/object-storage.ts", "../src/ontology-storage/shared.ts", "../src/ontology-storage/commits.ts", "../src/ontology-storage/materializations.ts", "../src/ontology-storage/materialization-session.ts", "../src/ontology-storage/materialization-state.ts", "../src/ontology-storage/materialization-writer.ts", "../src/ontology-storage/outbox.ts", "../src/ontology-storage/sources.ts", "../src/ontology-storage/index.ts", "../src/pipeline-run-storage.ts", "../src/latest-run-query.ts", "../src/projection-run-storage.ts", "../src/rules-storage.ts", "../src/sync-run-storage.ts", "../src/timeseries-storage.ts", "../src/webhook-delivery-storage.ts", "../src/webhook-run-storage.ts", "../src/workflow-intervention-storage.ts", "../src/workflow-run-storage.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Keep SQL module declarations visible to downstream workspaces that typecheck this package from\n// source.\n/// <reference path=\"./sql.d.ts\" />\n\nimport { AsyncLocalStorage } from \"node:async_hooks\"\nimport type {\n MigrationCapableStorage,\n Storage,\n StorageMigrator,\n StorageTransactionOptions,\n} from \"@sixb/core\"\nimport { ProviderMaterializationTransactionLifecycle } from \"@sixb/core/internal/ontology-storage-provider\"\nimport {\n createAgentOperationScope,\n createAuthOperationScope,\n createOntologyOperationScope,\n createOperationScopedFacade,\n createStorageOperationScope,\n createWorkflowRunOperationScope,\n} from \"@sixb/core/internal/storage-operation-scope\"\nimport {\n createTransactionStorageProxy,\n StorageTransactionError,\n throwNestedStorageTransaction,\n} from \"@sixb/core/storage\"\nimport { SqliteActionRunStorage } from \"./action-run-storage\"\nimport { SqliteAgentStorage } from \"./agents\"\nimport { SqliteAuthStorage } from \"./auth-storage\"\nimport {\n createSqliteStorageMigrators,\n installFreshSqliteSchema,\n sqliteStoragePath,\n} from \"./migrations\"\nimport { SqliteObjectStorage } from \"./object-storage\"\nimport { SqliteOntologyStorage, type SqliteOntologyTransactionContext } from \"./ontology-storage\"\nimport { SqlitePipelineRunStorage } from \"./pipeline-run-storage\"\nimport { SqliteProjectionRunStorage } from \"./projection-run-storage\"\nimport { SqliteRulesStorage } from \"./rules-storage\"\nimport { SqliteSyncRunStorage } from \"./sync-run-storage\"\nimport { SqliteTimeseriesStorage } from \"./timeseries-storage\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n runImmediateTransactionAsync,\n type SqliteStoreConnection,\n} from \"./transactions\"\nimport { SqliteWebhookDeliveryStorage } from \"./webhook-delivery-storage\"\nimport { SqliteWebhookRunStorage } from \"./webhook-run-storage\"\nimport { SqliteWorkflowInterventionStorage } from \"./workflow-intervention-storage\"\nimport { SqliteWorkflowRunStorage } from \"./workflow-run-storage\"\n\nexport interface SqliteStorageOptions {\n /** Directory path for the SQLite storage database. */\n path?: string\n}\n\n/**\n * SQLite storage provider for Sixb.\n *\n * Bundles object, timeseries, auth, sync run, pipeline run, projection run, workflow run, webhook\n * run, and webhook delivery storage backed by SQLite.\n *\n * Usage:\n * ```ts\n * const storage = new SqliteStorage({ path: \".sixb\" })\n *\n * export const sixb = createSixb({\n * broker: new InMemoryBroker(),\n * storage,\n * })\n * ```\n */\nexport class SqliteStorage implements MigrationCapableStorage {\n readonly objects: Storage[\"objects\"]\n readonly ontology: SqliteOntologyStorage\n readonly auth: SqliteAuthStorage\n readonly agents: SqliteAgentStorage\n readonly actionRuns: SqliteActionRunStorage\n readonly pipelineRuns: SqlitePipelineRunStorage\n readonly syncRuns: SqliteSyncRunStorage\n readonly projectionRuns: SqliteProjectionRunStorage\n readonly workflowRuns: SqliteWorkflowRunStorage\n readonly workflowInterventions: SqliteWorkflowInterventionStorage\n readonly timeseries: Storage[\"timeseries\"]\n readonly webhookDeliveries: SqliteWebhookDeliveryStorage\n readonly webhookRuns: SqliteWebhookRunStorage\n readonly rules: SqliteRulesStorage\n readonly migrators: readonly StorageMigrator[]\n\n private readonly connection: SqliteStoreConnection\n private readonly transactionScope = new AsyncLocalStorage<{ active: boolean }>()\n private transactionTail: Promise<void> = Promise.resolve()\n\n constructor(options: SqliteStorageOptions = {}) {\n const path = options.path ? sqliteStoragePath(options.path) : undefined\n this.connection = openSqliteStoreConnection({ path })\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.connection.db)\n }\n\n const stores = createSqliteStores(this.connection, {\n runOntologyOperation: async (run) => run(),\n transactionContext: null,\n })\n const assertRootOperationAvailable = () => this.assertRootOperationAvailable()\n const scope = createStorageOperationScope(\n (run) => this.runRootStorageOperation(run),\n assertRootOperationAvailable\n )\n const ontologyScope = createStorageOperationScope(\n (run) => this.runRootOntologyOperation(run),\n assertRootOperationAvailable\n )\n this.objects = createOperationScopedFacade(stores.objects, scope)\n this.ontology = createOntologyOperationScope(stores.ontology, ontologyScope)\n this.auth = createAuthOperationScope(stores.auth, scope)\n this.agents = createAgentOperationScope(stores.agents, scope)\n this.actionRuns = createOperationScopedFacade(stores.actionRuns, scope)\n this.pipelineRuns = createOperationScopedFacade(stores.pipelineRuns, scope)\n this.timeseries = createOperationScopedFacade(stores.timeseries, scope)\n this.syncRuns = createOperationScopedFacade(stores.syncRuns, scope)\n this.projectionRuns = createOperationScopedFacade(stores.projectionRuns, scope)\n this.workflowRuns = createWorkflowRunOperationScope(stores.workflowRuns, scope)\n this.workflowInterventions = createOperationScopedFacade(stores.workflowInterventions, scope)\n this.webhookDeliveries = createOperationScopedFacade(stores.webhookDeliveries, scope)\n this.webhookRuns = createOperationScopedFacade(stores.webhookRuns, scope)\n this.rules = createOperationScopedFacade(stores.rules, scope)\n this.migrators = options.path ? createSqliteStorageMigrators(options.path) : []\n }\n\n async ping(): Promise<void> {\n await this.runRootStorageOperation(() => {\n this.connection.db.query(\"SELECT 1\").get()\n })\n }\n\n /**\n * The `isolation` option is intentionally ignored. SQLite runs every transaction through one\n * shared connection serialized by {@link withTransactionLock} and a `BEGIN IMMEDIATE`, so there is\n * no concurrent transaction to isolate against — the lock already provides serializable semantics\n * for transaction-vs-transaction races. Postgres, which has true concurrent connections, is where\n * `isolation: \"serializable\"` translates to a real isolation level.\n */\n async transaction<T>(\n run: (tx: Storage) => Promise<T> | T,\n _options: StorageTransactionOptions = {}\n ): Promise<T> {\n if (this.transactionScope.getStore()) {\n throwNestedStorageTransaction()\n }\n\n return this.withTransactionLock(async () => {\n let active = true\n const scope = { active: true }\n const transactionContext: SqliteOntologyTransactionContext = {\n id: {},\n materializations: new ProviderMaterializationTransactionLifecycle(),\n active: true,\n }\n const txStorage = this.createTransactionStorage(transactionContext)\n const tx = createTransactionStorageProxy(txStorage, () => active)\n\n try {\n return await runImmediateTransactionAsync(this.connection.db, () =>\n this.transactionScope.run(scope, async () => {\n try {\n const result = await run(tx)\n transactionContext.materializations.assertCommittable()\n return result\n } finally {\n scope.active = false\n transactionContext.active = false\n txStorage.ontology.deactivateSessions()\n transactionContext.materializations.deactivate()\n }\n })\n )\n } finally {\n active = false\n }\n })\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private createTransactionStorage(\n transactionContext: SqliteOntologyTransactionContext\n ): Storage & { readonly ontology: SqliteOntologyStorage } {\n return {\n ...createSqliteStores(\n {\n db: this.connection.db,\n ownsConnection: false,\n installFreshSchema: false,\n },\n {\n runOntologyOperation: async (run) => run(),\n transactionContext,\n }\n ),\n ping: async () => {\n this.connection.db.query(\"SELECT 1\").get()\n },\n transaction: async <T>(): Promise<T> => {\n throwNestedStorageTransaction()\n },\n }\n }\n\n private runRootStorageOperation<T>(run: () => Promise<T> | T): Promise<T> {\n this.assertRootOperationAvailable()\n return this.withTransactionLock(async () => run())\n }\n\n private runRootOntologyOperation<T>(run: () => Promise<T> | T): Promise<T> {\n this.assertRootOperationAvailable()\n return this.withTransactionLock(() => runImmediateTransactionAsync(this.connection.db, run))\n }\n\n private assertRootOperationAvailable(): void {\n if (!this.transactionScope.getStore()?.active) return\n throw new StorageTransactionError(\n \"[SixbSqlite] Root storage cannot be used inside a transaction callback; use the provided tx storage.\"\n )\n }\n\n private async withTransactionLock<T>(run: () => Promise<T>): Promise<T> {\n const previous = this.transactionTail\n let release!: () => void\n this.transactionTail = new Promise<void>((resolve) => {\n release = resolve\n })\n\n await previous\n try {\n return await run()\n } finally {\n release()\n }\n }\n}\n\nfunction createSqliteStores(\n connection: SqliteStoreConnection,\n options: {\n readonly runOntologyOperation: <T>(run: () => Promise<T> | T) => Promise<T>\n readonly transactionContext: SqliteOntologyTransactionContext | null\n }\n): SqliteStoreSet {\n return {\n objects: new SqliteObjectStorage({ connection }),\n ontology: new SqliteOntologyStorage({\n db: connection.db,\n runRootOperation: options.runOntologyOperation,\n transactionContext: options.transactionContext,\n }),\n auth: new SqliteAuthStorage({ connection }),\n agents: new SqliteAgentStorage({ connection }),\n actionRuns: new SqliteActionRunStorage({ connection }),\n pipelineRuns: new SqlitePipelineRunStorage({ connection }),\n timeseries: new SqliteTimeseriesStorage({ connection }),\n syncRuns: new SqliteSyncRunStorage({ connection }),\n projectionRuns: new SqliteProjectionRunStorage({ connection }),\n workflowRuns: new SqliteWorkflowRunStorage({ connection }),\n workflowInterventions: new SqliteWorkflowInterventionStorage({ connection }),\n webhookDeliveries: new SqliteWebhookDeliveryStorage({ connection }),\n webhookRuns: new SqliteWebhookRunStorage({ connection }),\n rules: new SqliteRulesStorage({ connection }),\n }\n}\n\ninterface SqliteStoreSet {\n readonly objects: SqliteObjectStorage\n readonly ontology: SqliteOntologyStorage\n readonly auth: SqliteAuthStorage\n readonly agents: SqliteAgentStorage\n readonly actionRuns: SqliteActionRunStorage\n readonly pipelineRuns: SqlitePipelineRunStorage\n readonly syncRuns: SqliteSyncRunStorage\n readonly projectionRuns: SqliteProjectionRunStorage\n readonly workflowRuns: SqliteWorkflowRunStorage\n readonly workflowInterventions: SqliteWorkflowInterventionStorage\n readonly timeseries: SqliteTimeseriesStorage\n readonly webhookDeliveries: SqliteWebhookDeliveryStorage\n readonly webhookRuns: SqliteWebhookRunStorage\n readonly rules: SqliteRulesStorage\n}\n\nexport { migrateSqliteStorage } from \"./migrations\"\n",
|
|
6
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { ActionSubject, JsonValue } from \"@sixb/core\"\nimport type {\n ActionRunEffectsRecord,\n ActionRunFailure,\n ActionRunParams,\n ActionRunPhase,\n ActionRunRecord,\n ActionRunStorage,\n ActionRunWritebackRecord,\n EnterActionRunPhaseInput,\n FinishActionRunInput,\n ListActionRunsInput,\n ListActionRunsResult,\n LockActionMaterializationRunInput,\n QueueActionRunInput,\n RecordActionEffectsInput,\n RecordActionWritebackInput,\n StartActionRunInput,\n} from \"@sixb/core/storage\"\nimport {\n ActionRunError,\n actionRunPhaseRecordsEqual,\n canRequeueActionRunAfterEnqueueFailure,\n finishActionRunPhase,\n isTerminalActionRun,\n} from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteActionRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteActionRunStorage implements ActionRunStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteActionRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async lockForMaterialization(input: LockActionMaterializationRunInput): Promise<ActionRunRecord> {\n const row = this.db\n .query(`SELECT action_id, status FROM action_runs WHERE project_id = ? AND id = ?`)\n .get(input.projectId, input.runId) as {\n readonly action_id: string\n readonly status: string\n } | null\n if (!row) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.runId}' not found for project '${input.projectId}'.`\n )\n }\n if (row.action_id !== input.actionId) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.runId}' does not belong to action '${input.actionId}'.`\n )\n }\n if (row.status !== \"running\") {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.runId}' cannot materialize from status '${row.status}'.`\n )\n }\n const record = await this.getById({ projectId: input.projectId, id: input.runId })\n if (!record) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.runId}' disappeared while locking materialization.`\n )\n }\n return record\n }\n\n async queue(input: QueueActionRunInput): Promise<ActionRunRecord> {\n const queuedAt = input.queuedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO action_runs (\n project_id,\n id,\n action_id,\n subject_kind,\n object_type_id,\n primary_id,\n status,\n phase,\n queued_at,\n started_at,\n finished_at,\n params,\n idempotency_key,\n writeback_status,\n writeback_completed_at,\n writeback_result,\n writeback_error_name,\n writeback_error_message,\n writeback_error_phase,\n effects_status,\n effects_completed_at,\n effects_error_name,\n effects_error_message,\n effects_error_phase,\n error_name,\n error_message,\n error_phase\n ) VALUES (\n ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, NULL, ?, ?,\n NULL, NULL, NULL, NULL, NULL, NULL,\n NULL, NULL, NULL, NULL, NULL,\n NULL, NULL, NULL\n )\n `\n )\n .run(\n input.projectId,\n input.id,\n input.actionId,\n input.subject.kind,\n input.subject.kind === \"object\" ? input.subject.objectTypeId : null,\n input.subject.kind === \"object\" ? input.subject.primaryId : null,\n \"queued\",\n \"request\",\n queuedAt.toISOString(),\n JSON.stringify(input.params),\n input.idempotencyKey\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n return this.requeueAfterEnqueueFailure(input, queuedAt)\n }\n\n throw error\n }\n\n const record = await this.getById({ projectId: input.projectId, id: input.id })\n if (!record) {\n throw new ActionRunError(\n `[SixbSqlite] Failed to load action run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return record\n }\n\n private async requeueAfterEnqueueFailure(\n input: QueueActionRunInput,\n queuedAt: Date\n ): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow | null\n\n if (\n !existing ||\n !canRequeueActionRunAfterEnqueueFailure(rowToActionRunRecord(existing), input)\n ) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET\n status = ?,\n phase = ?,\n queued_at = ?,\n started_at = NULL,\n finished_at = NULL,\n writeback_status = NULL,\n writeback_completed_at = NULL,\n writeback_result = NULL,\n writeback_error_name = NULL,\n writeback_error_message = NULL,\n writeback_error_phase = NULL,\n effects_status = NULL,\n effects_completed_at = NULL,\n effects_error_name = NULL,\n effects_error_message = NULL,\n effects_error_phase = NULL,\n error_name = NULL,\n error_message = NULL,\n error_phase = NULL\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\"queued\", \"request\", queuedAt.toISOString(), input.projectId, input.id)\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async start(input: StartActionRunInput): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow | null\n\n if (!existing) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"queued\") {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' cannot start from status '${existing.status}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET\n status = ?,\n phase = ?,\n started_at = ?,\n error_name = NULL,\n error_message = NULL,\n error_phase = NULL\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"running\",\n input.phase ?? \"validation\",\n (input.startedAt ?? new Date()).toISOString(),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async enterPhase(input: EnterActionRunPhaseInput): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n this.requireRunningRun(input.projectId, input.id, \"transition phase\")\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET phase = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(input.phase, input.projectId, input.id)\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async recordWriteback(input: RecordActionWritebackInput): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n const existing = this.requireRunningRun(input.projectId, input.id, \"record writeback\")\n const nextWriteback = toWritebackRecord(input, new Date(input.completedAt ?? new Date()))\n const currentWriteback = toActionRunWritebackRecord(existing)\n\n if (currentWriteback) {\n if (actionRunPhaseRecordsEqual(currentWriteback, nextWriteback)) {\n return rowToActionRunRecord(existing)\n }\n\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' already has a different writeback record.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET\n phase = ?,\n writeback_status = ?,\n writeback_completed_at = ?,\n writeback_result = ?,\n writeback_error_name = ?,\n writeback_error_message = ?,\n writeback_error_phase = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"writeback\",\n input.status,\n nextWriteback.completedAt.toISOString(),\n input.status === \"succeeded\" ? serializeJsonValue(input.result) : null,\n input.status === \"failed\" ? (input.error.name ?? null) : null,\n input.status === \"failed\" ? input.error.message : null,\n input.status === \"failed\" ? (input.error.phase ?? \"writeback\") : null,\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async recordEffects(input: RecordActionEffectsInput): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n const existing = this.requireRunningRun(input.projectId, input.id, \"record effects\")\n const nextEffects = toEffectsRecord(input, new Date(input.completedAt ?? new Date()))\n const currentEffects = toActionRunEffectsRecord(existing)\n\n if (currentEffects) {\n if (actionRunPhaseRecordsEqual(currentEffects, nextEffects)) {\n return rowToActionRunRecord(existing)\n }\n\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' already has a different effects record.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET\n phase = ?,\n effects_status = ?,\n effects_completed_at = ?,\n effects_error_name = ?,\n effects_error_message = ?,\n effects_error_phase = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"effects\",\n input.status,\n nextEffects.completedAt.toISOString(),\n input.status === \"failed\" ? (input.error.name ?? null) : null,\n input.status === \"failed\" ? input.error.message : null,\n input.status === \"failed\" ? (input.error.phase ?? \"effects\") : null,\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async finish(input: FinishActionRunInput): Promise<ActionRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow | null\n\n if (!existing) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (isTerminalActionRun({ status: existing.status })) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${input.id}' cannot finish from terminal status '${existing.status}'.`\n )\n }\n\n const phase = finishActionRunPhase(input, existing.phase)\n\n this.db\n .query(\n `\n UPDATE action_runs\n SET\n status = ?,\n phase = ?,\n finished_at = ?,\n error_name = ?,\n error_message = ?,\n error_phase = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n phase,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\" ? null : (input.error?.name ?? null),\n input.status === \"succeeded\" ? null : (input.error?.message ?? null),\n input.status === \"succeeded\" ? null : (input.error?.phase ?? phase),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToActionRunRecord(updated)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<ActionRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as DatabaseRow | null\n\n return row ? rowToActionRunRecord(row) : null\n }\n\n async list(input: ListActionRunsInput): Promise<ListActionRunsResult> {\n if ((input.statuses && input.statuses.length === 0) || input.actionIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: (string | number)[] = [input.projectId]\n\n if (input.actionId) {\n whereClauses.push(\"action_id = ?\")\n args.push(input.actionId)\n }\n\n if (input.actionIds) {\n whereClauses.push(`action_id IN (${input.actionIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.actionIds)\n }\n\n if (input.objectTypeIds) {\n if (input.objectTypeIds.length === 0) {\n whereClauses.push(\"subject_kind <> ?\")\n args.push(\"object\")\n } else {\n whereClauses.push(\n `(subject_kind <> ? OR object_type_id IN (${input.objectTypeIds\n .map(() => \"?\")\n .join(\", \")}))`\n )\n args.push(\"object\", ...input.objectTypeIds)\n }\n }\n\n if (input.objectTypeId) {\n whereClauses.push(\"subject_kind = ?\")\n args.push(\"object\")\n whereClauses.push(\"object_type_id = ?\")\n args.push(input.objectTypeId)\n }\n\n if (input.primaryId) {\n whereClauses.push(\"subject_kind = ?\")\n args.push(\"object\")\n whereClauses.push(\"primary_id = ?\")\n args.push(input.primaryId)\n }\n\n if (input.subject) {\n whereClauses.push(\"subject_kind = ?\")\n args.push(input.subject.kind)\n if (input.subject.kind === \"object\") {\n whereClauses.push(\"object_type_id = ?\")\n args.push(input.subject.objectTypeId)\n whereClauses.push(\"primary_id = ?\")\n args.push(input.subject.primaryId)\n }\n }\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n if (input.startedAfter) {\n whereClauses.push(\"COALESCE(started_at, queued_at) >= ?\")\n args.push(input.startedAfter.toISOString())\n }\n\n if (input.startedBefore) {\n whereClauses.push(\"COALESCE(started_at, queued_at) <= ?\")\n args.push(input.startedBefore.toISOString())\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n const limit = input.limit\n\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM action_runs ${where}`)\n .get(...args) as { count: number }\n\n let query = `\n SELECT * FROM action_runs\n ${where}\n ORDER BY COALESCE(started_at, queued_at) ${order}, id ${order}\n `\n const queryArgs = [...args]\n\n if (limit !== undefined) {\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(limit, offset)\n } else if (offset > 0) {\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = this.db.query(query).all(...queryArgs) as DatabaseRow[]\n const runs = rows.map((row) => rowToActionRunRecord(row))\n\n return {\n runs,\n hasMore: offset + runs.length < totalRow.count,\n total: totalRow.count,\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private requireRunningRun(projectId: string, id: string, operation: string): DatabaseRow {\n const existing = this.db\n .query(\"SELECT * FROM action_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as DatabaseRow | null\n\n if (!existing) {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new ActionRunError(\n `[SixbSqlite] Action run '${id}' cannot ${operation} from status '${existing.status}'.`\n )\n }\n\n return existing\n }\n}\n\nfunction serializeJsonValue(value: JsonValue): string {\n return JSON.stringify(value)\n}\n\nfunction toActionRunFailure(row: DatabaseRow): ActionRunFailure | undefined {\n return toFailure(row.error_name, row.error_message, row.error_phase)\n}\n\nfunction toFailure(\n name: string | null,\n message: string | null,\n phase: ActionRunPhase | null\n): ActionRunFailure | undefined {\n if (!message) {\n return undefined\n }\n\n return {\n name: name ?? undefined,\n message,\n phase: phase ?? undefined,\n }\n}\n\nfunction toActionRunWritebackRecord(row: DatabaseRow): ActionRunWritebackRecord | undefined {\n if (!row.writeback_status) {\n return undefined\n }\n\n const completedAt = row.writeback_completed_at\n ? new Date(row.writeback_completed_at)\n : new Date(row.queued_at)\n\n if (row.writeback_status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n result:\n row.writeback_result === null ? null : (JSON.parse(row.writeback_result) as JsonValue),\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: toFailure(\n row.writeback_error_name,\n row.writeback_error_message,\n row.writeback_error_phase\n ),\n }\n}\n\nfunction toActionRunEffectsRecord(row: DatabaseRow): ActionRunEffectsRecord | undefined {\n if (!row.effects_status) {\n return undefined\n }\n\n const completedAt = row.effects_completed_at\n ? new Date(row.effects_completed_at)\n : new Date(row.queued_at)\n\n if (row.effects_status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: toFailure(row.effects_error_name, row.effects_error_message, row.effects_error_phase),\n }\n}\n\nfunction toWritebackRecord(\n input: RecordActionWritebackInput,\n completedAt: Date\n): ActionRunWritebackRecord {\n if (input.status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n result: input.result,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: input.error,\n }\n}\n\nfunction toEffectsRecord(\n input: RecordActionEffectsInput,\n completedAt: Date\n): ActionRunEffectsRecord {\n if (input.status === \"succeeded\") {\n return {\n status: \"succeeded\",\n completedAt,\n }\n }\n\n return {\n status: \"failed\",\n completedAt,\n error: input.error,\n }\n}\n\nfunction rowToActionRunRecord(row: DatabaseRow): ActionRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n actionId: row.action_id,\n subject: rowToActionSubject(row),\n status: row.status,\n phase: row.phase ?? undefined,\n queuedAt: new Date(row.queued_at),\n startedAt: row.started_at ? new Date(row.started_at) : undefined,\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n params: JSON.parse(row.params) as ActionRunParams,\n idempotencyKey: row.idempotency_key,\n writeback: toActionRunWritebackRecord(row),\n effects: toActionRunEffectsRecord(row),\n error: toActionRunFailure(row),\n }\n}\n\nfunction rowToActionSubject(row: DatabaseRow): ActionSubject {\n if (row.subject_kind === \"none\") {\n return { kind: \"none\" }\n }\n\n if (!row.object_type_id || !row.primary_id) {\n throw new ActionRunError(`[SixbSqlite] Action run '${row.id}' has an invalid object subject.`)\n }\n\n return {\n kind: \"object\",\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n }\n}\n\nfunction isUniqueConstraintError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(\"UNIQUE constraint failed\")\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n action_id: string\n subject_kind: ActionSubject[\"kind\"]\n object_type_id: string | null\n primary_id: string | null\n status: ActionRunRecord[\"status\"]\n phase: ActionRunPhase | null\n queued_at: string\n started_at: string | null\n finished_at: string | null\n params: string\n idempotency_key: string\n writeback_status: ActionRunWritebackRecord[\"status\"] | null\n writeback_completed_at: string | null\n writeback_result: string | null\n writeback_error_name: string | null\n writeback_error_message: string | null\n writeback_error_phase: ActionRunPhase | null\n effects_status: ActionRunEffectsRecord[\"status\"] | null\n effects_completed_at: string | null\n effects_error_name: string | null\n effects_error_message: string | null\n effects_error_phase: ActionRunPhase | null\n error_name: string | null\n error_message: string | null\n error_phase: ActionRunPhase | null\n}\n",
|
|
7
|
+
"import { Database } from \"bun:sqlite\"\nimport { createHash } from \"node:crypto\"\nimport { existsSync, mkdirSync } from \"node:fs\"\nimport { dirname } from \"node:path\"\nimport type { StorageMigrator } from \"@sixb/core\"\nimport type {\n MigrationHistoryStore,\n MigrationRecord,\n MigrationSet,\n MigrationStep,\n MigrationStepOptions,\n} from \"@sixb/core/storage\"\nimport {\n defineMigrations,\n describeMigrationHistory,\n runMigrationSet,\n step,\n} from \"@sixb/core/storage\"\nimport initialSchemaSql from \"./migrations/001-initial-schema.sql\" with { type: \"text\" }\n\nconst MIGRATIONS_TABLE_SQL = `\n CREATE TABLE IF NOT EXISTS sixb_migrations (\n adapter_id TEXT NOT NULL,\n version INTEGER NOT NULL,\n id TEXT NOT NULL,\n checksum TEXT,\n status TEXT NOT NULL,\n started_at TEXT NOT NULL,\n finished_at TEXT,\n PRIMARY KEY (adapter_id, version)\n );\n`\n\nexport const SQLITE_STORAGE_ADAPTER_ID = \"SixbSqliteStorage\"\nexport const SQLITE_STORAGE_FILE = \"storage.sqlite\"\n\nexport const sqliteStorageMigrations = defineMigrations({\n adapterId: SQLITE_STORAGE_ADAPTER_ID,\n steps: [sqliteSql(\"001-initial-schema\", initialSchemaSql)],\n})\n\nexport function sqliteStoragePath(basePath: string): string {\n return `${basePath}/${SQLITE_STORAGE_FILE}`\n}\n\nexport function sqliteSql(id: string, sqlText: string): MigrationStep<Database> {\n return sqliteStep(\n id,\n (db) => {\n db.run(sqlText)\n },\n { checksum: checksum(sqlText) }\n )\n}\n\nexport function sqliteStep(\n id: string,\n up: (db: Database) => void | Promise<void>,\n options: MigrationStepOptions = {}\n): MigrationStep<Database> {\n return step<Database>(id, up, options)\n}\n\nexport function installFreshSqliteSchema(db: Database): void {\n for (const migration of sqliteStorageMigrations.steps) {\n const installed = migration.up(db)\n if (installed instanceof Promise) {\n throw new Error(\n `[${sqliteStorageMigrations.adapterId}] Fresh SQLite schema installation must be synchronous`\n )\n }\n }\n}\n\nexport function createSqliteStorageMigrators(basePath: string): readonly StorageMigrator[] {\n return [\n createSqliteMigrator({\n path: sqliteStoragePath(basePath),\n migrations: sqliteStorageMigrations,\n }),\n ]\n}\n\nexport function createSqliteMigrator(params: {\n readonly path: string\n readonly migrations: MigrationSet<Database>\n}): StorageMigrator {\n return {\n adapterId: params.migrations.adapterId,\n latestVersion: params.migrations.latestVersion,\n async status() {\n return describeMigrationHistory({\n migrations: params.migrations,\n rows: await readSqliteHistory(params.path, params.migrations.adapterId),\n })\n },\n async migrate() {\n return withSqliteDatabase(params.path, (db) =>\n runMigrationSet({\n context: db,\n migrations: params.migrations,\n state: sqliteMigrationHistoryStore(db),\n })\n )\n },\n }\n}\n\nexport async function migrateSqliteStorage(basePath: string): Promise<void> {\n mkdirSync(basePath, { recursive: true })\n\n for (const migrator of createSqliteStorageMigrators(basePath)) {\n await migrator.migrate()\n }\n}\n\nexport async function migrateSqliteDatabase(path: string): Promise<void> {\n await createSqliteMigrator({ path, migrations: sqliteStorageMigrations }).migrate()\n}\n\nfunction sqliteMigrationHistoryStore(db: Database): MigrationHistoryStore {\n return {\n ensure() {\n db.run(MIGRATIONS_TABLE_SQL)\n },\n readHistory(adapterId) {\n return db\n .query(\"SELECT * FROM sixb_migrations WHERE adapter_id = ? ORDER BY version\")\n .all(adapterId)\n .map(rowToMigrationRecord)\n },\n markStarted(adapterId, migration, at) {\n db.query(`\n INSERT INTO sixb_migrations (\n adapter_id, version, id, checksum, status, started_at, finished_at\n ) VALUES (?, ?, ?, ?, 'started', ?, NULL)\n ON CONFLICT(adapter_id, version) DO UPDATE SET\n id = excluded.id,\n checksum = excluded.checksum,\n status = excluded.status,\n started_at = excluded.started_at,\n finished_at = NULL\n `).run(adapterId, migration.version, migration.id, migration.checksum ?? null, at)\n },\n markApplied(adapterId, migration, at) {\n db.query(`\n UPDATE sixb_migrations\n SET status = 'applied', finished_at = ?\n WHERE adapter_id = ? AND version = ?\n `).run(at, adapterId, migration.version)\n },\n async transaction(run) {\n db.run(\"BEGIN\")\n\n try {\n const result = await run()\n db.run(\"COMMIT\")\n return result\n } catch (error) {\n rollbackQuietly(db)\n throw error\n }\n },\n }\n}\n\nfunction rowToMigrationRecord(row: unknown): MigrationRecord {\n const migration = row as {\n adapter_id: string\n version: number\n id: string\n checksum: string | null\n status: \"started\" | \"applied\"\n started_at: string\n finished_at: string | null\n }\n\n return {\n adapterId: migration.adapter_id,\n version: migration.version,\n id: migration.id,\n checksum: migration.checksum ?? undefined,\n status: migration.status,\n startedAt: migration.started_at,\n finishedAt: migration.finished_at ?? undefined,\n }\n}\n\nfunction checksum(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\")\n}\n\n/**\n * Reads migration history without creating anything. `null` means there is no history\n * to read, which is a state and not a failure.\n *\n * `new Database(path)` creates the file, and `withSqliteDatabase` additionally mkdirs\n * its parent — fine on the way to a migration, wrong for a probe. So: `existsSync`\n * first, then open `readonly` so even a mistake below cannot write. `:memory:` is\n * always empty on a fresh connection, so there is nothing to report.\n */\nasync function readSqliteHistory(\n path: string,\n adapterId: string\n): Promise<readonly MigrationRecord[] | null> {\n if (path === \":memory:\" || !existsSync(path)) {\n return null\n }\n\n const db = new Database(path, { readonly: true })\n try {\n const table = db\n .query(\"SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'sixb_migrations'\")\n .get()\n if (!table) {\n return null\n }\n\n return db\n .query(\"SELECT * FROM sixb_migrations WHERE adapter_id = ? ORDER BY version\")\n .all(adapterId)\n .map(rowToMigrationRecord)\n } finally {\n db.close()\n }\n}\n\nasync function withSqliteDatabase<T>(path: string, run: (db: Database) => Promise<T>): Promise<T> {\n if (path !== \":memory:\") mkdirSync(dirname(path), { recursive: true })\n const db = new Database(path)\n\n try {\n return await run(db)\n } finally {\n db.close()\n }\n}\n\nfunction rollbackQuietly(db: Database): void {\n try {\n db.run(\"ROLLBACK\")\n } catch {\n // Ignore rollback errors so the original migration failure is preserved.\n }\n}\n",
|
|
8
|
+
"import type { Database } from \"bun:sqlite\"\nimport { Database as SqliteDatabase } from \"bun:sqlite\"\nimport { mkdirSync } from \"node:fs\"\nimport { dirname } from \"node:path\"\n\nexport interface SqliteStoreConnection {\n readonly db: Database\n readonly ownsConnection: boolean\n readonly installFreshSchema: boolean\n}\n\nexport interface SqliteStoreConnectionOptions {\n readonly path?: string\n readonly connection?: SqliteStoreConnection\n}\n\nexport function openSqliteStoreConnection(\n options: SqliteStoreConnectionOptions = {}\n): SqliteStoreConnection {\n if (options.connection) {\n return {\n db: options.connection.db,\n ownsConnection: false,\n installFreshSchema: false,\n }\n }\n\n const path = options.path ?? \":memory:\"\n if (path !== \":memory:\") mkdirSync(dirname(path), { recursive: true })\n const db = new SqliteDatabase(path)\n db.run(\"PRAGMA foreign_keys = ON\")\n return {\n db,\n ownsConnection: true,\n installFreshSchema: path === \":memory:\",\n }\n}\n\nexport function closeSqliteStoreConnection(connection: SqliteStoreConnection): void {\n if (connection.ownsConnection) {\n connection.db.close()\n }\n}\n\nconst activeImmediateTransactions = new WeakSet<Database>()\n\nexport function runImmediateTransaction<T>(db: Database, run: () => T): T {\n if (activeImmediateTransactions.has(db)) {\n return run()\n }\n\n db.run(\"BEGIN IMMEDIATE\")\n activeImmediateTransactions.add(db)\n\n try {\n const result = run()\n db.run(\"COMMIT\")\n return result\n } catch (error) {\n rollbackQuietly(db)\n throw error\n } finally {\n activeImmediateTransactions.delete(db)\n }\n}\n\nexport async function runImmediateTransactionAsync<T>(\n db: Database,\n run: () => Promise<T> | T\n): Promise<T> {\n if (activeImmediateTransactions.has(db)) {\n return run()\n }\n\n db.run(\"BEGIN IMMEDIATE\")\n activeImmediateTransactions.add(db)\n\n try {\n const result = await run()\n db.run(\"COMMIT\")\n return result\n } catch (error) {\n rollbackQuietly(db)\n throw error\n } finally {\n activeImmediateTransactions.delete(db)\n }\n}\n\nfunction rollbackQuietly(db: Database): void {\n try {\n db.run(\"ROLLBACK\")\n } catch {\n // Preserve the original SQLite storage failure.\n }\n}\n",
|
|
9
|
+
"import type { Database } from \"bun:sqlite\"\nimport { AGENT_MESSAGE_CONTENT_VERSION } from \"@sixb/core/internal/agents\"\nimport {\n type AgentMessageRecord,\n type AgentMessageStore,\n AgentStorageError,\n type AppendAgentMessageInput,\n type ListAgentMessagesInput,\n type ListAgentMessagesResult,\n} from \"@sixb/core/storage\"\nimport type { SqliteValue } from \"../run-list-query\"\nimport { isUniqueConstraintError } from \"../storage-errors\"\nimport { type AgentMessageRow, queryAgentList, rowToMessageRecord } from \"./rows\"\n\nexport class SqliteAgentMessageStore implements AgentMessageStore {\n constructor(private readonly db: Database) {}\n\n async append(input: AppendAgentMessageInput): Promise<AgentMessageRecord> {\n const createdAt = input.createdAt ?? new Date()\n\n return this.db.transaction(() => {\n const thread = this.db\n .query(\"SELECT 1 AS present FROM agent_threads WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.threadId) as { present: number } | null\n\n if (!thread) {\n throw new AgentStorageError(\n \"thread_not_found\",\n `[SixbSqlite] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (input.runId !== null) {\n const run = this.db\n .query(\"SELECT 1 AS present FROM agent_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.runId) as { present: number } | null\n\n if (!run) {\n throw new AgentStorageError(\n \"run_not_found\",\n `[SixbSqlite] Agent run '${input.runId}' not found for project '${input.projectId}'.`\n )\n }\n }\n\n const seqRow = this.db\n .query(\n \"SELECT COALESCE(MAX(seq), 0) + 1 AS next FROM agent_messages WHERE project_id = ? AND thread_id = ?\"\n )\n .get(input.projectId, input.threadId) as { next: number }\n\n try {\n this.db\n .query(\n `\n INSERT INTO agent_messages (\n project_id,\n id,\n thread_id,\n run_id,\n role,\n author_principal_type,\n author_principal_id,\n seq,\n parts,\n metadata,\n content_version,\n created_at,\n completed_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.threadId,\n input.runId,\n input.role,\n input.authorPrincipal?.type ?? null,\n input.authorPrincipal?.id ?? null,\n seqRow.next,\n JSON.stringify(input.parts),\n input.metadata === undefined ? null : JSON.stringify(input.metadata),\n AGENT_MESSAGE_CONTENT_VERSION,\n createdAt.toISOString(),\n input.completedAt ? input.completedAt.toISOString() : null\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbSqlite] Agent message '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n this.db\n .query(\n `\n UPDATE agent_threads\n SET message_count = message_count + 1, last_message_at = ?, updated_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(createdAt.toISOString(), createdAt.toISOString(), input.projectId, input.threadId)\n\n return this.requireMessage(input.projectId, input.id)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentMessageRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM agent_messages WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as AgentMessageRow | null\n\n return row ? rowToMessageRecord(row) : null\n }\n\n async list(input: ListAgentMessagesInput): Promise<ListAgentMessagesResult> {\n if (input.roles !== undefined && input.roles.length === 0) {\n return { messages: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\", \"thread_id = ?\"]\n const args: SqliteValue[] = [input.projectId, input.threadId]\n\n if (input.roles) {\n whereClauses.push(`role IN (${input.roles.map(() => \"?\").join(\", \")})`)\n args.push(...input.roles)\n }\n\n const dir = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const { rows, total, hasMore } = queryAgentList<AgentMessageRow>({\n db: this.db,\n table: \"agent_messages\",\n whereClauses,\n args,\n orderBy: `seq ${dir}`,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { messages: rows.map(rowToMessageRecord), hasMore, total }\n }\n\n private requireMessage(projectId: string, id: string): AgentMessageRecord {\n const row = this.db\n .query(\"SELECT * FROM agent_messages WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as AgentMessageRow | null\n\n if (!row) {\n throw new AgentStorageError(\n \"invalid_state\",\n `[SixbSqlite] Failed to load agent message '${id}' for project '${projectId}'.`\n )\n }\n\n return rowToMessageRecord(row)\n }\n}\n",
|
|
10
|
+
"export function isUniqueConstraintError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(\"UNIQUE constraint failed\")\n}\n",
|
|
11
|
+
"import type { Database } from \"bun:sqlite\"\nimport { type AgentMessagePart, type Principal, SYSTEM_PRINCIPAL } from \"@sixb/core\"\nimport {\n type AgentMessageRecord,\n type AgentRunDiagnostic,\n type AgentRunRecord,\n type AgentRunUsage,\n type AgentThreadRecord,\n coerceAgentRunFinishReason,\n} from \"@sixb/core/storage\"\nimport type { SqliteValue } from \"../run-list-query\"\n\n// ── row shapes (snake_case, as stored) ──────────────────────────────────────────────────────────\n\nexport interface AgentThreadRow {\n project_id: string\n id: string\n agent_id: string\n owner_principal_type: Principal[\"type\"]\n owner_principal_id: string\n title: string | null\n status: AgentThreadRecord[\"status\"]\n active_run_id: string | null\n last_message_at: string | null\n message_count: number\n created_at: string\n updated_at: string\n}\n\nexport interface AgentRunRow {\n project_id: string\n id: string\n thread_id: string\n agent_id: string\n trigger_message_id: string\n requested_by_principal_type: Principal[\"type\"] | null\n requested_by_principal_id: string | null\n execution_principal_type: \"serviceAccount\" | null\n execution_principal_id: string | null\n status: AgentRunRecord[\"status\"]\n model_id: string | null\n finish_reason: string | null\n usage_input_tokens: number | null\n usage_output_tokens: number | null\n usage_total_tokens: number | null\n usage_reasoning_tokens: number | null\n usage_cached_input_tokens: number | null\n error: string | null\n diagnostics: string | null\n attempt: number\n execution_token: string | null\n execution_queue_lease_expires_at: string | null\n created_at: string\n started_at: string | null\n completed_at: string | null\n}\n\nexport interface AgentMessageRow {\n project_id: string\n id: string\n thread_id: string\n run_id: string | null\n role: AgentMessageRecord[\"role\"]\n author_principal_type: Principal[\"type\"] | null\n author_principal_id: string | null\n seq: number\n parts: string\n metadata: string | null\n content_version: number\n created_at: string\n completed_at: string | null\n}\n\n// ── row → record mappers ────────────────────────────────────────────────────────────────────────\n\nexport function rowToThreadRecord(row: AgentThreadRow): AgentThreadRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n agentId: row.agent_id,\n ownerPrincipal: { type: row.owner_principal_type, id: row.owner_principal_id },\n title: row.title ?? undefined,\n status: row.status,\n activeRunId: row.active_run_id,\n lastMessageAt: row.last_message_at ? new Date(row.last_message_at) : undefined,\n messageCount: row.message_count,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n }\n}\n\nexport function rowToRunRecord(row: AgentRunRow): AgentRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n threadId: row.thread_id,\n agentId: row.agent_id,\n triggerMessageId: row.trigger_message_id,\n requestedByPrincipal:\n principalFromColumns(row.requested_by_principal_type, row.requested_by_principal_id) ??\n SYSTEM_PRINCIPAL,\n executionPrincipal: serviceAccountPrincipalFromColumns(\n row.execution_principal_type,\n row.execution_principal_id\n ),\n status: row.status,\n modelId: row.model_id ?? undefined,\n finishReason: coerceAgentRunFinishReason(row.finish_reason),\n usage: rowToUsage(row),\n error: row.error ?? undefined,\n diagnostics:\n row.diagnostics === null ? undefined : (JSON.parse(row.diagnostics) as AgentRunDiagnostic[]),\n attempt: row.attempt,\n execution:\n row.execution_token && row.execution_queue_lease_expires_at\n ? {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n }\n : undefined,\n createdAt: new Date(row.created_at),\n startedAt: row.started_at ? new Date(row.started_at) : undefined,\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n }\n}\n\nexport function rowToMessageRecord(row: AgentMessageRow): AgentMessageRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n threadId: row.thread_id,\n runId: row.run_id,\n role: row.role,\n authorPrincipal: principalFromColumns(row.author_principal_type, row.author_principal_id),\n seq: row.seq,\n parts: JSON.parse(row.parts) as AgentMessagePart[],\n // A null/absent column and an explicit JSON `null` both mean \"no metadata\" (jsonb cannot tell\n // SQL NULL from a json null on read, so both backends normalise to `undefined` for parity).\n metadata: row.metadata === null ? undefined : (JSON.parse(row.metadata) ?? undefined),\n contentVersion: row.content_version,\n createdAt: new Date(row.created_at),\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n }\n}\n\nfunction principalFromColumns(\n type: Principal[\"type\"] | null | undefined,\n id: string | null | undefined\n): Principal | undefined {\n return type && id ? { type, id } : undefined\n}\n\nfunction serviceAccountPrincipalFromColumns(\n type: \"serviceAccount\" | null | undefined,\n id: string | null | undefined\n): Extract<Principal, { readonly type: \"serviceAccount\" }> | undefined {\n return type === \"serviceAccount\" && id ? { type, id } : undefined\n}\n\nfunction rowToUsage(row: AgentRunRow): AgentRunUsage | undefined {\n const usage: AgentRunUsage = {\n ...(row.usage_input_tokens === null ? {} : { inputTokens: row.usage_input_tokens }),\n ...(row.usage_output_tokens === null ? {} : { outputTokens: row.usage_output_tokens }),\n ...(row.usage_total_tokens === null ? {} : { totalTokens: row.usage_total_tokens }),\n ...(row.usage_reasoning_tokens === null ? {} : { reasoningTokens: row.usage_reasoning_tokens }),\n ...(row.usage_cached_input_tokens === null\n ? {}\n : { cachedInputTokens: row.usage_cached_input_tokens }),\n }\n return Object.keys(usage).length === 0 ? undefined : usage\n}\n\n// ── offset pagination (threads / messages order by their own column, not started_at) ─────────────\n\nexport function queryAgentList<TRow>(input: {\n readonly db: Database\n readonly table: \"agent_threads\" | \"agent_messages\"\n readonly whereClauses: readonly string[]\n readonly args: readonly SqliteValue[]\n readonly orderBy: string\n readonly limit?: number\n readonly offset?: number\n}): { readonly rows: readonly TRow[]; readonly total: number; readonly hasMore: boolean } {\n const where = `WHERE ${input.whereClauses.join(\" AND \")}`\n const offset = input.offset ?? 0\n\n const totalRow = input.db\n .query(`SELECT COUNT(*) AS count FROM ${input.table} ${where}`)\n .get(...input.args) as { count: number }\n\n let query = `SELECT * FROM ${input.table} ${where} ORDER BY ${input.orderBy}`\n const queryArgs = [...input.args]\n\n if (input.limit !== undefined) {\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(input.limit, offset)\n } else if (offset > 0) {\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = input.db.query(query).all(...queryArgs) as TRow[]\n const total = totalRow.count\n return { rows, total, hasMore: offset + rows.length < total }\n}\n",
|
|
12
|
+
"import type { Database } from \"bun:sqlite\"\nimport {\n type AgentRunRecord,\n type AgentRunStore,\n AgentStorageError,\n type ConfirmAgentRunExecutionOwnershipInput,\n type CreateAgentRunInput,\n type FinishAgentRunInput,\n type FinishQueuedAgentRunInput,\n type ListAgentRunsInput,\n type ListAgentRunsResult,\n type ReclaimAgentRunInput,\n type StartAgentRunInput,\n} from \"@sixb/core/storage\"\nimport {\n appendRunListFilters,\n hasEmptyStatuses,\n queryRunList,\n type SqliteValue,\n} from \"../run-list-query\"\nimport { isUniqueConstraintError } from \"../storage-errors\"\nimport { type AgentRunRow, rowToRunRecord } from \"./rows\"\n\nconst SQLITE_RUN_ID_BATCH_SIZE = 500\n\nexport class SqliteAgentRunStore implements AgentRunStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAgentRunInput): Promise<AgentRunRecord> {\n const createdAt = input.createdAt ?? new Date()\n\n return this.db.transaction(() => {\n const thread = this.db\n .query(\"SELECT active_run_id FROM agent_threads WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.threadId) as { active_run_id: string | null } | null\n\n if (!thread) {\n throw new AgentStorageError(\n \"thread_not_found\",\n `[SixbSqlite] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (thread.active_run_id !== null) {\n throw new AgentStorageError(\n \"active_run_exists\",\n `[SixbSqlite] Agent thread '${input.threadId}' already has an active run '${thread.active_run_id}'.`\n )\n }\n\n try {\n this.db\n .query(\n `\n INSERT INTO agent_runs (\n project_id,\n id,\n thread_id,\n agent_id,\n trigger_message_id,\n requested_by_principal_type,\n requested_by_principal_id,\n status,\n attempt,\n created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, 'queued', 0, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.threadId,\n input.agentId,\n input.triggerMessageId,\n input.requestedByPrincipal.type,\n input.requestedByPrincipal.id,\n createdAt.toISOString()\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbSqlite] Agent run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n this.db\n .query(\n \"UPDATE agent_threads SET active_run_id = ?, updated_at = ? WHERE project_id = ? AND id = ?\"\n )\n .run(input.id, createdAt.toISOString(), input.projectId, input.threadId)\n\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async start(input: StartAgentRunInput): Promise<AgentRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n return this.db.transaction(() => {\n this.requireStatus(input.projectId, input.id, \"queued\")\n this.db\n .query(\n `\n UPDATE agent_runs\n SET\n status = 'running',\n execution_principal_type = ?,\n execution_principal_id = ?,\n model_id = ?,\n attempt = 1,\n execution_token = ?,\n execution_queue_lease_expires_at = ?,\n started_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.executionPrincipal?.type ?? null,\n input.executionPrincipal?.id ?? null,\n input.modelId ?? null,\n input.execution.token,\n input.execution.queueLeaseExpiresAt.toISOString(),\n startedAt.toISOString(),\n input.projectId,\n input.id\n )\n\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async finishQueued(input: FinishQueuedAgentRunInput): Promise<AgentRunRecord> {\n const completedAt = input.completedAt ?? new Date()\n return this.db.transaction(() => {\n const run = this.requireStatus(input.projectId, input.id, \"queued\")\n this.db\n .query(\n `\n UPDATE agent_runs\n SET status = ?, error = ?, completed_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n input.error ?? null,\n completedAt.toISOString(),\n input.projectId,\n input.id\n )\n this.releaseThread(run, completedAt)\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async reclaim(input: ReclaimAgentRunInput): Promise<AgentRunRecord> {\n return this.db.transaction(() => {\n this.requireRunning(input.projectId, input.id)\n this.db\n .query(\n `\n UPDATE agent_runs\n SET\n attempt = attempt + 1,\n execution_token = ?,\n execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.execution.token,\n input.execution.queueLeaseExpiresAt.toISOString(),\n input.projectId,\n input.id\n )\n\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async confirmExecutionOwnership(\n input: ConfirmAgentRunExecutionOwnershipInput\n ): Promise<AgentRunRecord> {\n return this.db.transaction(() => {\n const run = this.requireRunning(input.projectId, input.id)\n if (run.execution_token !== input.executionToken) {\n throw new AgentStorageError(\n \"execution_lost\",\n `[SixbSqlite] Execution token is no longer current on agent run '${input.id}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE agent_runs\n SET execution_queue_lease_expires_at = MAX(execution_queue_lease_expires_at, ?)\n WHERE project_id = ? AND id = ?\n `\n )\n .run(input.queueLeaseExpiresAt.toISOString(), input.projectId, input.id)\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async finish(input: FinishAgentRunInput): Promise<AgentRunRecord> {\n const completedAt = input.completedAt ?? new Date()\n const errorValue = input.status === \"succeeded\" ? null : (input.error ?? null)\n\n return this.db.transaction(() => {\n const run = this.requireRunning(input.projectId, input.id)\n\n if (run.execution_token !== input.executionToken) {\n throw new AgentStorageError(\n \"execution_lost\",\n `[SixbSqlite] Execution token is no longer current on agent run '${input.id}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE agent_runs\n SET\n status = ?,\n model_id = COALESCE(?, model_id),\n finish_reason = ?,\n usage_input_tokens = ?,\n usage_output_tokens = ?,\n usage_total_tokens = ?,\n usage_reasoning_tokens = ?,\n usage_cached_input_tokens = ?,\n error = ?,\n diagnostics = ?,\n execution_token = NULL,\n execution_queue_lease_expires_at = NULL,\n completed_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n input.modelId ?? null,\n input.finishReason ?? null,\n input.usage?.inputTokens ?? null,\n input.usage?.outputTokens ?? null,\n input.usage?.totalTokens ?? null,\n input.usage?.reasoningTokens ?? null,\n input.usage?.cachedInputTokens ?? null,\n errorValue,\n input.diagnostics === undefined ? null : JSON.stringify(input.diagnostics),\n completedAt.toISOString(),\n input.projectId,\n input.id\n )\n\n this.releaseThread(run, completedAt)\n\n return this.requireRun(input.projectId, input.id)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM agent_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as AgentRunRow | null\n\n return row ? rowToRunRecord(row) : null\n }\n\n async getByIds(params: {\n projectId: string\n ids: readonly string[]\n }): Promise<readonly AgentRunRecord[]> {\n const ids = [...new Set(params.ids)]\n if (ids.length === 0) {\n return []\n }\n\n const rows: AgentRunRow[] = []\n for (let offset = 0; offset < ids.length; offset += SQLITE_RUN_ID_BATCH_SIZE) {\n const batch = ids.slice(offset, offset + SQLITE_RUN_ID_BATCH_SIZE)\n const placeholders = batch.map(() => \"?\").join(\", \")\n rows.push(\n ...(this.db\n .query(`SELECT * FROM agent_runs WHERE project_id = ? AND id IN (${placeholders})`)\n .all(params.projectId, ...batch) as AgentRunRow[])\n )\n }\n const byId = new Map(rows.map((row) => [row.id, rowToRunRecord(row)]))\n return ids.flatMap((id) => {\n const run = byId.get(id)\n return run ? [run] : []\n })\n }\n\n async list(input: ListAgentRunsInput): Promise<ListAgentRunsResult> {\n if (hasEmptyStatuses(input)) {\n return { runs: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.threadId) {\n whereClauses.push(\"thread_id = ?\")\n args.push(input.threadId)\n }\n\n if (input.agentId) {\n whereClauses.push(\"agent_id = ?\")\n args.push(input.agentId)\n }\n\n appendRunListFilters(whereClauses, args, input, \"COALESCE(started_at, created_at)\")\n\n const { rows, total, hasMore } = queryRunList<AgentRunRow>({\n db: this.db,\n tableName: \"agent_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { runs: rows.map(rowToRunRecord), hasMore, total }\n }\n\n private requireRunning(projectId: string, id: string): AgentRunRow {\n return this.requireStatus(projectId, id, \"running\")\n }\n\n private requireStatus(\n projectId: string,\n id: string,\n status: AgentRunRecord[\"status\"]\n ): AgentRunRow {\n const row = this.db\n .query(\"SELECT * FROM agent_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as AgentRunRow | null\n\n if (!row) {\n throw new AgentStorageError(\n \"run_not_found\",\n `[SixbSqlite] Agent run '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.status !== status) {\n throw new AgentStorageError(\n \"invalid_state\",\n `[SixbSqlite] Agent run '${id}' is not ${status} (status '${row.status}').`\n )\n }\n\n return row\n }\n\n private releaseThread(run: AgentRunRow, completedAt: Date): void {\n this.db\n .query(\n `\n UPDATE agent_threads\n SET active_run_id = NULL, updated_at = ?\n WHERE project_id = ? AND id = ? AND active_run_id = ?\n `\n )\n .run(completedAt.toISOString(), run.project_id, run.thread_id, run.id)\n }\n\n private requireRun(projectId: string, id: string): AgentRunRecord {\n const row = this.db\n .query(\"SELECT * FROM agent_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as AgentRunRow | null\n\n if (!row) {\n throw new AgentStorageError(\n \"run_not_found\",\n `[SixbSqlite] Agent run '${id}' not found for project '${projectId}'.`\n )\n }\n\n return rowToRunRecord(row)\n }\n}\n",
|
|
13
|
+
"import type { Database } from \"bun:sqlite\"\n\nexport type SqliteValue = string | number | null\n\ntype SqliteRunListTable =\n | \"agent_runs\"\n | \"pipeline_runs\"\n | \"pipeline_step_runs\"\n | \"sync_runs\"\n | \"webhook_runs\"\n | \"workflow_runs\"\n | \"workflow_node_runs\"\n | \"workflow_agent_node_runs\"\n\nexport function hasEmptyStatuses(input: { readonly statuses?: readonly unknown[] }): boolean {\n return input.statuses !== undefined && input.statuses.length === 0\n}\n\ntype StartedAtExpression = \"started_at\" | \"COALESCE(started_at, created_at)\"\n\nexport function appendRunListFilters(\n whereClauses: string[],\n args: SqliteValue[],\n input: {\n readonly statuses?: readonly string[]\n readonly startedAfter?: Date\n readonly startedBefore?: Date\n },\n startedAtExpression: StartedAtExpression = \"started_at\"\n): void {\n if (input.statuses) {\n if (input.statuses.length === 0) {\n whereClauses.push(\"1 = 0\")\n } else {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n }\n\n if (input.startedAfter) {\n whereClauses.push(`${startedAtExpression} >= ?`)\n args.push(input.startedAfter.toISOString())\n }\n\n if (input.startedBefore) {\n whereClauses.push(`${startedAtExpression} <= ?`)\n args.push(input.startedBefore.toISOString())\n }\n}\n\nexport function queryRunList<TRow>(input: {\n readonly db: Database\n readonly tableName: SqliteRunListTable\n readonly whereClauses: readonly string[]\n readonly args: readonly SqliteValue[]\n readonly order?: \"asc\" | \"desc\"\n readonly limit?: number\n readonly offset?: number\n}): { readonly rows: readonly TRow[]; readonly total: number; readonly hasMore: boolean } {\n const where = `WHERE ${input.whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n\n const totalRow = input.db\n .query(`SELECT COUNT(*) AS count FROM ${input.tableName} ${where}`)\n .get(...input.args) as { count: number }\n\n const orderColumn =\n input.tableName === \"agent_runs\"\n ? \"COALESCE(started_at, created_at)\"\n : input.tableName === \"workflow_agent_node_runs\"\n ? \"created_at\"\n : \"started_at\"\n const idColumn = input.tableName === \"workflow_agent_node_runs\" ? \"node_run_id\" : \"id\"\n let query = `\n SELECT * FROM ${input.tableName}\n ${where}\n ORDER BY ${orderColumn} ${order}, ${idColumn} ${order}\n `\n const queryArgs = [...input.args]\n\n if (input.limit !== undefined) {\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(input.limit, offset)\n } else if (offset > 0) {\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = input.db.query(query).all(...queryArgs) as TRow[]\n const total = totalRow.count\n\n return {\n rows,\n total,\n hasMore: offset + rows.length < total,\n }\n}\n",
|
|
14
|
+
"import type { Database } from \"bun:sqlite\"\nimport {\n AgentStorageError,\n type AgentThreadRecord,\n type AgentThreadStore,\n type CreateAgentThreadInput,\n type ListAgentThreadsInput,\n type ListAgentThreadsResult,\n} from \"@sixb/core/storage\"\nimport type { SqliteValue } from \"../run-list-query\"\nimport { isUniqueConstraintError } from \"../storage-errors\"\nimport { type AgentThreadRow, queryAgentList, rowToThreadRecord } from \"./rows\"\n\nexport class SqliteAgentThreadStore implements AgentThreadStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAgentThreadInput): Promise<AgentThreadRecord> {\n const createdAt = input.createdAt ?? new Date()\n const updatedAt = input.updatedAt ?? createdAt\n\n try {\n this.db\n .query(\n `\n INSERT INTO agent_threads (\n project_id,\n id,\n agent_id,\n owner_principal_type,\n owner_principal_id,\n title,\n status,\n active_run_id,\n last_message_at,\n message_count,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL, NULL, 0, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.agentId,\n input.ownerPrincipal.type,\n input.ownerPrincipal.id,\n input.title ?? null,\n input.status ?? \"active\",\n createdAt.toISOString(),\n updatedAt.toISOString()\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new AgentStorageError(\n \"duplicate_id\",\n `[SixbSqlite] Agent thread '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n return this.requireThread(input.projectId, input.id)\n }\n\n async getById(params: { projectId: string; id: string }): Promise<AgentThreadRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM agent_threads WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as AgentThreadRow | null\n\n return row ? rowToThreadRecord(row) : null\n }\n\n async list(input: ListAgentThreadsInput): Promise<ListAgentThreadsResult> {\n if (\n (input.statuses !== undefined && input.statuses.length === 0) ||\n (input.agentIds !== undefined && input.agentIds.length === 0)\n ) {\n return { threads: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.agentId) {\n whereClauses.push(\"agent_id = ?\")\n args.push(input.agentId)\n }\n\n if (input.agentIds) {\n whereClauses.push(`agent_id IN (${input.agentIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.agentIds)\n }\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n if (input.ownerPrincipal) {\n whereClauses.push(\"owner_principal_type = ? AND owner_principal_id = ?\")\n args.push(input.ownerPrincipal.type, input.ownerPrincipal.id)\n }\n\n const dir = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const { rows, total, hasMore } = queryAgentList<AgentThreadRow>({\n db: this.db,\n table: \"agent_threads\",\n whereClauses,\n args,\n orderBy: `COALESCE(last_message_at, created_at) ${dir}, id ${dir}`,\n limit: input.limit,\n offset: input.offset,\n })\n\n return { threads: rows.map(rowToThreadRecord), hasMore, total }\n }\n\n private requireThread(projectId: string, id: string): AgentThreadRecord {\n const row = this.db\n .query(\"SELECT * FROM agent_threads WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as AgentThreadRow | null\n\n if (!row) {\n throw new AgentStorageError(\n \"invalid_state\",\n `[SixbSqlite] Failed to load agent thread '${id}' for project '${projectId}'.`\n )\n }\n\n return rowToThreadRecord(row)\n }\n}\n",
|
|
15
|
+
"import type { AgentStorage } from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"../migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"../transactions\"\nimport { SqliteAgentMessageStore } from \"./messages\"\nimport { SqliteAgentRunStore } from \"./runs\"\nimport { SqliteAgentThreadStore } from \"./threads\"\n\nexport interface SqliteAgentStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\n/**\n * SQLite-backed agent persistence: thread / run / message sub-stores sharing one connection. The\n * cross-table writes (reserve + finish touch the thread anchor, append bumps thread stats) run in\n * SQLite transactions; the bundled {@link SqliteStorage} serializes all of them on one connection.\n */\nexport class SqliteAgentStorage implements AgentStorage {\n readonly threads: SqliteAgentThreadStore\n readonly runs: SqliteAgentRunStore\n readonly messages: SqliteAgentMessageStore\n\n private readonly connection: SqliteStoreConnection\n\n constructor(options: SqliteAgentStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.connection.db)\n }\n\n this.threads = new SqliteAgentThreadStore(this.connection.db)\n this.runs = new SqliteAgentRunStore(this.connection.db)\n this.messages = new SqliteAgentMessageStore(this.connection.db)\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n",
|
|
16
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthStorage,\n CompleteMagicLinkSignInInput,\n CompleteOidcSignInInput,\n CompleteSignInResult,\n GroupMembershipRecord,\n InvitationRecord,\n SessionRecord,\n SuspendUserAndRevokeSessionsInput,\n UserIdentityRecord,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"../migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n runImmediateTransaction,\n type SqliteStoreConnection,\n} from \"../transactions\"\nimport { SqliteAuthAccessTokenStore } from \"./access-tokens\"\nimport { SqliteAuthGroupMembershipStore } from \"./group-memberships\"\nimport { SqliteAuthUserIdentityStore } from \"./identities\"\nimport { SqliteAuthInvitationStore } from \"./invitations\"\nimport { SqliteAuthMagicLinkStore } from \"./magic-links\"\nimport { SqliteAuthOidcAuthorizationAttemptStore } from \"./oidc-attempts\"\nimport type { SqliteAuthMagicLinkRow, SqliteAuthOidcAttemptRow } from \"./rows\"\nimport { rowToIdentityRecord, rowToUserRecord, serializeOptionalRecord } from \"./rows\"\nimport { SqliteAuthServiceAccountGroupMembershipStore } from \"./service-account-group-memberships\"\nimport { SqliteAuthServiceAccountStore } from \"./service-accounts\"\nimport { SqliteAuthSessionStore } from \"./sessions\"\nimport {\n assertNonEmpty,\n consumeMagicLink,\n consumeOidcAttempt,\n createSession,\n getActiveInvitationByEmail,\n getIdentityRowBySubject,\n getMagicLinkRowById,\n getOidcAttemptRowById,\n getUserRowByEmail,\n getUserRowById,\n mapUniqueConstraintError,\n normalizeEmail,\n normalizeGroupIds,\n revokeActiveSessionsForUser,\n toIso,\n upsertGroupMembership,\n validateCompleteSessionInput,\n} from \"./shared\"\nimport { SqliteAuthUserStore } from \"./users\"\n\ninterface AuthTransactionError {\n readonly error: AuthStorageError\n}\n\nexport interface SqliteAuthStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteAuthStorage implements AuthStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n readonly users: SqliteAuthUserStore\n readonly identities: SqliteAuthUserIdentityStore\n readonly serviceAccounts: SqliteAuthServiceAccountStore\n readonly serviceAccountGroupMemberships: SqliteAuthServiceAccountGroupMembershipStore\n readonly sessions: SqliteAuthSessionStore\n readonly accessTokens: SqliteAuthAccessTokenStore\n readonly invitations: SqliteAuthInvitationStore\n readonly groupMemberships: SqliteAuthGroupMembershipStore\n readonly magicLinks: SqliteAuthMagicLinkStore\n readonly oidcAuthorizationAttempts: SqliteAuthOidcAuthorizationAttemptStore\n\n constructor(options: SqliteAuthStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n\n this.users = new SqliteAuthUserStore(this.db)\n this.identities = new SqliteAuthUserIdentityStore(this.db)\n this.serviceAccounts = new SqliteAuthServiceAccountStore(this.db)\n this.serviceAccountGroupMemberships = new SqliteAuthServiceAccountGroupMembershipStore(this.db)\n this.sessions = new SqliteAuthSessionStore(this.db)\n this.accessTokens = new SqliteAuthAccessTokenStore(this.db)\n this.invitations = new SqliteAuthInvitationStore(this.db)\n this.groupMemberships = new SqliteAuthGroupMembershipStore(this.db)\n this.magicLinks = new SqliteAuthMagicLinkStore(this.db)\n this.oidcAuthorizationAttempts = new SqliteAuthOidcAuthorizationAttemptStore(this.db)\n }\n\n async completeMagicLinkSignIn(\n input: CompleteMagicLinkSignInInput\n ): Promise<CompleteSignInResult> {\n const result = runImmediateTransaction(\n this.db,\n (): CompleteSignInResult | AuthTransactionError => {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const completedAt = new Date(input.completedAt)\n const magicLink = getMagicLinkRowById(this.db, {\n projectId,\n id: input.magicLinkId,\n })\n\n this.assertMagicLinkUsable(\n projectId,\n input.magicLinkId,\n input.tokenHash,\n completedAt,\n magicLink\n )\n\n const existingUserRow = getUserRowByEmail(this.db, {\n projectId,\n email: magicLink.email,\n })\n const activeInvitation = getActiveInvitationByEmail(this.db, {\n projectId,\n email: magicLink.email,\n now: completedAt,\n })\n const shouldCreateUser = !existingUserRow\n const manualGroupIds = normalizeGroupIds(input.manualGroupIds)\n\n if (existingUserRow?.status === \"suspended\") {\n consumeMagicLink(this.db, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"suspended_user\",\n `[Sixb] User '${existingUserRow.id}' is suspended for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {\n consumeMagicLink(this.db, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (\n shouldCreateUser &&\n !activeInvitation &&\n input.allowUserCreationWithoutInvitation &&\n input.requireNoActiveUsersForUserCreation &&\n hasActiveUsers(this.db, projectId)\n ) {\n consumeMagicLink(this.db, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] Magic link '${input.magicLinkId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n validateCompleteSessionInput(this.db, projectId, input.session)\n assertSignInSessionAudience(projectId, input.session.audience, magicLink.audience)\n\n let newUserId: string | undefined\n if (shouldCreateUser) {\n newUserId = assertNonEmpty(input.newUserId, \"User id\")\n if (getUserRowById(this.db, { projectId, id: newUserId })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${newUserId}' already exists for project '${projectId}'.`\n )\n }\n }\n\n consumeMagicLink(this.db, {\n projectId,\n id: input.magicLinkId,\n tokenHash: input.tokenHash,\n consumedAt: completedAt,\n })\n\n const user = existingUserRow\n ? rowToUserRecord(existingUserRow)\n : this.insertUser({\n id: newUserId ?? assertNonEmpty(input.newUserId, \"User id\"),\n projectId,\n email: magicLink.email,\n displayName: input.newUserDisplayName,\n avatarUrl: input.newUserAvatarUrl,\n createdAt: completedAt,\n })\n\n const invitation = this.acceptInvitationAndApplyGroups({\n activeInvitation,\n completedAt,\n projectId,\n user,\n })\n const groupMemberships = this.applyManualGroups({\n completedAt,\n existing: invitation.groupMemberships,\n groupIds: manualGroupIds,\n projectId,\n userId: user.id,\n })\n const session = this.createSignInSession({\n projectId,\n strategyId: magicLink.strategy_id,\n session: input.session,\n userId: user.id,\n })\n\n return {\n user,\n session,\n invitation: invitation.invitation,\n groupMemberships,\n }\n }\n )\n\n if (\"error\" in result) {\n throw result.error\n }\n\n return result\n }\n\n async completeOidcSignIn(input: CompleteOidcSignInInput): Promise<CompleteSignInResult> {\n const result = runImmediateTransaction(\n this.db,\n (): CompleteSignInResult | AuthTransactionError => {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const completedAt = new Date(input.completedAt)\n const attempt = getOidcAttemptRowById(this.db, {\n projectId,\n id: input.oidcAuthorizationAttemptId,\n })\n\n this.assertOidcAttemptUsable(\n projectId,\n input.oidcAuthorizationAttemptId,\n input.stateHash,\n completedAt,\n attempt\n )\n\n const subject = assertNonEmpty(input.subject, \"Subject\")\n const email = normalizeEmail(input.email)\n const identity = getIdentityRowBySubject(this.db, {\n projectId,\n strategyId: attempt.strategy_id,\n subject,\n })\n const activeInvitation = identity\n ? null\n : getActiveInvitationByEmail(this.db, {\n projectId,\n email,\n now: completedAt,\n })\n let userRow = identity\n ? getUserRowById(this.db, { projectId, id: identity.user_id })\n : getUserRowByEmail(this.db, { projectId, email })\n const shouldCreateUser = !identity && !userRow\n const manualGroupIds = normalizeGroupIds(input.manualGroupIds)\n\n if (identity && !userRow) {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${identity.user_id}' not found for linked OIDC identity.`\n ),\n }\n }\n\n if (!identity && userRow && (!input.autoLinkByVerifiedEmail || !input.emailVerified)) {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"email_link_not_allowed\",\n `[Sixb] OIDC identity cannot auto-link to user '${userRow.id}' for project '${projectId}'.`\n ),\n }\n }\n\n if (userRow?.status === \"suspended\") {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"suspended_user\",\n `[Sixb] User '${userRow.id}' is suspended for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !input.emailVerified) {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (shouldCreateUser && !activeInvitation && !input.allowUserCreationWithoutInvitation) {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n if (\n shouldCreateUser &&\n !activeInvitation &&\n input.allowUserCreationWithoutInvitation &&\n input.requireNoActiveUsersForUserCreation &&\n hasActiveUsers(this.db, projectId)\n ) {\n this.consumeOidcAttempt(input, completedAt, projectId)\n return {\n error: new AuthStorageError(\n \"user_creation_not_allowed\",\n `[Sixb] OIDC authorization attempt '${input.oidcAuthorizationAttemptId}' cannot create a user for project '${projectId}'.`\n ),\n }\n }\n\n validateCompleteSessionInput(this.db, projectId, input.session)\n assertSignInSessionAudience(projectId, input.session.audience, attempt.audience)\n\n let newUserId: string | undefined\n if (shouldCreateUser) {\n newUserId = assertNonEmpty(input.newUserId, \"User id\")\n if (getUserRowById(this.db, { projectId, id: newUserId })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${newUserId}' already exists for project '${projectId}'.`\n )\n }\n }\n\n this.consumeOidcAttempt(input, completedAt, projectId)\n\n if (!userRow) {\n const user = this.insertUser({\n id: newUserId ?? assertNonEmpty(input.newUserId, \"User id\"),\n projectId,\n email,\n displayName: input.displayName,\n avatarUrl: input.avatarUrl,\n createdAt: completedAt,\n })\n userRow = {\n project_id: user.projectId,\n id: user.id,\n email: user.email,\n display_name: user.displayName ?? null,\n avatar_url: user.avatarUrl ?? null,\n status: user.status,\n created_at: toIso(user.createdAt),\n updated_at: toIso(user.updatedAt),\n }\n }\n\n const user = rowToUserRecord(userRow)\n const invitation = this.acceptInvitationAndApplyGroups({\n activeInvitation,\n completedAt,\n projectId,\n user,\n })\n const groupMemberships = this.applyManualGroups({\n completedAt,\n existing: invitation.groupMemberships,\n groupIds: manualGroupIds,\n projectId,\n userId: user.id,\n })\n const nextIdentity = this.upsertIdentity({\n projectId,\n strategyId: attempt.strategy_id,\n subject,\n userId: user.id,\n claims: input.claims,\n createdAt: identity ? new Date(identity.created_at) : completedAt,\n updatedAt: completedAt,\n })\n const session = this.createSignInSession({\n projectId,\n strategyId: attempt.strategy_id,\n session: input.session,\n userId: user.id,\n })\n\n return {\n user,\n session,\n identity: nextIdentity,\n invitation: invitation.invitation,\n groupMemberships,\n }\n }\n )\n\n if (\"error\" in result) {\n throw result.error\n }\n\n return result\n }\n\n async suspendUserAndRevokeSessions(\n input: SuspendUserAndRevokeSessionsInput\n ): Promise<UserRecord> {\n return runImmediateTransaction(this.db, () => {\n const existing = getUserRowById(this.db, {\n projectId: input.projectId,\n id: input.userId,\n })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.userId}' not found for project '${input.projectId}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE auth_users\n SET status = 'suspended',\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(input.suspendedAt), input.projectId, input.userId)\n revokeActiveSessionsForUser(this.db, {\n projectId: input.projectId,\n userId: input.userId,\n revokedAt: input.suspendedAt,\n })\n\n return rowToUserRecord({\n ...existing,\n status: \"suspended\",\n updated_at: toIso(input.suspendedAt),\n })\n })\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private assertMagicLinkUsable(\n projectId: string,\n id: string,\n tokenHash: string,\n completedAt: Date,\n row: SqliteAuthMagicLinkRow | null\n ): asserts row is SqliteAuthMagicLinkRow {\n if (!row) {\n throw new AuthStorageError(\n \"missing_magic_link\",\n `[Sixb] Magic link '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.token_hash !== tokenHash || row.consumed_at || row.revoked_at) {\n throw new AuthStorageError(\n \"invalid_magic_link\",\n `[Sixb] Magic link '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= completedAt) {\n throw new AuthStorageError(\n \"expired_magic_link\",\n `[Sixb] Magic link '${id}' is expired for project '${projectId}'.`\n )\n }\n }\n\n private assertOidcAttemptUsable(\n projectId: string,\n id: string,\n stateHash: string,\n completedAt: Date,\n row: SqliteAuthOidcAttemptRow | null\n ): asserts row is SqliteAuthOidcAttemptRow {\n if (!row) {\n throw new AuthStorageError(\n \"missing_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.state_hash !== stateHash || row.consumed_at) {\n throw new AuthStorageError(\n \"invalid_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= completedAt) {\n throw new AuthStorageError(\n \"expired_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is expired for project '${projectId}'.`\n )\n }\n }\n\n private insertUser(input: {\n readonly id: string\n readonly projectId: string\n readonly email: string\n readonly displayName?: string\n readonly avatarUrl?: string\n readonly createdAt: Date\n }): UserRecord {\n try {\n this.db\n .query(\n `\n INSERT INTO auth_users (\n project_id,\n id,\n email,\n display_name,\n avatar_url,\n status,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, 'active', ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.email,\n input.displayName ?? null,\n input.avatarUrl ?? null,\n toIso(input.createdAt),\n toIso(input.createdAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_user\",\n `[Sixb] User '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n return {\n id: input.id,\n projectId: input.projectId,\n email: input.email,\n displayName: input.displayName,\n avatarUrl: input.avatarUrl,\n status: \"active\",\n createdAt: new Date(input.createdAt),\n updatedAt: new Date(input.createdAt),\n }\n }\n\n private acceptInvitationAndApplyGroups(input: {\n readonly activeInvitation: InvitationRecord | null\n readonly completedAt: Date\n readonly projectId: string\n readonly user: UserRecord\n }): {\n readonly invitation?: InvitationRecord\n readonly groupMemberships: readonly GroupMembershipRecord[]\n } {\n if (!input.activeInvitation) {\n return { groupMemberships: [] }\n }\n\n this.db\n .query(\n `\n UPDATE auth_invitations\n SET status = 'accepted',\n accepted_at = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(\n toIso(input.completedAt),\n toIso(input.completedAt),\n input.projectId,\n input.activeInvitation.id\n )\n\n const invitation: InvitationRecord = {\n ...input.activeInvitation,\n status: \"accepted\",\n acceptedAt: new Date(input.completedAt),\n updatedAt: new Date(input.completedAt),\n }\n const groupMemberships = input.activeInvitation.groupIds.map((groupId) =>\n upsertGroupMembership(this.db, {\n projectId: input.projectId,\n userId: input.user.id,\n groupId,\n source: \"invitation\",\n createdAt: input.completedAt,\n })\n )\n\n return { invitation, groupMemberships }\n }\n\n private applyManualGroups(input: {\n readonly completedAt: Date\n readonly existing: readonly GroupMembershipRecord[]\n readonly groupIds: readonly string[]\n readonly projectId: string\n readonly userId: string\n }): readonly GroupMembershipRecord[] {\n const groupMemberships = [...input.existing]\n\n for (const groupId of input.groupIds) {\n groupMemberships.push(\n upsertGroupMembership(this.db, {\n projectId: input.projectId,\n userId: input.userId,\n groupId,\n source: \"manual\",\n createdAt: input.completedAt,\n })\n )\n }\n\n return groupMemberships\n }\n\n private createSignInSession(input: {\n readonly projectId: string\n readonly strategyId: string\n readonly session: CompleteMagicLinkSignInInput[\"session\"]\n readonly userId: string\n }): SessionRecord {\n return createSession(this.db, {\n id: input.session.id,\n projectId: input.projectId,\n userId: input.userId,\n strategyId: input.strategyId,\n audience: input.session.audience,\n tokenHash: input.session.tokenHash,\n createdAt: input.session.createdAt,\n expiresAt: input.session.expiresAt,\n absoluteExpiresAt: input.session.absoluteExpiresAt,\n userAgent: input.session.userAgent,\n ipAddress: input.session.ipAddress,\n })\n }\n\n private consumeOidcAttempt(\n input: CompleteOidcSignInInput,\n completedAt: Date,\n projectId: string\n ): void {\n consumeOidcAttempt(this.db, {\n projectId,\n id: input.oidcAuthorizationAttemptId,\n stateHash: input.stateHash,\n consumedAt: completedAt,\n })\n }\n\n private upsertIdentity(input: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n readonly userId: string\n readonly claims?: Readonly<Record<string, unknown>>\n readonly createdAt: Date\n readonly updatedAt: Date\n }): UserIdentityRecord {\n this.db\n .query(\n `\n INSERT INTO auth_user_identities (\n project_id,\n strategy_id,\n subject,\n user_id,\n claims,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(project_id, strategy_id, subject)\n DO UPDATE SET\n user_id = excluded.user_id,\n claims = excluded.claims,\n updated_at = excluded.updated_at\n `\n )\n .run(\n input.projectId,\n input.strategyId,\n input.subject,\n input.userId,\n serializeOptionalRecord(input.claims),\n toIso(input.createdAt),\n toIso(input.updatedAt)\n )\n\n return rowToIdentityRecord({\n project_id: input.projectId,\n strategy_id: input.strategyId,\n subject: input.subject,\n user_id: input.userId,\n claims: serializeOptionalRecord(input.claims),\n created_at: toIso(input.createdAt),\n updated_at: toIso(input.updatedAt),\n })\n }\n}\n\nfunction hasActiveUsers(db: Database, projectId: string): boolean {\n const row = db\n .query(\n `\n SELECT 1 AS active\n FROM auth_users\n WHERE project_id = ?\n AND status = 'active'\n LIMIT 1\n `\n )\n .get(projectId) as { readonly active: number } | null\n\n return row !== null\n}\n\nfunction assertSignInSessionAudience(\n projectId: string,\n sessionAudience: string,\n storedAudience: string\n): void {\n if (sessionAudience === storedAudience) {\n return\n }\n\n throw new AuthStorageError(\n \"invalid_input\",\n `[Sixb] Sign-in session audience '${sessionAudience}' does not match stored auth audience '${storedAudience}' for project '${projectId}'.`\n )\n}\n",
|
|
17
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AccessTokenRecord,\n AuthAccessTokenStore,\n CreateAuthAccessTokenInput,\n ListAuthAccessTokensInput,\n ListAuthAccessTokensResult,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type {\n SqliteAuthAccessTokenRow,\n SqliteAuthServiceAccountRow,\n SqliteAuthUserRow,\n} from \"./rows\"\nimport { rowToAccessTokenRecord, serializeOptionalStringArray } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n mapUniqueConstraintError,\n normalizeGroupIds,\n type SqliteValue,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthAccessTokenStore implements AuthAccessTokenStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAuthAccessTokenInput): Promise<AccessTokenRecord> {\n const id = assertNonEmpty(input.id, \"Access token id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const name = assertNonEmpty(input.name, \"Access token name\")\n const subjectId = assertNonEmpty(input.subjectId, \"Access token subject id\")\n const tokenHash = assertNonEmpty(input.tokenHash, \"Access token hash\")\n assertKindMatchesSubject(input)\n this.assertSubjectExists(projectId, input.subjectType, subjectId)\n const groupIds = input.groupIds === undefined ? undefined : normalizeGroupIds(input.groupIds)\n\n try {\n this.db\n .query(\n `\n INSERT INTO auth_access_tokens (\n project_id,\n id,\n name,\n kind,\n subject_type,\n subject_id,\n token_hash,\n group_ids,\n created_by_principal_type,\n created_by_principal_id,\n created_by_session_id,\n created_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n name,\n input.kind,\n input.subjectType,\n subjectId,\n tokenHash,\n serializeOptionalStringArray(groupIds),\n input.createdByPrincipal?.type ?? null,\n input.createdByPrincipal?.id ?? null,\n input.createdBySessionId ?? null,\n toIso(input.createdAt),\n toIso(input.expiresAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_access_token\",\n `[Sixb] Access token '${id}' already exists for project '${projectId}'.`\n )\n }\n\n const token = await this.getById({ projectId, id })\n if (!token) {\n throw new AuthStorageError(\n \"missing_access_token\",\n `[Sixb] Access token '${id}' not found for project '${projectId}'.`\n )\n }\n return token\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<AccessTokenRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM auth_access_tokens WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthAccessTokenRow | null\n return row ? rowToAccessTokenRecord(row) : null\n }\n\n async list(input: ListAuthAccessTokensInput): Promise<ListAuthAccessTokensResult> {\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n if (input.kind) {\n whereClauses.push(\"kind = ?\")\n args.push(input.kind)\n }\n if (input.subjectType) {\n whereClauses.push(\"subject_type = ?\")\n args.push(input.subjectType)\n }\n if (input.subjectId) {\n whereClauses.push(\"subject_id = ?\")\n args.push(input.subjectId)\n }\n if (!input.includeRevoked) {\n whereClauses.push(\"revoked_at IS NULL\")\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM auth_access_tokens ${where}`)\n .get(...args) as { readonly count: number }\n const queryArgs = [...args]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_access_tokens\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryArgs,\n input\n )\n const rows = this.db.query(query).all(...queryArgs) as SqliteAuthAccessTokenRow[]\n\n return {\n accessTokens: rows.map(rowToAccessTokenRecord),\n hasMore:\n input.limit === undefined ? false : (input.offset ?? 0) + input.limit < totalRow.count,\n total: totalRow.count,\n }\n }\n\n async findValidByTokenHash(params: {\n readonly projectId: string\n readonly id: string\n readonly kind: AccessTokenRecord[\"kind\"]\n readonly tokenHash: string\n readonly now: Date\n }): Promise<AccessTokenRecord | null> {\n const row = this.db\n .query(\n `\n SELECT *\n FROM auth_access_tokens\n WHERE project_id = ?\n AND id = ?\n AND kind = ?\n AND token_hash = ?\n AND revoked_at IS NULL\n AND expires_at > ?\n `\n )\n .get(\n params.projectId,\n params.id,\n params.kind,\n params.tokenHash,\n toIso(params.now)\n ) as SqliteAuthAccessTokenRow | null\n\n return row ? rowToAccessTokenRecord(row) : null\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<AccessTokenRecord> {\n const existing = await this.getById(params)\n if (!existing) {\n throw new AuthStorageError(\n \"missing_access_token\",\n `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE auth_access_tokens\n SET revoked_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(params.revokedAt), params.projectId, params.id)\n\n return { ...existing, revokedAt: new Date(params.revokedAt) }\n }\n\n async touch(params: {\n readonly projectId: string\n readonly id: string\n readonly lastUsedAt: Date\n readonly userAgent?: string\n readonly ipAddress?: string\n }): Promise<AccessTokenRecord> {\n const existing = await this.getById(params)\n if (!existing) {\n throw new AuthStorageError(\n \"missing_access_token\",\n `[Sixb] Access token '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n\n const lastUsedUserAgent = params.userAgent ?? existing.lastUsedUserAgent\n const lastUsedIpAddress = params.ipAddress ?? existing.lastUsedIpAddress\n\n this.db\n .query(\n `\n UPDATE auth_access_tokens\n SET last_used_at = ?,\n last_used_user_agent = ?,\n last_used_ip_address = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(\n toIso(params.lastUsedAt),\n lastUsedUserAgent ?? null,\n lastUsedIpAddress ?? null,\n params.projectId,\n params.id\n )\n\n return {\n ...existing,\n lastUsedAt: new Date(params.lastUsedAt),\n lastUsedUserAgent,\n lastUsedIpAddress,\n }\n }\n\n private assertSubjectExists(\n projectId: string,\n subjectType: CreateAuthAccessTokenInput[\"subjectType\"],\n subjectId: string\n ): void {\n if (subjectType === \"user\") {\n const row = this.db\n .query(\"SELECT * FROM auth_users WHERE project_id = ? AND id = ?\")\n .get(projectId, subjectId) as SqliteAuthUserRow | null\n if (row) return\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${subjectId}' not found for project '${projectId}'.`\n )\n }\n\n const row = this.db\n .query(\"SELECT * FROM auth_service_accounts WHERE project_id = ? AND id = ?\")\n .get(projectId, subjectId) as SqliteAuthServiceAccountRow | null\n if (row) return\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${subjectId}' not found for project '${projectId}'.`\n )\n }\n}\n\nfunction assertKindMatchesSubject(input: CreateAuthAccessTokenInput): void {\n if (\n (input.kind === \"personal\" && input.subjectType === \"user\") ||\n (input.kind === \"serviceAccount\" && input.subjectType === \"serviceAccount\")\n ) {\n return\n }\n\n throw new AuthStorageError(\n \"invalid_input\",\n `[Sixb] Access token kind '${input.kind}' cannot target subject type '${input.subjectType}'.`\n )\n}\n",
|
|
18
|
+
"import type { Principal } from \"@sixb/core\"\nimport type {\n AccessTokenRecord,\n GroupMembershipRecord,\n GroupMembershipSource,\n InvitationRecord,\n InvitationStatus,\n MagicLinkRecord,\n OidcAuthorizationAttemptRecord,\n ServiceAccountGroupMembershipRecord,\n ServiceAccountRecord,\n ServiceAccountStatus,\n SessionRecord,\n UserIdentityRecord,\n UserRecord,\n UserStatus,\n} from \"@sixb/core/storage\"\n\nexport interface SqliteAuthUserRow {\n readonly project_id: string\n readonly id: string\n readonly email: string\n readonly display_name: string | null\n readonly avatar_url: string | null\n readonly status: UserStatus\n readonly created_at: string\n readonly updated_at: string\n}\n\nexport interface SqliteAuthUserIdentityRow {\n readonly project_id: string\n readonly strategy_id: string\n readonly subject: string\n readonly user_id: string\n readonly claims: string | null\n readonly created_at: string\n readonly updated_at: string\n}\n\nexport interface SqliteAuthServiceAccountRow {\n readonly project_id: string\n readonly id: string\n readonly name: string\n readonly description: string | null\n readonly status: ServiceAccountStatus\n readonly created_by_principal_type: Principal[\"type\"] | null\n readonly created_by_principal_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: string\n readonly updated_at: string\n}\n\nexport interface SqliteAuthServiceAccountGroupMembershipRow {\n readonly project_id: string\n readonly service_account_id: string\n readonly group_id: string\n readonly source: GroupMembershipSource\n readonly created_at: string\n}\n\nexport interface SqliteAuthSessionRow {\n readonly project_id: string\n readonly id: string\n readonly user_id: string\n readonly strategy_id: string\n readonly audience: SessionRecord[\"audience\"]\n readonly token_hash: string\n readonly created_at: string\n readonly expires_at: string\n readonly absolute_expires_at: string | null\n readonly revoked_at: string | null\n readonly last_seen_at: string | null\n readonly user_agent: string | null\n readonly ip_address: string | null\n}\n\nexport interface SqliteAuthAccessTokenRow {\n readonly project_id: string\n readonly id: string\n readonly name: string\n readonly kind: AccessTokenRecord[\"kind\"]\n readonly subject_type: AccessTokenRecord[\"subjectType\"]\n readonly subject_id: string\n readonly token_hash: string\n readonly group_ids: string | null\n readonly created_by_principal_type: Principal[\"type\"] | null\n readonly created_by_principal_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: string\n readonly expires_at: string\n readonly revoked_at: string | null\n readonly last_used_at: string | null\n readonly last_used_user_agent: string | null\n readonly last_used_ip_address: string | null\n}\n\nexport interface SqliteAuthInvitationRow {\n readonly project_id: string\n readonly id: string\n readonly email: string\n readonly status: InvitationStatus\n readonly created_by_principal_type: Principal[\"type\"] | null\n readonly created_by_principal_id: string | null\n readonly created_by_session_id: string | null\n readonly created_at: string\n readonly updated_at: string\n readonly expires_at: string\n readonly accepted_at: string | null\n readonly revoked_at: string | null\n}\n\nexport interface SqliteAuthGroupMembershipRow {\n readonly project_id: string\n readonly user_id: string\n readonly group_id: string\n readonly source: GroupMembershipSource\n readonly created_at: string\n}\n\nexport interface SqliteAuthMagicLinkRow {\n readonly project_id: string\n readonly id: string\n readonly strategy_id: string\n readonly audience: MagicLinkRecord[\"audience\"]\n readonly email: string\n readonly token_hash: string\n readonly return_to: string | null\n readonly created_at: string\n readonly expires_at: string\n readonly consumed_at: string | null\n readonly revoked_at: string | null\n}\n\nexport interface SqliteAuthOidcAttemptRow {\n readonly project_id: string\n readonly id: string\n readonly strategy_id: string\n readonly audience: OidcAuthorizationAttemptRecord[\"audience\"]\n readonly state_hash: string\n readonly nonce_hash: string\n readonly code_verifier: string\n readonly return_to: string | null\n readonly created_at: string\n readonly expires_at: string\n readonly consumed_at: string | null\n}\n\nexport function rowToUserRecord(row: SqliteAuthUserRow): UserRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n email: row.email,\n displayName: row.display_name ?? undefined,\n avatarUrl: row.avatar_url ?? undefined,\n status: row.status,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n }\n}\n\nexport function rowToIdentityRecord(row: SqliteAuthUserIdentityRow): UserIdentityRecord {\n return {\n projectId: row.project_id,\n strategyId: row.strategy_id,\n subject: row.subject,\n userId: row.user_id,\n claims: parseOptionalRecord(row.claims),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n }\n}\n\nexport function rowToServiceAccountRecord(row: SqliteAuthServiceAccountRow): ServiceAccountRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n name: row.name,\n description: row.description ?? undefined,\n status: row.status,\n createdByPrincipal:\n row.created_by_principal_type && row.created_by_principal_id\n ? {\n type: row.created_by_principal_type,\n id: row.created_by_principal_id,\n }\n : undefined,\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n }\n}\n\nexport function rowToServiceAccountGroupMembershipRecord(\n row: SqliteAuthServiceAccountGroupMembershipRow\n): ServiceAccountGroupMembershipRecord {\n return {\n projectId: row.project_id,\n serviceAccountId: row.service_account_id,\n groupId: row.group_id,\n source: row.source,\n createdAt: new Date(row.created_at),\n }\n}\n\nexport function rowToSessionRecord(row: SqliteAuthSessionRow): SessionRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n userId: row.user_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n tokenHash: row.token_hash,\n createdAt: new Date(row.created_at),\n expiresAt: new Date(row.expires_at),\n absoluteExpiresAt: row.absolute_expires_at ? new Date(row.absolute_expires_at) : undefined,\n revokedAt: row.revoked_at ? new Date(row.revoked_at) : undefined,\n lastSeenAt: row.last_seen_at ? new Date(row.last_seen_at) : undefined,\n userAgent: row.user_agent ?? undefined,\n ipAddress: row.ip_address ?? undefined,\n }\n}\n\nexport function rowToAccessTokenRecord(row: SqliteAuthAccessTokenRow): AccessTokenRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n name: row.name,\n kind: row.kind,\n subjectType: row.subject_type,\n subjectId: row.subject_id,\n tokenHash: row.token_hash,\n groupIds: parseOptionalStringArray(row.group_ids),\n createdByPrincipal:\n row.created_by_principal_type && row.created_by_principal_id\n ? {\n type: row.created_by_principal_type,\n id: row.created_by_principal_id,\n }\n : undefined,\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: new Date(row.created_at),\n expiresAt: new Date(row.expires_at),\n revokedAt: row.revoked_at ? new Date(row.revoked_at) : undefined,\n lastUsedAt: row.last_used_at ? new Date(row.last_used_at) : undefined,\n lastUsedUserAgent: row.last_used_user_agent ?? undefined,\n lastUsedIpAddress: row.last_used_ip_address ?? undefined,\n }\n}\n\nexport function rowToInvitationRecord(\n row: SqliteAuthInvitationRow,\n groupIds: readonly string[]\n): InvitationRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n email: row.email,\n groupIds,\n status: row.status,\n createdByPrincipal:\n row.created_by_principal_type && row.created_by_principal_id\n ? {\n type: row.created_by_principal_type,\n id: row.created_by_principal_id,\n }\n : undefined,\n createdBySessionId: row.created_by_session_id ?? undefined,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n expiresAt: new Date(row.expires_at),\n acceptedAt: row.accepted_at ? new Date(row.accepted_at) : undefined,\n revokedAt: row.revoked_at ? new Date(row.revoked_at) : undefined,\n }\n}\n\nexport function rowToGroupMembershipRecord(\n row: SqliteAuthGroupMembershipRow\n): GroupMembershipRecord {\n return {\n projectId: row.project_id,\n userId: row.user_id,\n groupId: row.group_id,\n source: row.source,\n createdAt: new Date(row.created_at),\n }\n}\n\nexport function rowToMagicLinkRecord(row: SqliteAuthMagicLinkRow): MagicLinkRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n email: row.email,\n tokenHash: row.token_hash,\n returnTo: row.return_to ?? undefined,\n createdAt: new Date(row.created_at),\n expiresAt: new Date(row.expires_at),\n consumedAt: row.consumed_at ? new Date(row.consumed_at) : undefined,\n revokedAt: row.revoked_at ? new Date(row.revoked_at) : undefined,\n }\n}\n\nexport function rowToOidcAuthorizationAttemptRecord(\n row: SqliteAuthOidcAttemptRow\n): OidcAuthorizationAttemptRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n strategyId: row.strategy_id,\n audience: row.audience,\n stateHash: row.state_hash,\n nonceHash: row.nonce_hash,\n codeVerifier: row.code_verifier,\n returnTo: row.return_to ?? undefined,\n createdAt: new Date(row.created_at),\n expiresAt: new Date(row.expires_at),\n consumedAt: row.consumed_at ? new Date(row.consumed_at) : undefined,\n }\n}\n\nexport function serializeOptionalRecord(\n value: Readonly<Record<string, unknown>> | undefined\n): string | null {\n return value ? JSON.stringify(value) : null\n}\n\nexport function serializeOptionalStringArray(value: readonly string[] | undefined): string | null {\n return value === undefined ? null : JSON.stringify(value)\n}\n\nfunction parseOptionalRecord(value: string | null): Readonly<Record<string, unknown>> | undefined {\n return value ? (JSON.parse(value) as Readonly<Record<string, unknown>>) : undefined\n}\n\nfunction parseOptionalStringArray(value: string | null): readonly string[] | undefined {\n return value === null ? undefined : (JSON.parse(value) as readonly string[])\n}\n",
|
|
19
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { AuthSessionAudience } from \"@sixb/core\"\nimport type {\n CompleteAuthSessionInput,\n CreateAuthSessionInput,\n GroupMembershipRecord,\n InvitationRecord,\n MagicLinkRecord,\n OidcAuthorizationAttemptRecord,\n UpsertAuthGroupMembershipInput,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { isUniqueConstraintError } from \"../storage-errors\"\nimport type {\n SqliteAuthGroupMembershipRow,\n SqliteAuthInvitationRow,\n SqliteAuthMagicLinkRow,\n SqliteAuthOidcAttemptRow,\n SqliteAuthSessionRow,\n SqliteAuthUserIdentityRow,\n SqliteAuthUserRow,\n} from \"./rows\"\nimport {\n rowToGroupMembershipRecord,\n rowToInvitationRecord,\n rowToMagicLinkRecord,\n rowToOidcAuthorizationAttemptRecord,\n rowToSessionRecord,\n rowToUserRecord,\n} from \"./rows\"\n\nexport type SqliteValue = string | number | null\n\nexport function assertNonEmpty(value: string, label: string): string {\n const normalized = value.trim()\n if (!normalized) {\n throw new AuthStorageError(\"invalid_input\", `[Sixb] ${label} must be a non-empty string.`)\n }\n return normalized\n}\n\nexport function normalizeEmail(email: string): string {\n return assertNonEmpty(email, \"Email\").toLowerCase()\n}\n\nexport function normalizeGroupIds(groupIds: readonly string[] | undefined): readonly string[] {\n return [...new Set((groupIds ?? []).map((groupId) => assertNonEmpty(groupId, \"Group id\")))]\n}\n\nexport function cloneRecord<T>(record: T): T {\n return structuredClone(record)\n}\n\nexport function dateOrNow(value: Date | undefined): Date {\n return value ? new Date(value) : new Date()\n}\n\nexport function toIso(value: Date): string {\n return value.toISOString()\n}\n\nexport function hasEmptyFilter(values: readonly unknown[] | undefined): boolean {\n return values !== undefined && values.length === 0\n}\n\nexport function appendPagination(\n query: string,\n args: SqliteValue[],\n input: { readonly limit?: number; readonly offset?: number }\n): string {\n const offset = input.offset ?? 0\n\n if (input.limit !== undefined) {\n args.push(input.limit, offset)\n return `${query} LIMIT ? OFFSET ?`\n }\n\n if (offset > 0) {\n args.push(offset)\n return `${query} LIMIT -1 OFFSET ?`\n }\n\n return query\n}\n\nexport function getUserRowById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): SqliteAuthUserRow | null {\n return db\n .query(\"SELECT * FROM auth_users WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthUserRow | null\n}\n\nexport function getUserById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): UserRecord | null {\n const row = getUserRowById(db, params)\n return row ? rowToUserRecord(row) : null\n}\n\nexport function getUserRowByEmail(\n db: Database,\n params: { readonly projectId: string; readonly email: string }\n): SqliteAuthUserRow | null {\n return db\n .query(\"SELECT * FROM auth_users WHERE project_id = ? AND email = ?\")\n .get(params.projectId, normalizeEmail(params.email)) as SqliteAuthUserRow | null\n}\n\nexport function getUserByEmail(\n db: Database,\n params: { readonly projectId: string; readonly email: string }\n): UserRecord | null {\n const row = getUserRowByEmail(db, params)\n return row ? rowToUserRecord(row) : null\n}\n\nexport function getIdentityRowBySubject(\n db: Database,\n params: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n }\n): SqliteAuthUserIdentityRow | null {\n return db\n .query(\n `\n SELECT *\n FROM auth_user_identities\n WHERE project_id = ?\n AND strategy_id = ?\n AND subject = ?\n `\n )\n .get(params.projectId, params.strategyId, params.subject) as SqliteAuthUserIdentityRow | null\n}\n\nexport function getSessionRowById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): SqliteAuthSessionRow | null {\n return db\n .query(\"SELECT * FROM auth_sessions WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthSessionRow | null\n}\n\nexport function getSessionById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): ReturnType<typeof rowToSessionRecord> | null {\n const row = getSessionRowById(db, params)\n return row ? rowToSessionRecord(row) : null\n}\n\nexport function requireSessionById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): ReturnType<typeof rowToSessionRecord> {\n const session = getSessionById(db, params)\n if (!session) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Session '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return session\n}\n\nexport function getInvitationGroupIds(\n db: Database,\n params: { readonly projectId: string; readonly invitationId: string }\n): readonly string[] {\n const rows = db\n .query(\n `\n SELECT group_id\n FROM auth_invitation_groups\n WHERE project_id = ?\n AND invitation_id = ?\n ORDER BY position ASC, group_id ASC\n `\n )\n .all(params.projectId, params.invitationId) as Array<{ readonly group_id: string }>\n\n return rows.map((row) => row.group_id)\n}\n\nexport function getInvitationById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): InvitationRecord | null {\n const row = db\n .query(\"SELECT * FROM auth_invitations WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthInvitationRow | null\n\n return row ? invitationRowToRecord(db, row) : null\n}\n\nexport function requireInvitationById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): InvitationRecord {\n const invitation = getInvitationById(db, params)\n if (!invitation) {\n throw new AuthStorageError(\n \"missing_invitation\",\n `[Sixb] Invitation '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return invitation\n}\n\nexport function getActiveInvitationByEmail(\n db: Database,\n params: { readonly projectId: string; readonly email: string; readonly now: Date }\n): InvitationRecord | null {\n const row = db\n .query(\n `\n SELECT *\n FROM auth_invitations\n WHERE project_id = ?\n AND email = ?\n AND status = 'pending'\n AND expires_at > ?\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n `\n )\n .get(\n params.projectId,\n normalizeEmail(params.email),\n toIso(params.now)\n ) as SqliteAuthInvitationRow | null\n\n return row ? invitationRowToRecord(db, row) : null\n}\n\nexport function replaceInvitationGroups(\n db: Database,\n params: {\n readonly projectId: string\n readonly invitationId: string\n readonly groupIds: readonly string[]\n }\n): void {\n db.query(\"DELETE FROM auth_invitation_groups WHERE project_id = ? AND invitation_id = ?\").run(\n params.projectId,\n params.invitationId\n )\n\n for (const [index, groupId] of params.groupIds.entries()) {\n db.query(\n `\n INSERT INTO auth_invitation_groups (\n project_id,\n invitation_id,\n group_id,\n position\n ) VALUES (?, ?, ?, ?)\n `\n ).run(params.projectId, params.invitationId, groupId, index)\n }\n}\n\nexport function getMagicLinkRowById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): SqliteAuthMagicLinkRow | null {\n return db\n .query(\"SELECT * FROM auth_magic_links WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthMagicLinkRow | null\n}\n\nexport function getMagicLinkById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): MagicLinkRecord | null {\n const row = getMagicLinkRowById(db, params)\n return row ? rowToMagicLinkRecord(row) : null\n}\n\nexport function consumeMagicLink(\n db: Database,\n params: {\n readonly projectId: string\n readonly id: string\n readonly tokenHash: string\n readonly consumedAt: Date\n }\n): MagicLinkRecord {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const id = assertNonEmpty(params.id, \"Magic link id\")\n const tokenHash = assertNonEmpty(params.tokenHash, \"Magic link token hash\")\n const row = getMagicLinkRowById(db, { projectId, id })\n\n if (!row) {\n throw new AuthStorageError(\n \"missing_magic_link\",\n `[Sixb] Magic link '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.token_hash !== tokenHash || row.consumed_at || row.revoked_at) {\n throw new AuthStorageError(\n \"invalid_magic_link\",\n `[Sixb] Magic link '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= params.consumedAt) {\n throw new AuthStorageError(\n \"expired_magic_link\",\n `[Sixb] Magic link '${id}' is expired for project '${projectId}'.`\n )\n }\n\n db.query(\n `\n UPDATE auth_magic_links\n SET consumed_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n ).run(toIso(params.consumedAt), projectId, id)\n\n return rowToMagicLinkRecord({\n ...row,\n consumed_at: toIso(params.consumedAt),\n })\n}\n\nexport function getOidcAttemptRowById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): SqliteAuthOidcAttemptRow | null {\n return db\n .query(\"SELECT * FROM auth_oidc_authorization_attempts WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthOidcAttemptRow | null\n}\n\nexport function getOidcAttemptById(\n db: Database,\n params: { readonly projectId: string; readonly id: string }\n): OidcAuthorizationAttemptRecord | null {\n const row = getOidcAttemptRowById(db, params)\n return row ? rowToOidcAuthorizationAttemptRecord(row) : null\n}\n\nexport function consumeOidcAttempt(\n db: Database,\n params: {\n readonly projectId: string\n readonly id: string\n readonly stateHash: string\n readonly consumedAt: Date\n }\n): OidcAuthorizationAttemptRecord {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const id = assertNonEmpty(params.id, \"OIDC authorization attempt id\")\n const stateHash = assertNonEmpty(params.stateHash, \"OIDC state hash\")\n const row = getOidcAttemptRowById(db, { projectId, id })\n\n if (!row) {\n throw new AuthStorageError(\n \"missing_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.state_hash !== stateHash || row.consumed_at) {\n throw new AuthStorageError(\n \"invalid_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is not valid for project '${projectId}'.`\n )\n }\n\n if (new Date(row.expires_at) <= params.consumedAt) {\n throw new AuthStorageError(\n \"expired_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' is expired for project '${projectId}'.`\n )\n }\n\n db.query(\n `\n UPDATE auth_oidc_authorization_attempts\n SET consumed_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n ).run(toIso(params.consumedAt), projectId, id)\n\n return rowToOidcAuthorizationAttemptRecord({\n ...row,\n consumed_at: toIso(params.consumedAt),\n })\n}\n\nexport function validateCompleteSessionInput(\n db: Database,\n projectId: string,\n session: CompleteAuthSessionInput\n): void {\n const sessionId = assertNonEmpty(session.id, \"Session id\")\n assertNonEmpty(session.audience, \"Session audience\")\n assertNonEmpty(session.tokenHash, \"Session token hash\")\n assertSessionIdAvailable(db, projectId, sessionId)\n}\n\nexport function assertSessionIdAvailable(db: Database, projectId: string, sessionId: string): void {\n if (getSessionRowById(db, { projectId, id: sessionId })) {\n throw new AuthStorageError(\n \"duplicate_session\",\n `[Sixb] Session '${sessionId}' already exists for project '${projectId}'.`\n )\n }\n}\n\nexport function createSession(\n db: Database,\n input: CreateAuthSessionInput\n): ReturnType<typeof rowToSessionRecord> {\n const id = assertNonEmpty(input.id, \"Session id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = assertNonEmpty(input.audience, \"Session audience\")\n const tokenHash = assertNonEmpty(input.tokenHash, \"Session token hash\")\n\n assertSessionIdAvailable(db, projectId, id)\n\n db.query(\n `\n INSERT INTO auth_sessions (\n project_id,\n id,\n user_id,\n strategy_id,\n audience,\n token_hash,\n created_at,\n expires_at,\n absolute_expires_at,\n user_agent,\n ip_address\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n ).run(\n projectId,\n id,\n userId,\n strategyId,\n audience,\n tokenHash,\n toIso(input.createdAt),\n toIso(input.expiresAt),\n input.absoluteExpiresAt ? toIso(input.absoluteExpiresAt) : null,\n input.userAgent ?? null,\n input.ipAddress ?? null\n )\n\n const session = getSessionById(db, { projectId, id })\n if (!session) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Failed to load session '${id}' for project '${projectId}'.`\n )\n }\n return session\n}\n\nexport function revokeActiveSessionsForUser(\n db: Database,\n params: {\n readonly projectId: string\n readonly userId: string\n readonly audience?: AuthSessionAudience\n readonly revokedAt: Date\n }\n): readonly ReturnType<typeof rowToSessionRecord>[] {\n const revokedAt = toIso(params.revokedAt)\n const audienceCondition = params.audience === undefined ? \"\" : \"AND audience = ?\"\n const selectArgs =\n params.audience === undefined\n ? [params.projectId, params.userId, revokedAt, revokedAt]\n : [params.projectId, params.userId, params.audience, revokedAt, revokedAt]\n const updateArgs =\n params.audience === undefined\n ? [revokedAt, params.projectId, params.userId, revokedAt, revokedAt]\n : [revokedAt, params.projectId, params.userId, params.audience, revokedAt, revokedAt]\n const rows = db\n .query(\n `\n SELECT *\n FROM auth_sessions\n WHERE project_id = ?\n AND user_id = ?\n ${audienceCondition}\n AND revoked_at IS NULL\n AND expires_at > ?\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)\n ORDER BY created_at ASC, id ASC\n `\n )\n .all(...selectArgs) as SqliteAuthSessionRow[]\n\n db.query(\n `\n UPDATE auth_sessions\n SET revoked_at = ?\n WHERE project_id = ?\n AND user_id = ?\n ${audienceCondition}\n AND revoked_at IS NULL\n AND expires_at > ?\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)\n `\n ).run(...updateArgs)\n\n return rows.map((row) =>\n rowToSessionRecord({\n ...row,\n revoked_at: revokedAt,\n })\n )\n}\n\nexport function upsertGroupMembership(\n db: Database,\n input: UpsertAuthGroupMembershipInput\n): GroupMembershipRecord {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const groupId = assertNonEmpty(input.groupId, \"Group id\")\n if (!getUserRowById(db, { projectId, id: userId })) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${userId}' not found for project '${projectId}'.`\n )\n }\n\n const existing = getGroupMembership(db, { projectId, userId, groupId })\n\n if (existing) {\n return existing\n }\n\n const createdAt = dateOrNow(input.createdAt)\n db.query(\n `\n INSERT INTO auth_group_memberships (\n project_id,\n user_id,\n group_id,\n source,\n created_at\n ) VALUES (?, ?, ?, ?, ?)\n `\n ).run(projectId, userId, groupId, input.source, toIso(createdAt))\n\n return {\n projectId,\n userId,\n groupId,\n source: input.source,\n createdAt,\n }\n}\n\nexport function removeGroupMembership(\n db: Database,\n params: { readonly projectId: string; readonly userId: string; readonly groupId: string }\n): GroupMembershipRecord | null {\n const projectId = assertNonEmpty(params.projectId, \"Project id\")\n const userId = assertNonEmpty(params.userId, \"User id\")\n const groupId = assertNonEmpty(params.groupId, \"Group id\")\n\n const existing = getGroupMembership(db, { projectId, userId, groupId })\n if (!existing) {\n return null\n }\n\n db.query(\n `\n DELETE FROM auth_group_memberships\n WHERE project_id = ?\n AND user_id = ?\n AND group_id = ?\n `\n ).run(projectId, userId, groupId)\n\n return existing\n}\n\nexport function getGroupMembership(\n db: Database,\n params: { readonly projectId: string; readonly userId: string; readonly groupId: string }\n): GroupMembershipRecord | null {\n const row = db\n .query(\n `\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ?\n AND user_id = ?\n AND group_id = ?\n `\n )\n .get(params.projectId, params.userId, params.groupId) as SqliteAuthGroupMembershipRow | null\n\n return row ? rowToGroupMembershipRecord(row) : null\n}\n\nexport function listMembershipsForUser(\n db: Database,\n params: { readonly projectId: string; readonly userId: string }\n): readonly GroupMembershipRecord[] {\n const rows = db\n .query(\n `\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ?\n AND user_id = ?\n ORDER BY group_id ASC\n `\n )\n .all(params.projectId, params.userId) as SqliteAuthGroupMembershipRow[]\n\n return rows.map(rowToGroupMembershipRecord)\n}\n\nexport function revokeActiveMagicLinksForEmail(\n db: Database,\n params: { readonly projectId: string; readonly email: string; readonly revokedAt: Date }\n): readonly MagicLinkRecord[] {\n const email = normalizeEmail(params.email)\n const revokedAt = toIso(params.revokedAt)\n const rows = db\n .query(\n `\n SELECT *\n FROM auth_magic_links\n WHERE project_id = ?\n AND email = ?\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ?\n ORDER BY created_at ASC, id ASC\n `\n )\n .all(params.projectId, email, revokedAt) as SqliteAuthMagicLinkRow[]\n\n db.query(\n `\n UPDATE auth_magic_links\n SET revoked_at = ?\n WHERE project_id = ?\n AND email = ?\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ?\n `\n ).run(revokedAt, params.projectId, email, revokedAt)\n\n return rows.map((row) =>\n rowToMagicLinkRecord({\n ...row,\n revoked_at: revokedAt,\n })\n )\n}\n\nexport function mapUniqueConstraintError(\n error: unknown,\n code:\n | \"duplicate_access_token\"\n | \"duplicate_identity\"\n | \"duplicate_invitation\"\n | \"duplicate_magic_link\"\n | \"duplicate_oidc_attempt\"\n | \"duplicate_service_account\"\n | \"duplicate_session\"\n | \"duplicate_user\",\n message: string\n): never {\n if (isUniqueConstraintError(error)) {\n throw new AuthStorageError(code, message)\n }\n\n throw error\n}\n\nfunction invitationRowToRecord(db: Database, row: SqliteAuthInvitationRow): InvitationRecord {\n return rowToInvitationRecord(\n row,\n getInvitationGroupIds(db, {\n projectId: row.project_id,\n invitationId: row.id,\n })\n )\n}\n",
|
|
20
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthGroupMembershipStore,\n GroupMembershipRecord,\n UpsertAuthGroupMembershipInput,\n} from \"@sixb/core/storage\"\nimport { runImmediateTransaction } from \"../transactions\"\nimport type { SqliteAuthGroupMembershipRow } from \"./rows\"\nimport { rowToGroupMembershipRecord } from \"./rows\"\nimport { listMembershipsForUser, removeGroupMembership, upsertGroupMembership } from \"./shared\"\n\nexport class SqliteAuthGroupMembershipStore implements AuthGroupMembershipStore {\n constructor(private readonly db: Database) {}\n\n async upsert(input: UpsertAuthGroupMembershipInput): Promise<GroupMembershipRecord> {\n return runImmediateTransaction(this.db, () => upsertGroupMembership(this.db, input))\n }\n\n async remove(params: {\n readonly projectId: string\n readonly userId: string\n readonly groupId: string\n }): Promise<GroupMembershipRecord | null> {\n return runImmediateTransaction(this.db, () => removeGroupMembership(this.db, params))\n }\n\n async listForUser(params: {\n readonly projectId: string\n readonly userId: string\n }): Promise<readonly GroupMembershipRecord[]> {\n return listMembershipsForUser(this.db, params)\n }\n\n async listForGroup(params: {\n readonly projectId: string\n readonly groupId: string\n }): Promise<readonly GroupMembershipRecord[]> {\n const rows = this.db\n .query(\n `\n SELECT *\n FROM auth_group_memberships\n WHERE project_id = ?\n AND group_id = ?\n ORDER BY user_id ASC\n `\n )\n .all(params.projectId, params.groupId) as SqliteAuthGroupMembershipRow[]\n\n return rows.map(rowToGroupMembershipRecord)\n }\n}\n",
|
|
21
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthUserIdentityStore,\n UpsertAuthUserIdentityInput,\n UserIdentityRecord,\n} from \"@sixb/core/storage\"\nimport type { SqliteAuthUserIdentityRow } from \"./rows\"\nimport { rowToIdentityRecord, serializeOptionalRecord } from \"./rows\"\nimport { assertNonEmpty, dateOrNow, getIdentityRowBySubject, toIso } from \"./shared\"\n\nexport class SqliteAuthUserIdentityStore implements AuthUserIdentityStore {\n constructor(private readonly db: Database) {}\n\n async upsert(input: UpsertAuthUserIdentityInput): Promise<UserIdentityRecord> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const subject = assertNonEmpty(input.subject, \"Subject\")\n const userId = assertNonEmpty(input.userId, \"User id\")\n const existing = getIdentityRowBySubject(this.db, {\n projectId,\n strategyId,\n subject,\n })\n const createdAt = existing ? new Date(existing.created_at) : dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt\n ? new Date(input.updatedAt)\n : existing\n ? new Date()\n : createdAt\n\n this.db\n .query(\n `\n INSERT INTO auth_user_identities (\n project_id,\n strategy_id,\n subject,\n user_id,\n claims,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(project_id, strategy_id, subject)\n DO UPDATE SET\n user_id = excluded.user_id,\n claims = excluded.claims,\n updated_at = excluded.updated_at\n `\n )\n .run(\n projectId,\n strategyId,\n subject,\n userId,\n serializeOptionalRecord(input.claims),\n toIso(createdAt),\n toIso(updatedAt)\n )\n\n return {\n projectId,\n strategyId,\n subject,\n userId,\n claims: input.claims ? structuredClone(input.claims) : undefined,\n createdAt,\n updatedAt,\n }\n }\n\n async getBySubject(params: {\n readonly projectId: string\n readonly strategyId: string\n readonly subject: string\n }): Promise<UserIdentityRecord | null> {\n const row = getIdentityRowBySubject(this.db, params)\n return row ? rowToIdentityRecord(row) : null\n }\n\n async listForUser(params: {\n readonly projectId: string\n readonly userId: string\n }): Promise<readonly UserIdentityRecord[]> {\n const rows = this.db\n .query(\n `\n SELECT *\n FROM auth_user_identities\n WHERE project_id = ?\n AND user_id = ?\n ORDER BY created_at ASC, strategy_id ASC, subject ASC\n `\n )\n .all(params.projectId, params.userId) as SqliteAuthUserIdentityRow[]\n\n return rows.map(rowToIdentityRecord)\n }\n}\n",
|
|
22
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthInvitationStore,\n CreateOrUpdateAuthInvitationInput,\n InvitationRecord,\n ListAuthInvitationsInput,\n ListAuthInvitationsResult,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { runImmediateTransaction } from \"../transactions\"\nimport type { SqliteAuthInvitationRow } from \"./rows\"\nimport { rowToInvitationRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n getActiveInvitationByEmail,\n getInvitationById,\n getInvitationGroupIds,\n hasEmptyFilter,\n mapUniqueConstraintError,\n normalizeEmail,\n normalizeGroupIds,\n replaceInvitationGroups,\n requireInvitationById,\n type SqliteValue,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthInvitationStore implements AuthInvitationStore {\n constructor(private readonly db: Database) {}\n\n async createOrUpdateActive(input: CreateOrUpdateAuthInvitationInput): Promise<InvitationRecord> {\n return runImmediateTransaction(this.db, () => {\n const id = assertNonEmpty(input.id, \"Invitation id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const email = normalizeEmail(input.email)\n const groupIds = normalizeGroupIds(input.groupIds)\n const now = dateOrNow(input.updatedAt ?? input.createdAt)\n const existingActive = getActiveInvitationByEmail(this.db, {\n projectId,\n email,\n now,\n })\n\n if (existingActive) {\n this.db\n .query(\n `\n UPDATE auth_invitations\n SET created_by_principal_type = ?,\n created_by_principal_id = ?,\n created_by_session_id = ?,\n expires_at = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(\n input.createdByPrincipal?.type ?? null,\n input.createdByPrincipal?.id ?? null,\n input.createdBySessionId ?? null,\n toIso(input.expiresAt),\n toIso(now),\n projectId,\n existingActive.id\n )\n replaceInvitationGroups(this.db, {\n projectId,\n invitationId: existingActive.id,\n groupIds,\n })\n\n return requireInvitationById(this.db, { projectId, id: existingActive.id })\n }\n\n if (getInvitationById(this.db, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_invitation\",\n `[Sixb] Invitation '${id}' already exists but is not active for project '${projectId}'.`\n )\n }\n\n const createdAt = dateOrNow(input.createdAt)\n try {\n this.db\n .query(\n `\n INSERT INTO auth_invitations (\n project_id,\n id,\n email,\n status,\n created_by_principal_type,\n created_by_principal_id,\n created_by_session_id,\n created_at,\n updated_at,\n expires_at\n ) VALUES (?, ?, ?, 'pending', ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n email,\n input.createdByPrincipal?.type ?? null,\n input.createdByPrincipal?.id ?? null,\n input.createdBySessionId ?? null,\n toIso(createdAt),\n toIso(now),\n toIso(input.expiresAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_invitation\",\n `[Sixb] Invitation '${id}' already exists for project '${projectId}'.`\n )\n }\n\n replaceInvitationGroups(this.db, { projectId, invitationId: id, groupIds })\n return requireInvitationById(this.db, { projectId, id })\n })\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<InvitationRecord | null> {\n return getInvitationById(this.db, params)\n }\n\n async getActiveByEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly now: Date\n }): Promise<InvitationRecord | null> {\n return getActiveInvitationByEmail(this.db, params)\n }\n\n async list(input: ListAuthInvitationsInput): Promise<ListAuthInvitationsResult> {\n if (hasEmptyFilter(input.statuses) || hasEmptyFilter(input.groupIds)) {\n return { invitations: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.email) {\n whereClauses.push(\"email = ?\")\n args.push(normalizeEmail(input.email))\n }\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n const groupIds = input.groupIds ? normalizeGroupIds(input.groupIds) : null\n if (groupIds) {\n whereClauses.push(`\n EXISTS (\n SELECT 1\n FROM auth_invitation_groups invitation_groups\n WHERE invitation_groups.project_id = auth_invitations.project_id\n AND invitation_groups.invitation_id = auth_invitations.id\n AND invitation_groups.group_id IN (${groupIds.map(() => \"?\").join(\", \")})\n )\n `)\n args.push(...groupIds)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM auth_invitations ${where}`)\n .get(...args) as { readonly count: number }\n\n const queryArgs = [...args]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_invitations\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryArgs,\n input\n )\n const rows = this.db.query(query).all(...queryArgs) as SqliteAuthInvitationRow[]\n\n return {\n invitations: rows.map((row) =>\n rowToInvitationRecord(\n row,\n getInvitationGroupIds(this.db, {\n projectId: row.project_id,\n invitationId: row.id,\n })\n )\n ),\n hasMore: (input.offset ?? 0) + rows.length < totalRow.count,\n total: totalRow.count,\n }\n }\n\n async accept(params: {\n readonly projectId: string\n readonly id: string\n readonly acceptedAt: Date\n }): Promise<InvitationRecord> {\n return runImmediateTransaction(this.db, () => {\n requireInvitationById(this.db, params)\n\n this.db\n .query(\n `\n UPDATE auth_invitations\n SET status = 'accepted',\n accepted_at = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(params.acceptedAt), toIso(params.acceptedAt), params.projectId, params.id)\n\n return requireInvitationById(this.db, params)\n })\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<InvitationRecord> {\n return runImmediateTransaction(this.db, () => {\n requireInvitationById(this.db, params)\n\n this.db\n .query(\n `\n UPDATE auth_invitations\n SET status = 'revoked',\n revoked_at = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(params.revokedAt), toIso(params.revokedAt), params.projectId, params.id)\n\n return requireInvitationById(this.db, params)\n })\n }\n}\n",
|
|
23
|
+
"import type { Database } from \"bun:sqlite\"\nimport { resolveAuthSessionAudience } from \"@sixb/core\"\nimport type {\n AuthMagicLinkStore,\n CreateAuthMagicLinkInput,\n MagicLinkRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { runImmediateTransaction } from \"../transactions\"\nimport type { SqliteAuthMagicLinkRow } from \"./rows\"\nimport { rowToMagicLinkRecord } from \"./rows\"\nimport {\n assertNonEmpty,\n consumeMagicLink,\n getMagicLinkById,\n getMagicLinkRowById,\n mapUniqueConstraintError,\n normalizeEmail,\n revokeActiveMagicLinksForEmail,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthMagicLinkStore implements AuthMagicLinkStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAuthMagicLinkInput): Promise<MagicLinkRecord> {\n return runImmediateTransaction(this.db, () => {\n const id = assertNonEmpty(input.id, \"Magic link id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = resolveAuthSessionAudience(input.audience)\n const email = normalizeEmail(input.email)\n const tokenHash = assertNonEmpty(input.tokenHash, \"Magic link token hash\")\n\n if (getMagicLinkRowById(this.db, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_magic_link\",\n `[Sixb] Magic link '${id}' already exists for project '${projectId}'.`\n )\n }\n\n revokeActiveMagicLinksForEmail(this.db, {\n projectId,\n email,\n revokedAt: input.createdAt,\n })\n\n try {\n this.db\n .query(\n `\n INSERT INTO auth_magic_links (\n project_id,\n id,\n strategy_id,\n audience,\n email,\n token_hash,\n return_to,\n created_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n strategyId,\n audience,\n email,\n tokenHash,\n input.returnTo ?? null,\n toIso(input.createdAt),\n toIso(input.expiresAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_magic_link\",\n `[Sixb] Magic link '${id}' already exists for project '${projectId}'.`\n )\n }\n\n return {\n id,\n projectId,\n strategyId,\n audience,\n email,\n tokenHash,\n returnTo: input.returnTo,\n createdAt: new Date(input.createdAt),\n expiresAt: new Date(input.expiresAt),\n }\n })\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<MagicLinkRecord | null> {\n return getMagicLinkById(this.db, params)\n }\n\n async getActiveByEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly now: Date\n }): Promise<MagicLinkRecord | null> {\n const row = this.db\n .query(\n `\n SELECT *\n FROM auth_magic_links\n WHERE project_id = ?\n AND email = ?\n AND consumed_at IS NULL\n AND revoked_at IS NULL\n AND expires_at > ?\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n `\n )\n .get(\n params.projectId,\n normalizeEmail(params.email),\n toIso(params.now)\n ) as SqliteAuthMagicLinkRow | null\n\n return row ? rowToMagicLinkRecord(row) : null\n }\n\n async consume(params: {\n readonly projectId: string\n readonly id: string\n readonly tokenHash: string\n readonly consumedAt: Date\n }): Promise<MagicLinkRecord> {\n return runImmediateTransaction(this.db, () => consumeMagicLink(this.db, params))\n }\n\n async revokeActiveForEmail(params: {\n readonly projectId: string\n readonly email: string\n readonly revokedAt: Date\n }): Promise<readonly MagicLinkRecord[]> {\n return runImmediateTransaction(this.db, () => revokeActiveMagicLinksForEmail(this.db, params))\n }\n}\n",
|
|
24
|
+
"import type { Database } from \"bun:sqlite\"\nimport { resolveAuthSessionAudience } from \"@sixb/core\"\nimport type {\n AuthOidcAuthorizationAttemptStore,\n CreateOidcAuthorizationAttemptInput,\n OidcAuthorizationAttemptRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { runImmediateTransaction } from \"../transactions\"\nimport {\n assertNonEmpty,\n consumeOidcAttempt,\n getOidcAttemptById,\n getOidcAttemptRowById,\n mapUniqueConstraintError,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthOidcAuthorizationAttemptStore implements AuthOidcAuthorizationAttemptStore {\n constructor(private readonly db: Database) {}\n\n async create(\n input: CreateOidcAuthorizationAttemptInput\n ): Promise<OidcAuthorizationAttemptRecord> {\n return runImmediateTransaction(this.db, () => {\n const id = assertNonEmpty(input.id, \"OIDC authorization attempt id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const strategyId = assertNonEmpty(input.strategyId, \"Strategy id\")\n const audience = resolveAuthSessionAudience(input.audience)\n const stateHash = assertNonEmpty(input.stateHash, \"OIDC state hash\")\n const nonceHash = assertNonEmpty(input.nonceHash, \"OIDC nonce hash\")\n const codeVerifier = assertNonEmpty(input.codeVerifier, \"OIDC code verifier\")\n\n if (getOidcAttemptRowById(this.db, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' already exists for project '${projectId}'.`\n )\n }\n\n try {\n this.db\n .query(\n `\n INSERT INTO auth_oidc_authorization_attempts (\n project_id,\n id,\n strategy_id,\n audience,\n state_hash,\n nonce_hash,\n code_verifier,\n return_to,\n created_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n strategyId,\n audience,\n stateHash,\n nonceHash,\n codeVerifier,\n input.returnTo ?? null,\n toIso(input.createdAt),\n toIso(input.expiresAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_oidc_attempt\",\n `[Sixb] OIDC authorization attempt '${id}' already exists for project '${projectId}'.`\n )\n }\n\n return {\n id,\n projectId,\n strategyId,\n audience,\n stateHash,\n nonceHash,\n codeVerifier,\n returnTo: input.returnTo,\n createdAt: new Date(input.createdAt),\n expiresAt: new Date(input.expiresAt),\n }\n })\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<OidcAuthorizationAttemptRecord | null> {\n return getOidcAttemptById(this.db, params)\n }\n\n async consume(params: {\n readonly projectId: string\n readonly id: string\n readonly stateHash: string\n readonly consumedAt: Date\n }): Promise<OidcAuthorizationAttemptRecord> {\n return runImmediateTransaction(this.db, () => consumeOidcAttempt(this.db, params))\n }\n}\n",
|
|
25
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthServiceAccountGroupMembershipStore,\n ReconcileAuthServiceAccountGroupMembershipsInput,\n ServiceAccountGroupMembershipRecord,\n UpsertAuthServiceAccountGroupMembershipInput,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type {\n SqliteAuthServiceAccountGroupMembershipRow,\n SqliteAuthServiceAccountRow,\n} from \"./rows\"\nimport { rowToServiceAccountGroupMembershipRecord } from \"./rows\"\nimport { assertNonEmpty, dateOrNow, normalizeGroupIds, toIso } from \"./shared\"\n\nexport class SqliteAuthServiceAccountGroupMembershipStore\n implements AuthServiceAccountGroupMembershipStore\n{\n constructor(private readonly db: Database) {}\n\n async upsert(\n input: UpsertAuthServiceAccountGroupMembershipInput\n ): Promise<ServiceAccountGroupMembershipRecord> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const serviceAccountId = assertNonEmpty(input.serviceAccountId, \"Service account id\")\n const groupId = assertNonEmpty(input.groupId, \"Group id\")\n const serviceAccount = this.db\n .query(\"SELECT * FROM auth_service_accounts WHERE project_id = ? AND id = ?\")\n .get(projectId, serviceAccountId) as SqliteAuthServiceAccountRow | null\n if (!serviceAccount) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${serviceAccountId}' not found for project '${projectId}'.`\n )\n }\n\n this.db\n .query(\n `\n INSERT OR IGNORE INTO auth_service_account_group_memberships (\n project_id,\n service_account_id,\n group_id,\n source,\n created_at\n ) VALUES (?, ?, ?, ?, ?)\n `\n )\n .run(projectId, serviceAccountId, groupId, input.source, toIso(dateOrNow(input.createdAt)))\n\n const row = this.db\n .query(\n `\n SELECT *\n FROM auth_service_account_group_memberships\n WHERE project_id = ?\n AND service_account_id = ?\n AND group_id = ?\n `\n )\n .get(projectId, serviceAccountId, groupId) as SqliteAuthServiceAccountGroupMembershipRow\n return rowToServiceAccountGroupMembershipRecord(row)\n }\n\n async reconcileForServiceAccount(\n input: ReconcileAuthServiceAccountGroupMembershipsInput\n ): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const serviceAccountId = assertNonEmpty(input.serviceAccountId, \"Service account id\")\n const serviceAccount = this.db\n .query(\"SELECT * FROM auth_service_accounts WHERE project_id = ? AND id = ?\")\n .get(projectId, serviceAccountId) as SqliteAuthServiceAccountRow | null\n if (!serviceAccount) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${serviceAccountId}' not found for project '${projectId}'.`\n )\n }\n\n const groupIds = normalizeGroupIds(input.groupIds)\n const desired = new Set(groupIds)\n const existing = await this.listForServiceAccount({ projectId, serviceAccountId })\n for (const membership of existing) {\n if (membership.source === input.source && !desired.has(membership.groupId)) {\n this.db\n .query(\n `\n DELETE FROM auth_service_account_group_memberships\n WHERE project_id = ?\n AND service_account_id = ?\n AND group_id = ?\n AND source = ?\n `\n )\n .run(projectId, serviceAccountId, membership.groupId, input.source)\n }\n }\n\n const updatedAt = toIso(dateOrNow(input.updatedAt))\n for (const groupId of groupIds) {\n this.db\n .query(\n `\n INSERT INTO auth_service_account_group_memberships (\n project_id,\n service_account_id,\n group_id,\n source,\n created_at\n ) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(project_id, service_account_id, group_id) DO UPDATE\n SET source = excluded.source\n `\n )\n .run(projectId, serviceAccountId, groupId, input.source, updatedAt)\n }\n\n return this.listForServiceAccount({ projectId, serviceAccountId })\n }\n\n async listForServiceAccount(params: {\n readonly projectId: string\n readonly serviceAccountId: string\n }): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const rows = this.db\n .query(\n `\n SELECT *\n FROM auth_service_account_group_memberships\n WHERE project_id = ?\n AND service_account_id = ?\n ORDER BY group_id ASC\n `\n )\n .all(\n params.projectId,\n params.serviceAccountId\n ) as SqliteAuthServiceAccountGroupMembershipRow[]\n\n return rows.map(rowToServiceAccountGroupMembershipRecord)\n }\n\n async listForGroup(params: {\n readonly projectId: string\n readonly groupId: string\n }): Promise<readonly ServiceAccountGroupMembershipRecord[]> {\n const rows = this.db\n .query(\n `\n SELECT *\n FROM auth_service_account_group_memberships\n WHERE project_id = ?\n AND group_id = ?\n ORDER BY service_account_id ASC\n `\n )\n .all(params.projectId, params.groupId) as SqliteAuthServiceAccountGroupMembershipRow[]\n\n return rows.map(rowToServiceAccountGroupMembershipRecord)\n }\n}\n",
|
|
26
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthServiceAccountStore,\n CreateAuthServiceAccountInput,\n ListAuthServiceAccountsInput,\n ListAuthServiceAccountsResult,\n ServiceAccountRecord,\n UpdateAuthServiceAccountInput,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { SqliteAuthServiceAccountRow } from \"./rows\"\nimport { rowToServiceAccountRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n hasEmptyFilter,\n mapUniqueConstraintError,\n type SqliteValue,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthServiceAccountStore implements AuthServiceAccountStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAuthServiceAccountInput): Promise<ServiceAccountRecord> {\n const id = assertNonEmpty(input.id, \"Service account id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const name = assertNonEmpty(input.name, \"Service account name\")\n const createdAt = dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt ? new Date(input.updatedAt) : createdAt\n\n try {\n this.db\n .query(\n `\n INSERT INTO auth_service_accounts (\n project_id,\n id,\n name,\n description,\n status,\n created_by_principal_type,\n created_by_principal_id,\n created_by_session_id,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n name,\n input.description ?? null,\n input.status ?? \"active\",\n input.createdByPrincipal?.type ?? null,\n input.createdByPrincipal?.id ?? null,\n input.createdBySessionId ?? null,\n toIso(createdAt),\n toIso(updatedAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_service_account\",\n `[Sixb] Service account '${id}' already exists for project '${projectId}'.`\n )\n }\n\n return {\n id,\n projectId,\n name,\n description: input.description,\n status: input.status ?? \"active\",\n createdByPrincipal: input.createdByPrincipal,\n createdBySessionId: input.createdBySessionId,\n createdAt,\n updatedAt,\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<ServiceAccountRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM auth_service_accounts WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as SqliteAuthServiceAccountRow | null\n return row ? rowToServiceAccountRecord(row) : null\n }\n\n async update(input: UpdateAuthServiceAccountInput): Promise<ServiceAccountRecord> {\n const existing = await this.getById(input)\n if (!existing) {\n throw new AuthStorageError(\n \"missing_service_account\",\n `[Sixb] Service account '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n const name =\n input.name === undefined ? existing.name : assertNonEmpty(input.name, \"Service account name\")\n const description = input.description === undefined ? existing.description : input.description\n const status = input.status ?? existing.status\n this.db\n .query(\n `\n UPDATE auth_service_accounts\n SET name = ?,\n description = ?,\n status = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(name, description ?? null, status, toIso(updatedAt), input.projectId, input.id)\n\n return {\n ...existing,\n name,\n description,\n status,\n updatedAt,\n }\n }\n\n async list(input: ListAuthServiceAccountsInput): Promise<ListAuthServiceAccountsResult> {\n if (hasEmptyFilter(input.statuses)) {\n return { serviceAccounts: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM auth_service_accounts ${where}`)\n .get(...args) as { readonly count: number }\n const queryArgs = [...args]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_service_accounts\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryArgs,\n input\n )\n const rows = this.db.query(query).all(...queryArgs) as SqliteAuthServiceAccountRow[]\n\n return {\n serviceAccounts: rows.map(rowToServiceAccountRecord),\n hasMore:\n input.limit === undefined ? false : (input.offset ?? 0) + input.limit < totalRow.count,\n total: totalRow.count,\n }\n }\n}\n",
|
|
27
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { AuthSessionAudience } from \"@sixb/core\"\nimport type { AuthSessionStore, CreateAuthSessionInput, SessionRecord } from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport { runImmediateTransaction } from \"../transactions\"\nimport type { SqliteAuthSessionRow } from \"./rows\"\nimport { rowToSessionRecord } from \"./rows\"\nimport {\n createSession,\n getSessionById,\n getSessionRowById,\n requireSessionById,\n revokeActiveSessionsForUser,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthSessionStore implements AuthSessionStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAuthSessionInput): Promise<SessionRecord> {\n return runImmediateTransaction(this.db, () => createSession(this.db, input))\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<SessionRecord | null> {\n return getSessionById(this.db, params)\n }\n\n async getActiveByUserId(params: {\n readonly projectId: string\n readonly userId: string\n readonly audience: AuthSessionAudience\n readonly now: Date\n }): Promise<SessionRecord | null> {\n const row = this.db\n .query(\n `\n SELECT *\n FROM auth_sessions\n WHERE project_id = ?\n AND user_id = ?\n AND audience = ?\n AND revoked_at IS NULL\n AND expires_at > ?\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)\n ORDER BY created_at DESC, id DESC\n LIMIT 1\n `\n )\n .get(\n params.projectId,\n params.userId,\n params.audience,\n toIso(params.now),\n toIso(params.now)\n ) as SqliteAuthSessionRow | null\n\n return row ? rowToSessionRecord(row) : null\n }\n\n async listActiveByUserId(params: {\n readonly projectId: string\n readonly userId: string\n readonly now: Date\n }): Promise<readonly SessionRecord[]> {\n const rows = this.db\n .query(\n `\n SELECT *\n FROM auth_sessions\n WHERE project_id = ?\n AND user_id = ?\n AND revoked_at IS NULL\n AND expires_at > ?\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)\n ORDER BY COALESCE(last_seen_at, created_at) DESC, created_at DESC, id DESC\n `\n )\n .all(\n params.projectId,\n params.userId,\n toIso(params.now),\n toIso(params.now)\n ) as SqliteAuthSessionRow[]\n\n return rows.map(rowToSessionRecord)\n }\n\n async findValidByTokenHash(params: {\n readonly projectId: string\n readonly id: string\n readonly audience: AuthSessionAudience\n readonly tokenHash: string\n readonly now: Date\n }): Promise<SessionRecord | null> {\n const row = getSessionRowById(this.db, params)\n\n if (\n !row ||\n row.audience !== params.audience ||\n row.token_hash !== params.tokenHash ||\n row.revoked_at ||\n new Date(row.expires_at) <= params.now ||\n (row.absolute_expires_at !== null && new Date(row.absolute_expires_at) <= params.now)\n ) {\n return null\n }\n\n return rowToSessionRecord(row)\n }\n\n async renewIfValid(params: {\n readonly projectId: string\n readonly id: string\n readonly audience: AuthSessionAudience\n readonly tokenHash: string\n readonly now: Date\n readonly expiresAt: Date\n }): Promise<SessionRecord | null> {\n return runImmediateTransaction(this.db, () => {\n const now = toIso(params.now)\n const expiresAt = toIso(params.expiresAt)\n const result = this.db\n .query(\n `\n UPDATE auth_sessions\n SET expires_at = MAX(\n expires_at,\n MIN(?, COALESCE(absolute_expires_at, ?))\n ),\n last_seen_at = ?\n WHERE project_id = ?\n AND id = ?\n AND audience = ?\n AND token_hash = ?\n AND revoked_at IS NULL\n AND expires_at > ?\n AND (absolute_expires_at IS NULL OR absolute_expires_at > ?)\n `\n )\n .run(\n expiresAt,\n expiresAt,\n now,\n params.projectId,\n params.id,\n params.audience,\n params.tokenHash,\n now,\n now\n )\n\n return result.changes === 0 ? null : getSessionById(this.db, params)\n })\n }\n\n async revoke(params: {\n readonly projectId: string\n readonly id: string\n readonly revokedAt: Date\n }): Promise<SessionRecord> {\n return runImmediateTransaction(this.db, () => {\n const existing = getSessionRowById(this.db, params)\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Session '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE auth_sessions\n SET revoked_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(params.revokedAt), params.projectId, params.id)\n\n return rowToSessionRecord({\n ...existing,\n revoked_at: toIso(params.revokedAt),\n })\n })\n }\n\n async revokeActiveForUser(params: {\n readonly projectId: string\n readonly userId: string\n readonly audience?: AuthSessionAudience\n readonly revokedAt: Date\n }): Promise<readonly SessionRecord[]> {\n return runImmediateTransaction(this.db, () => revokeActiveSessionsForUser(this.db, params))\n }\n\n async touch(params: {\n readonly projectId: string\n readonly id: string\n readonly lastSeenAt: Date\n }): Promise<SessionRecord> {\n return runImmediateTransaction(this.db, () => {\n requireSessionById(this.db, params)\n\n this.db\n .query(\n `\n UPDATE auth_sessions\n SET last_seen_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(toIso(params.lastSeenAt), params.projectId, params.id)\n\n const updated = getSessionById(this.db, params)\n if (!updated) {\n throw new AuthStorageError(\n \"missing_session\",\n `[Sixb] Session '${params.id}' not found for project '${params.projectId}'.`\n )\n }\n return updated\n })\n }\n}\n",
|
|
28
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n AuthUserStore,\n CreateAuthUserInput,\n ListAuthUsersInput,\n ListAuthUsersResult,\n UpdateAuthUserProfileInput,\n UpdateAuthUserStatusInput,\n UserRecord,\n} from \"@sixb/core/storage\"\nimport { AuthStorageError } from \"@sixb/core/storage\"\nimport type { SqliteAuthUserRow } from \"./rows\"\nimport { rowToUserRecord } from \"./rows\"\nimport {\n appendPagination,\n assertNonEmpty,\n dateOrNow,\n getUserRowByEmail,\n getUserRowById,\n hasEmptyFilter,\n mapUniqueConstraintError,\n normalizeEmail,\n type SqliteValue,\n toIso,\n} from \"./shared\"\n\nexport class SqliteAuthUserStore implements AuthUserStore {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateAuthUserInput): Promise<UserRecord> {\n const id = assertNonEmpty(input.id, \"User id\")\n const projectId = assertNonEmpty(input.projectId, \"Project id\")\n const email = normalizeEmail(input.email)\n\n if (getUserRowById(this.db, { projectId, id })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User '${id}' already exists for project '${projectId}'.`\n )\n }\n\n if (getUserRowByEmail(this.db, { projectId, email })) {\n throw new AuthStorageError(\n \"duplicate_user\",\n `[Sixb] User email '${email}' already exists for project '${projectId}'.`\n )\n }\n\n const createdAt = dateOrNow(input.createdAt)\n const updatedAt = input.updatedAt ? new Date(input.updatedAt) : createdAt\n\n try {\n this.db\n .query(\n `\n INSERT INTO auth_users (\n project_id,\n id,\n email,\n display_name,\n avatar_url,\n status,\n created_at,\n updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n id,\n email,\n input.displayName ?? null,\n input.avatarUrl ?? null,\n input.status ?? \"active\",\n toIso(createdAt),\n toIso(updatedAt)\n )\n } catch (error) {\n mapUniqueConstraintError(\n error,\n \"duplicate_user\",\n `[Sixb] User '${id}' already exists for project '${projectId}'.`\n )\n }\n\n return {\n id,\n projectId,\n email,\n displayName: input.displayName,\n avatarUrl: input.avatarUrl,\n status: input.status ?? \"active\",\n createdAt,\n updatedAt,\n }\n }\n\n async getById(params: {\n readonly projectId: string\n readonly id: string\n }): Promise<UserRecord | null> {\n const row = getUserRowById(this.db, params)\n return row ? rowToUserRecord(row) : null\n }\n\n async getByEmail(params: {\n readonly projectId: string\n readonly email: string\n }): Promise<UserRecord | null> {\n const row = getUserRowByEmail(this.db, params)\n return row ? rowToUserRecord(row) : null\n }\n\n async updateProfile(input: UpdateAuthUserProfileInput): Promise<UserRecord> {\n const existing = getUserRowById(this.db, {\n projectId: input.projectId,\n id: input.id,\n })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n this.db\n .query(\n `\n UPDATE auth_users\n SET display_name = ?,\n avatar_url = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(\n input.displayName ?? null,\n input.avatarUrl ?? null,\n toIso(updatedAt),\n input.projectId,\n input.id\n )\n\n return rowToUserRecord({\n ...existing,\n display_name: input.displayName ?? null,\n avatar_url: input.avatarUrl ?? null,\n updated_at: toIso(updatedAt),\n })\n }\n\n async updateStatus(input: UpdateAuthUserStatusInput): Promise<UserRecord> {\n const existing = getUserRowById(this.db, {\n projectId: input.projectId,\n id: input.id,\n })\n\n if (!existing) {\n throw new AuthStorageError(\n \"missing_user\",\n `[Sixb] User '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n const updatedAt = dateOrNow(input.updatedAt)\n this.db\n .query(\n `\n UPDATE auth_users\n SET status = ?,\n updated_at = ?\n WHERE project_id = ?\n AND id = ?\n `\n )\n .run(input.status, toIso(updatedAt), input.projectId, input.id)\n\n return rowToUserRecord({\n ...existing,\n status: input.status,\n updated_at: toIso(updatedAt),\n })\n }\n\n async list(input: ListAuthUsersInput): Promise<ListAuthUsersResult> {\n if (hasEmptyFilter(input.statuses)) {\n return { users: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM auth_users ${where}`)\n .get(...args) as { readonly count: number }\n\n const queryArgs = [...args]\n const query = appendPagination(\n `\n SELECT *\n FROM auth_users\n ${where}\n ORDER BY created_at ${order}, id ${order}\n `,\n queryArgs,\n input\n )\n const rows = this.db.query(query).all(...queryArgs) as SqliteAuthUserRow[]\n\n return {\n users: rows.map(rowToUserRecord),\n hasMore: (input.offset ?? 0) + rows.length < totalRow.count,\n total: totalRow.count,\n }\n }\n}\n",
|
|
29
|
+
"import {\n type ObjectExpansion,\n type ObjectQuery,\n ObjectQueryExecutionError,\n type ObjectQueryPredicate,\n type ObjectQuerySetOperation,\n type ObjectQuerySortField,\n} from \"@sixb/core\"\n\nexport type SqliteValue = string | number | bigint | boolean | null\n\nexport interface SqliteObjectQueryPageRow {\n object_type_id: string\n primary_id: string\n properties: string\n _cursor_properties?: string\n}\n\nexport interface CompiledObjectQuery {\n sql: string\n args: SqliteValue[]\n totalSql: string\n totalArgs: SqliteValue[]\n order: CompiledOrder\n hasMoreProbe?: CompiledHasMoreProbe\n hasMore(rowCount: number, total?: number): boolean\n trimRows<T>(rows: readonly T[]): readonly T[]\n nextPageToken(rows: readonly SqliteObjectQueryPageRow[], rowCount: number): string | undefined\n}\n\ninterface CompiledHasMoreProbe {\n sql: string\n args: SqliteValue[]\n hasMore(rowCount: number): boolean\n}\n\ninterface CompileContext {\n probeLimit: boolean\n}\n\ninterface CompiledPredicate {\n sql: string\n args: SqliteValue[]\n}\n\ninterface CompiledOrder {\n sql: string\n args: SqliteValue[]\n fields: readonly CompiledOrderField[]\n propertyColumn: string\n}\n\ntype CompiledOrderField =\n | {\n kind: \"property\"\n propertyId: string\n direction: \"asc\" | \"desc\"\n }\n | {\n kind: \"column\"\n column: \"object_type_id\" | \"primary_id\"\n direction: \"asc\" | \"desc\"\n }\n\ninterface EncodedPageToken {\n version: 1\n order: readonly string[]\n values: readonly EncodedCursorValue[]\n}\n\ninterface EncodedCursorValue {\n nullish: boolean\n value?: unknown\n}\n\nconst PAGE_TOKEN_PREFIX = \"keyset:\"\nconst exactContext: CompileContext = { probeLimit: false }\n\n// Fallback fanout cap for a \"many\" expansion that arrives without an explicit\n// limit. The core executor normally bakes a limit in before pushdown; this only\n// bounds the degenerate uncapped case. Mirrors the PostgreSQL compiler.\nconst DEFAULT_EXPANSION_FANOUT = 1_000\n\nexport function compileObjectQuery(\n projectId: string,\n query: ObjectQuery,\n options: { includeTotal?: boolean } = {}\n): CompiledObjectQuery {\n const ctx: CompileContext = { probeLimit: options.includeTotal === false }\n return compileObjectQueryInternal(projectId, query, ctx)\n}\n\nfunction compileObjectQueryInternal(\n projectId: string,\n query: ObjectQuery,\n ctx: CompileContext\n): CompiledObjectQuery {\n switch (query.kind) {\n case \"start\":\n return compileStart(projectId, query)\n case \"filter\":\n return compileFilter(projectId, query.input, query.predicate)\n case \"sort\":\n return compileSort(projectId, query.input, query.fields, ctx)\n case \"limit\":\n return compileLimit(projectId, query.input, query.limit, ctx)\n case \"page\":\n return compilePage(projectId, query.input, query.pageSize, query.pageToken)\n case \"traverse\":\n return compileTraversal(\n projectId,\n query.input,\n query.linkId,\n query.direction,\n query.sourceObjectTypeId\n )\n case \"set\":\n return compileSet(projectId, query.op, query.inputs)\n case \"project\":\n return compileProject(projectId, query.input, query.properties, ctx)\n case \"text\":\n return compileText(\n projectId,\n query.input,\n query.query,\n query.fields,\n query.fieldsByObjectType\n )\n case \"expand\":\n return compileExpand(projectId, query.input, query.expansions)\n case \"vector\":\n throw new Error(`[Sixb] SQLite object storage does not support query node '${query.kind}'`)\n }\n}\n\nfunction compileStart(\n projectId: string,\n query: Extract<ObjectQuery, { kind: \"start\" }>\n): CompiledObjectQuery {\n if (query.includeSubtypes === true) {\n throw new Error(\"[Sixb] SQLite object storage does not support start.includeSubtypes\")\n }\n\n const order = compileOrder(identityOrderFields())\n const sql = `\n SELECT *, properties AS _cursor_properties\n FROM objects\n WHERE project_id = ? AND object_type_id = ?\n ORDER BY ${order.sql}\n `\n const args = [projectId, query.objectTypeId, ...order.args]\n\n return {\n sql,\n args,\n totalSql: \"SELECT COUNT(*) as total FROM objects WHERE project_id = ? AND object_type_id = ?\",\n totalArgs: [projectId, query.objectTypeId],\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileFilter(\n projectId: string,\n inputQuery: ObjectQuery,\n predicateNode: ObjectQueryPredicate\n): CompiledObjectQuery {\n const predicate = compilePredicate(predicateNode)\n return compileWhere(projectId, inputQuery, predicate)\n}\n\nfunction compileWhere(\n projectId: string,\n inputQuery: ObjectQuery,\n predicate: CompiledPredicate\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const sql = `\n SELECT *\n FROM (${input.sql}) AS input\n WHERE ${predicate.sql}\n ORDER BY ${input.order.sql}\n `\n\n return {\n sql,\n args: [...input.args, ...predicate.args, ...input.order.args],\n totalSql: `\n SELECT COUNT(*) as total\n FROM (${input.sql}) AS input\n WHERE ${predicate.sql}\n `,\n totalArgs: [...input.args, ...predicate.args],\n order: input.order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileText(\n projectId: string,\n inputQuery: ObjectQuery,\n query: string,\n fields: readonly string[] | undefined,\n fieldsByObjectType: Readonly<Record<string, readonly string[]>> | undefined\n): CompiledObjectQuery {\n const predicate =\n fields && fields.length > 0\n ? compileTextPredicate(query, fields)\n : compileScopedTextPredicate(query, fieldsByObjectType)\n\n if (!predicate) {\n throw new Error(\"[Sixb] SQLite object text search requires fields or resolved text defaults\")\n }\n return compileWhere(projectId, inputQuery, predicate)\n}\n\nfunction compileSort(\n projectId: string,\n inputQuery: ObjectQuery,\n fields: readonly ObjectQuerySortField[],\n ctx: CompileContext\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const probeInput =\n ctx.probeLimit && needsLimitProbe(inputQuery)\n ? compileObjectQueryInternal(projectId, inputQuery, ctx)\n : undefined\n const order = compileOrder(sortOrderFields(fields))\n\n return {\n sql: `\n SELECT\n input.project_id,\n input.object_type_id,\n input.primary_id,\n input.properties,\n input.properties AS _cursor_properties,\n input.created_at,\n input.updated_at,\n input.version,\n input.last_commit_id\n FROM (${input.sql}) AS input\n ORDER BY ${order.sql}\n `,\n args: [...input.args, ...order.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order,\n hasMoreProbe: probeInput ? hasMoreProbeFor(probeInput) : input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\nfunction compileLimit(\n projectId: string,\n inputQuery: ObjectQuery,\n rawLimit: number,\n ctx: CompileContext\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const limit = Math.max(0, rawLimit)\n const rowLimit = ctx.probeLimit ? limit + 1 : limit\n\n return {\n sql: `\n SELECT *\n FROM (${input.sql}) AS input\n ORDER BY ${input.order.sql}\n LIMIT ?\n `,\n args: [...input.args, ...input.order.args, rowLimit],\n totalSql: `\n SELECT COUNT(*) as total\n FROM (${input.sql}) AS input\n `,\n totalArgs: input.args,\n order: input.order,\n hasMore: (rowCount, total) =>\n total === undefined ? ctx.probeLimit && rowCount > limit : limit < total,\n trimRows: ctx.probeLimit ? (rows) => rows.slice(0, limit) : identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compilePage(\n projectId: string,\n inputQuery: ObjectQuery,\n rawPageSize: number,\n pageToken: string | undefined\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const pageSize = Math.max(0, rawPageSize)\n const cursor = pageToken ? decodePageToken(pageToken, input.order.fields) : undefined\n const cursorPredicate = cursor\n ? compileKeysetPredicate(input.order.fields, cursor, input.order.propertyColumn)\n : undefined\n const whereSql = cursorPredicate ? `WHERE ${cursorPredicate.sql}` : \"\"\n\n return {\n sql: `\n SELECT *\n FROM (${input.sql}) AS input\n ${whereSql}\n ORDER BY ${input.order.sql}\n LIMIT ?\n `,\n args: [...input.args, ...(cursorPredicate?.args ?? []), ...input.order.args, pageSize + 1],\n totalSql: `\n SELECT COUNT(*) as total\n FROM (${input.sql}) AS input\n `,\n totalArgs: input.args,\n order: input.order,\n hasMore: (rowCount) => rowCount > pageSize,\n trimRows: (rows) => rows.slice(0, pageSize),\n nextPageToken: (rows, rowCount) => {\n if (rowCount <= pageSize || rows.length === 0) return undefined\n return encodePageToken(rows[rows.length - 1], input.order.fields)\n },\n }\n}\n\nfunction compileTraversal(\n projectId: string,\n inputQuery: ObjectQuery,\n linkId: string,\n direction: \"outgoing\" | \"incoming\",\n sourceObjectTypeId?: string\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const outputAlias = direction === \"outgoing\" ? \"target_object\" : \"source_object\"\n const joinSql =\n direction === \"outgoing\"\n ? `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.source_type_id = input.object_type_id\n AND edge.source_id = input.primary_id\n AND edge.link_id = ?\n JOIN objects AS target_object\n ON target_object.project_id = edge.project_id\n AND target_object.object_type_id = edge.target_type_id\n AND target_object.primary_id = edge.target_id\n `\n : `\n JOIN links AS edge\n ON edge.project_id = input.project_id\n AND edge.target_type_id = input.object_type_id\n AND edge.target_id = input.primary_id\n AND edge.link_id = ?${sourceObjectTypeId === undefined ? \"\" : \"\\n AND edge.source_type_id = ?\"}\n JOIN objects AS source_object\n ON source_object.project_id = edge.project_id\n AND source_object.object_type_id = edge.source_type_id\n AND source_object.primary_id = edge.source_id\n `\n const order = compileOrder(identityOrderFields())\n const qualifiedOrder = compileOrder(identityOrderFields(), outputAlias)\n const sql = `\n SELECT DISTINCT ${outputAlias}.*, ${outputAlias}.properties AS _cursor_properties\n FROM (${input.sql}) AS input\n ${joinSql}\n ORDER BY ${qualifiedOrder.sql}\n `\n const args = [\n ...input.args,\n linkId,\n ...(sourceObjectTypeId === undefined ? [] : [sourceObjectTypeId]),\n ...qualifiedOrder.args,\n ]\n\n return {\n sql,\n args,\n totalSql: `SELECT COUNT(*) as total FROM (${sql}) AS traversed`,\n totalArgs: args,\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\n/** Correlation handle for an expansion: the parent row's identity columns. */\ninterface ExpansionParent {\n project: string\n type: string\n id: string\n}\n\n// `expand` attaches linked objects to each result row without changing which\n// objects match (unlike `traverse`, which pivots to the targets). Each expansion\n// becomes a correlated subquery that hydrates its links into a JSON value, and\n// all expansions are folded into one `_expand` object column the row mapper reads\n// back. The input set is otherwise untouched, so pagination/order pass through.\nfunction compileExpand(\n projectId: string,\n inputQuery: ObjectQuery,\n expansions: readonly ObjectExpansion[]\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, exactContext)\n const expand = compileExpansionsObject(\n expansions,\n { project: \"input.project_id\", type: \"input.object_type_id\", id: \"input.primary_id\" },\n \"\"\n )\n const inputOrder = compileOrder(input.order.fields, \"input\", \"input._cursor_properties\")\n const sql = `\n SELECT input.*, ${expand.sql} AS _expand\n FROM (${input.sql}) AS input\n ORDER BY ${inputOrder.sql}\n `\n\n return {\n sql,\n args: [...expand.args, ...input.args, ...inputOrder.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order: input.order,\n hasMoreProbe: input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\n// `json_object(linkId, value, ...)` over a set of expansions sharing one parent.\n// Link ids are user data, so they ride as parameters. Each value is a correlated\n// subquery whose JSON subtype is lost crossing the subquery boundary, so it is\n// re-parsed with `json(...)` to embed as nested JSON rather than a quoted string.\n// Used both for the outer `_expand` column and for each child's nested `links`.\nfunction compileExpansionsObject(\n expansions: readonly ObjectExpansion[],\n parent: ExpansionParent,\n pathPrefix: string\n): CompiledPredicate {\n const parts: string[] = []\n const args: SqliteValue[] = []\n expansions.forEach((expansion, index) => {\n const path = pathPrefix === \"\" ? `${index}` : `${pathPrefix}_${index}`\n const value = compileExpansionValue(expansion, parent, path)\n parts.push(\"?\", `json(${value.sql})`)\n args.push(expansion.linkId, ...value.args)\n })\n return { sql: `json_object(${parts.join(\", \")})`, args }\n}\n\n// One expansion's hydrated value. `row_number()` numbers a parent's links by the\n// order from `compileExpansionOrder` (the expansion's `orderBy` against the target\n// object's properties, then an identity tiebreak); `WHERE _ord <= N` keeps the\n// top-N per parent in-DB; each retained neighbour becomes a JSON object; and the\n// value is an ordered array (\"many\") or the first element or null (\"one\"). The\n// cardinality is core-resolved before pushdown.\nfunction compileExpansionValue(\n expansion: ObjectExpansion,\n parent: ExpansionParent,\n path: string\n): CompiledPredicate {\n const edge = `edge_${path}`\n const target = `tgt_${path}`\n const ranked = `ranked_${path}`\n const incoming = expansion.direction === \"incoming\"\n // The hydrated neighbour is the link target (outgoing) or source (incoming);\n // the parent sits on the opposite end, mirroring `compileTraversal`.\n const neighborType = incoming ? `${edge}.source_type_id` : `${edge}.target_type_id`\n const neighborId = incoming ? `${edge}.source_id` : `${edge}.target_id`\n const parentType = incoming ? `${edge}.target_type_id` : `${edge}.source_type_id`\n const parentId = incoming ? `${edge}.target_id` : `${edge}.source_id`\n\n const child = compileExpansionChildJson(expansion, edge, target, path)\n const order = compileExpansionOrder(expansion, target, neighborType, neighborId)\n\n const whereParts = [\n `${edge}.project_id = ${parent.project}`,\n `${parentType} = ${parent.type}`,\n `${parentId} = ${parent.id}`,\n `${edge}.link_id = ?`,\n ]\n const whereArgs: SqliteValue[] = [expansion.linkId]\n if (incoming && expansion.sourceObjectTypeId !== undefined) {\n whereParts.push(`${edge}.source_type_id = ?`)\n whereArgs.push(expansion.sourceObjectTypeId)\n }\n\n const inner = `\n SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord\n FROM links AS ${edge}\n JOIN objects AS ${target}\n ON ${target}.project_id = ${edge}.project_id\n AND ${target}.object_type_id = ${neighborType}\n AND ${target}.primary_id = ${neighborId}\n WHERE ${whereParts.join(\" AND \")}\n `\n const innerArgs = [...child.args, ...order.args, ...whereArgs]\n\n if (expansion.cardinality === \"one\") {\n return {\n sql: `(SELECT ${ranked}.elem FROM (${inner}) AS ${ranked} WHERE ${ranked}._ord = 1)`,\n args: innerArgs,\n }\n }\n\n // The fanout cap is baked into `limit` by the core executor before pushdown.\n // Each element is re-parsed with `json(...)` so the aggregate embeds objects\n // rather than the quoted JSON text the subquery column hands back.\n const limit = expansion.limit ?? DEFAULT_EXPANSION_FANOUT\n return {\n sql: `COALESCE((SELECT json_group_array(json(${ranked}.elem) ORDER BY ${ranked}._ord) FROM (${inner}) AS ${ranked} WHERE ${ranked}._ord <= ?), '[]')`,\n args: [...innerArgs, limit],\n }\n}\n\n// Build one hydrated neighbour as an `ExpandedObjectRow`-shaped JSON object. The\n// JSON-valued columns (`properties`, the edge's `linkProperties`) are re-parsed\n// with `json(...)` so they embed as JSON rather than strings; `linkProperties`\n// always rides along (the mapper drops it when null/empty), and nested expansions\n// recurse under `links`, correlated on this neighbour.\nfunction compileExpansionChildJson(\n expansion: ObjectExpansion,\n edge: string,\n target: string,\n path: string\n): CompiledPredicate {\n const fields = [\n `'projectId', ${target}.project_id`,\n `'objectTypeId', ${target}.object_type_id`,\n `'primaryId', ${target}.primary_id`,\n `'properties', json(${target}.properties)`,\n `'createdAt', ${target}.created_at`,\n `'updatedAt', ${target}.updated_at`,\n `'version', ${target}.version`,\n `'lastCommitId', ${target}.last_commit_id`,\n `'linkProperties', json(${edge}.properties)`,\n ]\n const args: SqliteValue[] = []\n\n if (expansion.expand && expansion.expand.length > 0) {\n const nested = compileExpansionsObject(\n expansion.expand,\n {\n project: `${target}.project_id`,\n type: `${target}.object_type_id`,\n id: `${target}.primary_id`,\n },\n path\n )\n fields.push(`'links', ${nested.sql}`)\n args.push(...nested.args)\n }\n\n return { sql: `json_object(${fields.join(\", \")})`, args }\n}\n\n// Order a parent's links the way the fallback's per-parent trim does: each\n// property sorts nulls last with the requested direction (against the neighbour's\n// JSON properties), then a deterministic identity tiebreak on the neighbour.\nfunction compileExpansionOrder(\n expansion: ObjectExpansion,\n target: string,\n neighborType: string,\n neighborId: string\n): CompiledPredicate {\n const propertyColumn = `${target}.properties`\n const clauses: string[] = []\n const args: SqliteValue[] = []\n\n for (const field of expansion.orderBy ?? []) {\n // Relevance is a no-op in the fallback comparator; mirror that by skipping it.\n if (field.kind !== \"property\") continue\n if (field.scalarKind === \"decimal\") {\n throw new ObjectQueryExecutionError(\n \"exact_decimal_not_supported\",\n \"SQLite object storage cannot push down exact decimal expansion sorting\",\n \"$.expand.orderBy\"\n )\n }\n const direction = field.direction === \"desc\" ? \"DESC\" : \"ASC\"\n const path = jsonPath(field.propertyId)\n clauses.push(\n `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END ASC`,\n `${jsonValueExpression(propertyColumn)} ${direction}`\n )\n args.push(path, path, path)\n }\n\n clauses.push(`${neighborType} ASC`, `${neighborId} ASC`)\n return { sql: clauses.join(\", \"), args }\n}\n\nfunction compileSet(\n projectId: string,\n op: ObjectQuerySetOperation,\n inputs: readonly ObjectQuery[]\n): CompiledObjectQuery {\n if (inputs.length === 0) {\n const order = compileOrder(identityOrderFields())\n return {\n sql: `\n SELECT *\n FROM objects\n WHERE 1 = 0\n ORDER BY ${order.sql}\n `,\n args: order.args,\n totalSql: \"SELECT 0 as total\",\n totalArgs: [],\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n }\n\n const compiledInputs = inputs.map((input) =>\n compileObjectQueryInternal(projectId, input, exactContext)\n )\n const identities = compileSetIdentities(op, compiledInputs)\n const order = compileOrder(identityOrderFields())\n const selectedOrder = compileOrder(identityOrderFields(), \"selected\")\n const sql = `\n SELECT selected.*, selected.properties AS _cursor_properties\n FROM (${identities.sql}) AS ids\n JOIN objects AS selected\n ON selected.project_id = ?\n AND selected.object_type_id = ids.object_type_id\n AND selected.primary_id = ids.primary_id\n ORDER BY ${selectedOrder.sql}\n `\n const args = [...identities.args, projectId, ...selectedOrder.args]\n\n return {\n sql,\n args,\n totalSql: `SELECT COUNT(*) as total FROM (${identities.sql}) AS ids`,\n totalArgs: identities.args,\n order,\n hasMore: () => false,\n trimRows: identityRows,\n nextPageToken: () => undefined,\n }\n}\n\nfunction compileProject(\n projectId: string,\n inputQuery: ObjectQuery,\n properties: readonly string[] | undefined,\n ctx: CompileContext\n): CompiledObjectQuery {\n const input = compileObjectQueryInternal(projectId, inputQuery, ctx)\n if (!properties) return input\n\n const projection = compileProjectionExpression(properties)\n const inputOrder = compileOrder(input.order.fields, \"input\", \"input._cursor_properties\")\n const outputOrder = compileOrder(input.order.fields, undefined, \"_cursor_properties\")\n\n return {\n sql: `\n SELECT\n input.project_id,\n input.object_type_id,\n input.primary_id,\n ${projection.sql} AS properties,\n input._cursor_properties AS _cursor_properties,\n input.created_at,\n input.updated_at,\n input.version,\n input.last_commit_id\n FROM (${input.sql}) AS input\n ORDER BY ${inputOrder.sql}\n `,\n args: [...projection.args, ...input.args, ...inputOrder.args],\n totalSql: input.totalSql,\n totalArgs: input.totalArgs,\n order: outputOrder,\n hasMoreProbe: input.hasMoreProbe,\n hasMore: input.hasMore,\n trimRows: input.trimRows,\n nextPageToken: input.nextPageToken,\n }\n}\n\nfunction needsLimitProbe(query: ObjectQuery): boolean {\n switch (query.kind) {\n case \"limit\":\n return true\n case \"project\":\n case \"sort\":\n return needsLimitProbe(query.input)\n default:\n return false\n }\n}\n\nfunction hasMoreProbeFor(compiled: CompiledObjectQuery): CompiledHasMoreProbe {\n return (\n compiled.hasMoreProbe ?? {\n sql: compiled.sql,\n args: compiled.args,\n hasMore: (rowCount) => compiled.hasMore(rowCount, undefined),\n }\n )\n}\n\nfunction compileSetIdentities(\n op: ObjectQuerySetOperation,\n inputs: readonly CompiledObjectQuery[]\n): CompiledPredicate {\n const operator = op === \"union\" ? \"UNION\" : op === \"intersect\" ? \"INTERSECT\" : \"EXCEPT\"\n const identitySqls = inputs.map(\n (input) => `SELECT object_type_id, primary_id FROM (${input.sql}) AS input`\n )\n\n return {\n sql: identitySqls.join(` ${operator} `),\n args: inputs.flatMap((input) => input.args),\n }\n}\n\nfunction compileProjectionExpression(properties: readonly string[]): CompiledPredicate {\n if (properties.length === 0) return { sql: \"json('{}')\", args: [] }\n\n return {\n sql: `\n COALESCE(\n (\n SELECT json_group_object(projected.key, projected.value)\n FROM json_each(input.properties) AS projected\n WHERE projected.key IN (${properties.map(() => \"?\").join(\", \")})\n ),\n json('{}')\n )\n `,\n args: [...properties],\n }\n}\n\nfunction compilePredicate(predicate: ObjectQueryPredicate): CompiledPredicate {\n if (\n \"scalarKind\" in predicate &&\n predicate.scalarKind === \"decimal\" &&\n (predicate.op === \"lt\" ||\n predicate.op === \"lte\" ||\n predicate.op === \"gt\" ||\n predicate.op === \"gte\")\n ) {\n throw new ObjectQueryExecutionError(\n \"exact_decimal_not_supported\",\n \"SQLite object storage cannot push down exact decimal predicates\",\n \"$.predicate\"\n )\n }\n\n switch (predicate.op) {\n case \"and\":\n case \"or\": {\n const items = predicate.items.map(compilePredicate)\n const joiner = predicate.op === \"and\" ? \" AND \" : \" OR \"\n return {\n sql: `(${items.map((item) => item.sql).join(joiner)})`,\n args: items.flatMap((item) => item.args),\n }\n }\n case \"not\": {\n const item = compilePredicate(predicate.item)\n return negatePredicate(item)\n }\n case \"eq\":\n return compileEqualityPredicate(predicate.propertyId, \"eq\", predicate.value)\n case \"neq\":\n return compileEqualityPredicate(predicate.propertyId, \"neq\", predicate.value)\n case \"lt\":\n case \"lte\":\n case \"gt\":\n case \"gte\": {\n const op = sqlComparisonOperator(predicate.op)\n return {\n sql: `${jsonValueExpression()} ${op} ?`,\n args: [jsonPath(predicate.propertyId), sqlValue(predicate.value)],\n }\n }\n case \"in\":\n return compileInPredicate(predicate.propertyId, predicate.values)\n case \"exists\": {\n const sql = `${jsonTypeExpression()} IS NOT NULL`\n const item: CompiledPredicate = { sql, args: [jsonPath(predicate.propertyId)] }\n return predicate.value ? item : negatePredicate(item)\n }\n case \"contains\":\n return compileContainsPredicate(predicate.propertyId, predicate.value)\n }\n}\n\nfunction negatePredicate(predicate: CompiledPredicate): CompiledPredicate {\n return {\n sql: `(NOT COALESCE((${predicate.sql}), 0))`,\n args: predicate.args,\n }\n}\n\nfunction compileEqualityPredicate(\n propertyId: string,\n op: \"eq\" | \"neq\",\n value: unknown\n): CompiledPredicate {\n const path = jsonPath(propertyId)\n if (value === null) {\n const sql = `${jsonTypeExpression()} = 'null'`\n const item: CompiledPredicate = { sql, args: [path] }\n return op === \"eq\" ? item : negatePredicate(item)\n }\n\n if (op === \"eq\") {\n return {\n sql: `${jsonValueExpression()} = ?`,\n args: [path, sqlValue(value)],\n }\n }\n\n // JS predicate semantics treat missing/null properties as not equal to any\n // non-null scalar. SQL three-valued null logic needs those cases explicit.\n return {\n sql: `(${jsonTypeExpression()} IS NULL OR ${jsonTypeExpression()} = 'null' OR ${jsonValueExpression()} != ?)`,\n args: [path, path, path, sqlValue(value)],\n }\n}\n\nfunction compileInPredicate(propertyId: string, values: readonly unknown[]): CompiledPredicate {\n if (values.length === 0) return { sql: \"0 = 1\", args: [] }\n\n const path = jsonPath(propertyId)\n const nonNullValues = values.filter((value) => value !== null)\n const clauses: string[] = []\n const args: SqliteValue[] = []\n\n if (values.length !== nonNullValues.length) {\n clauses.push(`${jsonTypeExpression()} = 'null'`)\n args.push(path)\n }\n\n if (nonNullValues.length > 0) {\n clauses.push(`${jsonValueExpression()} IN (${nonNullValues.map(() => \"?\").join(\", \")})`)\n args.push(path, ...nonNullValues.map(sqlValue))\n }\n\n return {\n sql: `(${clauses.join(\" OR \")})`,\n args,\n }\n}\n\nfunction compileContainsPredicate(propertyId: string, value: unknown): CompiledPredicate {\n const path = jsonPath(propertyId)\n const clauses: string[] = []\n const args: SqliteValue[] = []\n\n if (typeof value === \"string\") {\n clauses.push(`(${jsonTypeExpression()} = 'text' AND instr(${jsonValueExpression()}, ?) > 0)`)\n args.push(path, path, value)\n }\n\n clauses.push(\n `(${jsonTypeExpression()} = 'array' AND EXISTS (SELECT 1 FROM json_each(properties, ?) AS item WHERE item.value IS ?))`\n )\n args.push(path, path, sqlValue(value))\n\n if (typeof value === \"string\") {\n clauses.push(\n `(${jsonTypeExpression()} = 'object' AND EXISTS (SELECT 1 FROM json_each(properties, ?) AS item WHERE item.key = ?))`\n )\n args.push(path, path, value)\n }\n\n return { sql: `(${clauses.join(\" OR \")})`, args }\n}\n\nfunction compileTextPredicate(query: string, fields: readonly string[]): CompiledPredicate {\n const terms = tokenize(query)\n if (terms.length === 0) return { sql: \"0 = 1\", args: [] }\n\n const clauses = terms.map(() => {\n const fieldClauses = fields.map(\n () => `instr(lower(COALESCE(CAST(${jsonValueExpression()} AS TEXT), '')), ?) > 0`\n )\n return `(${fieldClauses.join(\" OR \")})`\n })\n const args = terms.flatMap((term) => fields.flatMap((field) => [jsonPath(field), term]))\n\n return { sql: `(${clauses.join(\" AND \")})`, args }\n}\n\nfunction compileScopedTextPredicate(\n query: string,\n fieldsByObjectType: Readonly<Record<string, readonly string[]>> | undefined\n): CompiledPredicate | null {\n const scopedPredicates: CompiledPredicate[] = []\n\n for (const [objectTypeId, fields] of Object.entries(fieldsByObjectType ?? {})) {\n if (fields.length === 0) continue\n const predicate = compileTextPredicate(query, fields)\n scopedPredicates.push({\n sql: `(object_type_id = ? AND ${predicate.sql})`,\n args: [objectTypeId, ...predicate.args],\n })\n }\n\n if (scopedPredicates.length === 0) return null\n\n return {\n sql: `(${scopedPredicates.map((predicate) => predicate.sql).join(\" OR \")})`,\n args: scopedPredicates.flatMap((predicate) => predicate.args),\n }\n}\n\nfunction compileOrder(\n fields: readonly CompiledOrderField[],\n qualifier?: string,\n propertyColumn = \"properties\"\n): CompiledOrder {\n const clauses: string[] = []\n const args: SqliteValue[] = []\n\n for (const field of fields) {\n if (field.kind === \"column\") {\n clauses.push(`${columnExpression(field.column, qualifier)} ${field.direction.toUpperCase()}`)\n continue\n }\n\n const direction = field.direction === \"desc\" ? \"DESC\" : \"ASC\"\n const path = jsonPath(field.propertyId)\n clauses.push(\n `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END ASC`,\n `${jsonValueExpression(propertyColumn)} ${direction}`\n )\n args.push(path, path, path)\n }\n\n return { sql: clauses.join(\", \"), args, fields, propertyColumn }\n}\n\nfunction sortOrderFields(fields: readonly ObjectQuerySortField[]): readonly CompiledOrderField[] {\n const orderFields: CompiledOrderField[] = []\n for (const field of fields) {\n if (field.kind !== \"property\") {\n throw new Error(\"[Sixb] SQLite object storage does not support relevance sorting\")\n }\n if (field.scalarKind === \"decimal\") {\n throw new ObjectQueryExecutionError(\n \"exact_decimal_not_supported\",\n \"SQLite object storage cannot push down exact decimal sorting\",\n \"$.sort\"\n )\n }\n\n orderFields.push({\n kind: \"property\",\n propertyId: field.propertyId,\n direction: field.direction === \"desc\" ? \"desc\" : \"asc\",\n })\n }\n orderFields.push(...identityOrderFields())\n return orderFields\n}\n\nfunction identityOrderFields(): readonly CompiledOrderField[] {\n return [\n { kind: \"column\", column: \"object_type_id\", direction: \"asc\" },\n { kind: \"column\", column: \"primary_id\", direction: \"asc\" },\n ]\n}\n\nfunction compileKeysetPredicate(\n fields: readonly CompiledOrderField[],\n cursor: readonly EncodedCursorValue[],\n propertyColumn = \"properties\"\n): CompiledPredicate {\n const disjuncts: CompiledPredicate[] = []\n\n for (let index = 0; index < fields.length; index += 1) {\n const equalityPredicates = fields\n .slice(0, index)\n .map((field, equalityIndex) =>\n compileFieldEquality(field, cursor[equalityIndex], propertyColumn)\n )\n const advancePredicate = compileFieldAfter(fields[index], cursor[index], propertyColumn)\n if (!advancePredicate) continue\n\n const parts = [...equalityPredicates, advancePredicate]\n disjuncts.push({\n sql: `(${parts.map((part) => part.sql).join(\" AND \")})`,\n args: parts.flatMap((part) => part.args),\n })\n }\n\n if (disjuncts.length === 0) return { sql: \"0 = 1\", args: [] }\n\n return {\n sql: `(${disjuncts.map((part) => part.sql).join(\" OR \")})`,\n args: disjuncts.flatMap((part) => part.args),\n }\n}\n\nfunction compileFieldEquality(\n field: CompiledOrderField,\n cursor: EncodedCursorValue,\n propertyColumn = \"properties\"\n): CompiledPredicate {\n if (field.kind === \"column\") {\n return {\n sql: `${columnExpression(field.column)} = ?`,\n args: [sqlValue(cursor.value)],\n }\n }\n\n const path = jsonPath(field.propertyId)\n if (cursor.nullish) {\n return {\n sql: `(${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null')`,\n args: [path, path],\n }\n }\n\n return {\n sql: `(${jsonTypeExpression(propertyColumn)} IS NOT NULL AND ${jsonTypeExpression(propertyColumn)} != 'null' AND ${jsonValueExpression(propertyColumn)} = ?)`,\n args: [path, path, path, sqlValue(cursor.value)],\n }\n}\n\nfunction compileFieldAfter(\n field: CompiledOrderField,\n cursor: EncodedCursorValue,\n propertyColumn = \"properties\"\n): CompiledPredicate | null {\n if (field.kind === \"column\") {\n return {\n sql: `${columnExpression(field.column)} ${field.direction === \"desc\" ? \"<\" : \">\"} ?`,\n args: [sqlValue(cursor.value)],\n }\n }\n\n if (cursor.nullish) return null\n\n const path = jsonPath(field.propertyId)\n const rankSql = `CASE WHEN ${jsonTypeExpression(propertyColumn)} IS NULL OR ${jsonTypeExpression(propertyColumn)} = 'null' THEN 1 ELSE 0 END`\n const valueOperator = field.direction === \"desc\" ? \"<\" : \">\"\n\n return {\n sql: `(${rankSql} > 0 OR (${rankSql} = 0 AND ${jsonValueExpression(propertyColumn)} ${valueOperator} ?))`,\n args: [path, path, path, path, path, sqlValue(cursor.value)],\n }\n}\n\nfunction encodePageToken(\n row: SqliteObjectQueryPageRow,\n fields: readonly CompiledOrderField[]\n): string {\n const properties = JSON.parse(row._cursor_properties ?? row.properties) as Record<string, unknown>\n const token: EncodedPageToken = {\n version: 1,\n order: fields.map(orderFieldKey),\n values: fields.map((field) => cursorValueForField(row, properties, field)),\n }\n return `${PAGE_TOKEN_PREFIX}${Buffer.from(JSON.stringify(token)).toString(\"base64url\")}`\n}\n\nfunction decodePageToken(\n token: string,\n fields: readonly CompiledOrderField[]\n): readonly EncodedCursorValue[] {\n if (!token.startsWith(PAGE_TOKEN_PREFIX)) {\n throwInvalidPageToken(\"Invalid SQLite object query page token\")\n }\n\n const raw = token.slice(PAGE_TOKEN_PREFIX.length)\n let decoded: unknown\n try {\n decoded = JSON.parse(Buffer.from(raw, \"base64url\").toString(\"utf8\"))\n } catch {\n throwInvalidPageToken(\"Invalid SQLite object query page token\")\n }\n\n if (!isEncodedPageToken(decoded)) {\n throwInvalidPageToken(\"Invalid SQLite object query page token\")\n }\n\n const expectedOrder = fields.map(orderFieldKey)\n if (\n decoded.order.length !== expectedOrder.length ||\n decoded.order.some((field, index) => field !== expectedOrder[index])\n ) {\n throwInvalidPageToken(\"SQLite object query page token does not match query order\")\n }\n\n return decoded.values\n}\n\nfunction throwInvalidPageToken(message: string): never {\n throw new ObjectQueryExecutionError(\"invalid_page_token\", message, \"$.pageToken\")\n}\n\nfunction isEncodedPageToken(value: unknown): value is EncodedPageToken {\n if (!isPlainObject(value)) return false\n if (value.version !== 1) return false\n if (!Array.isArray(value.order) || value.order.some((item) => typeof item !== \"string\")) {\n return false\n }\n if (!Array.isArray(value.values)) return false\n return value.values.every(\n (item) =>\n isPlainObject(item) &&\n typeof item.nullish === \"boolean\" &&\n (item.nullish || Object.hasOwn(item, \"value\"))\n )\n}\n\nfunction cursorValueForField(\n row: SqliteObjectQueryPageRow,\n properties: Record<string, unknown>,\n field: CompiledOrderField\n): EncodedCursorValue {\n const value =\n field.kind === \"column\"\n ? field.column === \"object_type_id\"\n ? row.object_type_id\n : row.primary_id\n : properties[field.propertyId]\n\n return value === null || value === undefined ? { nullish: true } : { nullish: false, value }\n}\n\nfunction orderFieldKey(field: CompiledOrderField): string {\n return field.kind === \"column\"\n ? `column:${field.column}:${field.direction}`\n : `property:${field.propertyId}:${field.direction}`\n}\n\nfunction columnExpression(column: \"object_type_id\" | \"primary_id\", qualifier?: string): string {\n return qualifier ? `${qualifier}.${column}` : column\n}\n\nfunction jsonValueExpression(column = \"properties\"): string {\n return `json_extract(${column}, ?)`\n}\n\nfunction jsonTypeExpression(column = \"properties\"): string {\n return `json_type(${column}, ?)`\n}\n\nfunction jsonPath(propertyId: string): string {\n return `$.\"${propertyId.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`\n}\n\nfunction sqlValue(value: unknown): SqliteValue {\n if (value instanceof Date) return value.toISOString()\n if (typeof value === \"boolean\") return value ? 1 : 0\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"bigint\" ||\n value === null\n ) {\n return value\n }\n return JSON.stringify(value)\n}\n\nfunction tokenize(query: string): string[] {\n return query\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .filter((term) => term.length > 0)\n}\n\nfunction sqlComparisonOperator(op: \"lt\" | \"lte\" | \"gt\" | \"gte\"): \"<\" | \"<=\" | \">\" | \">=\" {\n switch (op) {\n case \"lt\":\n return \"<\"\n case \"lte\":\n return \"<=\"\n case \"gt\":\n return \">\"\n case \"gte\":\n return \">=\"\n }\n}\n\nfunction identityRows<T>(rows: readonly T[]): readonly T[] {\n return rows\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n",
|
|
30
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { ObjectQuery } from \"@sixb/core\"\nimport type {\n CountObjectsInput,\n CountObjectsResult,\n ExistsObjectsInput,\n ExistsObjectsResult,\n ExpandedLinkValue,\n ExpandedObjectRow,\n FacetObjectsInput,\n FacetObjectsResult,\n LinkDirection,\n ObjectFacetRequest,\n ObjectLinkRow,\n ObjectQueryCapabilities,\n ObjectRow,\n ObjectRowLinks,\n ObjectStorage,\n QueryObjectsInput,\n QueryObjectsResult,\n} from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport { type CompiledObjectQuery, compileObjectQuery } from \"./object-query-compiler\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteObjectStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nconst SQLITE_OBJECT_QUERY_CAPABILITIES: ObjectQueryCapabilities = {\n queryObjects: true,\n countObjects: true,\n existsObjects: true,\n facetObjects: true,\n nodes: {\n start: true,\n filter: true,\n text: true,\n sort: true,\n limit: true,\n page: true,\n traverse: true,\n set: true,\n project: true,\n expand: true,\n },\n predicateOps: {\n and: true,\n or: true,\n not: true,\n eq: true,\n neq: true,\n lt: true,\n lte: true,\n gt: true,\n gte: true,\n in: true,\n exists: true,\n contains: true,\n },\n sortKinds: {\n property: true,\n },\n traversalDirections: {\n outgoing: true,\n incoming: true,\n },\n setOps: {\n union: true,\n intersect: true,\n subtract: true,\n },\n scalarOperations: {\n string: { equality: true, ordering: true },\n uuid: { equality: true, ordering: true },\n boolean: { equality: true },\n integer: { equality: true, ordering: true },\n double: { equality: true, ordering: true },\n decimal: { equality: true },\n date: { equality: true, ordering: true },\n timestamp: { equality: true, ordering: true },\n },\n limits: {\n totalCount: true,\n stablePageTokens: true,\n },\n notes: [\n \"SQLite object query pushdown supports start/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.\",\n \"expand hydrates linked objects in-database (top-N per parent via row_number() + json_group_array); core resolves each expansion's cardinality before pushdown, and a mixed/unresolved one stays on the fallback.\",\n \"Ordered decimal predicates and sorting use the bounded core fallback because SQLite has no native exact decimal type; canonical decimal equality remains pushdown-safe.\",\n \"Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases.\",\n ],\n}\n\n/**\n * SQLite-based ObjectStorage implementation.\n *\n * Stores object projections and links. V1 object-query IR pushdown covers the\n * scalar JSON-property and link-traversal subset declared by queryCapabilities().\n */\nexport class SqliteObjectStorage implements ObjectStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteObjectStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n queryCapabilities(): ObjectQueryCapabilities {\n return SQLITE_OBJECT_QUERY_CAPABILITIES\n }\n\n async queryObjects(params: QueryObjectsInput): Promise<QueryObjectsResult> {\n const compiled = compileObjectQuery(params.projectId, params.query, {\n includeTotal: params.includeTotal,\n })\n const total = params.includeTotal === false ? undefined : readTotal(this.db, compiled)\n const rawRows = this.db.query(compiled.sql).all(...compiled.args) as ObjectQueryDatabaseRow[]\n const rows = compiled.trimRows(rawRows) as readonly ObjectQueryDatabaseRow[]\n const hasMore =\n total === undefined && compiled.hasMoreProbe\n ? compiled.hasMoreProbe.hasMore(\n this.db.query(compiled.hasMoreProbe.sql).all(...compiled.hasMoreProbe.args).length\n )\n : compiled.hasMore(rawRows.length, total)\n\n return {\n objects: rows.map((row) => this.queryRowToObject(row)),\n hasMore,\n nextPageToken: compiled.nextPageToken(rows, rawRows.length),\n ...(total === undefined ? {} : { total }),\n }\n }\n\n async countObjects(params: CountObjectsInput): Promise<CountObjectsResult> {\n return {\n count: readTotal(\n this.db,\n compileObjectQuery(params.projectId, stripOuterRowShape(params.query))\n ),\n }\n }\n\n async existsObjects(params: ExistsObjectsInput): Promise<ExistsObjectsResult> {\n const compiled = compileObjectQuery(params.projectId, existsProbeQuery(params.query))\n return { exists: this.db.query(compiled.sql).get(...compiled.args) !== null }\n }\n\n async facetObjects(params: FacetObjectsInput): Promise<FacetObjectsResult> {\n const compiled = compileObjectQuery(params.projectId, stripOuterRowShape(params.query))\n return {\n facets: params.facets.map((facet) => ({\n propertyId: facet.propertyId,\n buckets: readFacetBuckets(this.db, compiled, facet),\n })),\n }\n }\n\n async getByPrimaryId(params: {\n projectId: string\n objectTypeId: string\n primaryId: string\n }): Promise<ObjectRow | null> {\n const row = this.db\n .query(\"SELECT * FROM objects WHERE project_id = ? AND object_type_id = ? AND primary_id = ?\")\n .get(params.projectId, params.objectTypeId, params.primaryId) as DatabaseRow | null\n\n return row ? this.rowToObject(row) : null\n }\n\n async listLinks(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n linkId?: string\n direction?: LinkDirection\n }): Promise<readonly ObjectLinkRow[]> {\n const direction = params.direction ?? \"outgoing\"\n const directionWhere =\n direction === \"incoming\"\n ? \"target_type_id = ? AND target_id = ?\"\n : direction === \"both\"\n ? \"((source_type_id = ? AND source_id = ?) OR (target_type_id = ? AND target_id = ?))\"\n : \"source_type_id = ? AND source_id = ?\"\n let query = `SELECT * FROM links WHERE project_id = ? AND ${directionWhere}`\n const args: (string | number)[] =\n direction === \"both\"\n ? [\n params.projectId,\n params.objectTypeId,\n params.objectId,\n params.objectTypeId,\n params.objectId,\n ]\n : [params.projectId, params.objectTypeId, params.objectId]\n\n if (params.linkId) {\n query += \" AND link_id = ?\"\n args.push(params.linkId)\n }\n\n const rows = this.db.query(query).all(...args) as LinkDatabaseRow[]\n\n return rows.map((row) => this.rowToLink(row))\n }\n\n async getByPrimaryIdBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; primaryId: string }[]\n }): Promise<Map<string, ObjectRow>> {\n const result = new Map<string, ObjectRow>()\n if (params.items.length === 0) return result\n\n const stmt = this.db.query(\n \"SELECT * FROM objects WHERE project_id = ? AND object_type_id = ? AND primary_id = ?\"\n )\n for (const item of params.items) {\n const row = stmt.get(\n params.projectId,\n item.objectTypeId,\n item.primaryId\n ) as DatabaseRow | null\n if (row) {\n result.set(`${item.objectTypeId}:${item.primaryId}`, this.rowToObject(row))\n }\n }\n return result\n }\n\n async listLinksBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; objectId: string; linkId: string }[]\n }): Promise<Map<string, ObjectLinkRow[]>> {\n const result = new Map<string, ObjectLinkRow[]>()\n if (params.items.length === 0) return result\n\n const stmt = this.db.query(\n \"SELECT * FROM links WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?\"\n )\n for (const item of params.items) {\n const rows = stmt.all(\n params.projectId,\n item.objectTypeId,\n item.objectId,\n item.linkId\n ) as LinkDatabaseRow[]\n if (rows.length > 0) {\n result.set(\n `${item.objectTypeId}:${item.objectId}:${item.linkId}`,\n rows.map((r) => this.rowToLink(r))\n )\n }\n }\n return result\n }\n\n async listIncidentLinksBatch(params: {\n projectId: string\n items: readonly { objectTypeId: string; objectId: string }[]\n }): Promise<readonly ObjectLinkRow[]> {\n const deduped = new Map<string, ObjectLinkRow>()\n for (const item of params.items) {\n const rows = await this.listLinks({\n projectId: params.projectId,\n objectTypeId: item.objectTypeId,\n objectId: item.objectId,\n direction: \"both\",\n })\n for (const row of rows) {\n deduped.set(\n `${row.sourceTypeId}:${row.sourceId}:${row.linkId}:${row.targetTypeId}:${row.targetId}`,\n row\n )\n }\n }\n return [...deduped.values()]\n }\n\n async listByPrimaryIdPage(params: {\n projectId: string\n objectTypeId: string\n afterPrimaryId?: string\n limit: number\n }): Promise<{ objects: readonly ObjectRow[]; nextPrimaryId?: string }> {\n assertReconciliationPageLimit(params.limit)\n const rows = this.db\n .query(\n `\n SELECT * FROM objects\n WHERE project_id = ? AND object_type_id = ?\n AND (? IS NULL OR primary_id > ?)\n ORDER BY primary_id ASC\n LIMIT ?\n `\n )\n .all(\n params.projectId,\n params.objectTypeId,\n params.afterPrimaryId ?? null,\n params.afterPrimaryId ?? null,\n params.limit + 1\n ) as DatabaseRow[]\n const hasMore = rows.length > params.limit\n const objects = rows.slice(0, params.limit).map((row) => this.rowToObject(row))\n const last = objects.at(-1)\n return {\n objects,\n ...(hasMore && last ? { nextPrimaryId: last.primaryId } : {}),\n }\n }\n\n async list(params: {\n projectId: string\n objectTypeId?: string | readonly string[]\n primaryIdPrefix?: string\n primaryIdSuffix?: string\n updatedAfter?: Date\n updatedBefore?: Date\n createdAfter?: Date\n createdBefore?: Date\n limit?: number\n offset?: number\n orderBy?: \"createdAt\" | \"updatedAt\" | \"primaryId\"\n order?: \"asc\" | \"desc\"\n }): Promise<{ objects: readonly ObjectRow[]; hasMore: boolean; total: number }> {\n let query = \"SELECT * FROM objects WHERE project_id = ?\"\n const args: (string | number | null)[] = [params.projectId]\n\n if (params.objectTypeId) {\n if (typeof params.objectTypeId === \"string\") {\n query += \" AND object_type_id = ?\"\n args.push(params.objectTypeId)\n } else {\n query += ` AND object_type_id IN (${params.objectTypeId.map(() => \"?\").join(\", \")})`\n args.push(...params.objectTypeId)\n }\n }\n\n if (params.primaryIdPrefix) {\n query += \" AND primary_id LIKE ?\"\n args.push(`${params.primaryIdPrefix}%`)\n }\n\n if (params.primaryIdSuffix) {\n query += \" AND primary_id LIKE ?\"\n args.push(`%${params.primaryIdSuffix}`)\n }\n\n if (params.updatedAfter) {\n query += \" AND updated_at >= ?\"\n args.push(params.updatedAfter.toISOString())\n }\n\n if (params.updatedBefore) {\n query += \" AND updated_at <= ?\"\n args.push(params.updatedBefore.toISOString())\n }\n\n if (params.createdAfter) {\n query += \" AND created_at >= ?\"\n args.push(params.createdAfter.toISOString())\n }\n\n if (params.createdBefore) {\n query += \" AND created_at <= ?\"\n args.push(params.createdBefore.toISOString())\n }\n\n // Get total count\n const countResult = this.db.query(`SELECT COUNT(*) as total FROM (${query})`).get(...args) as {\n total: number\n }\n const total = countResult.total\n\n const offset = params.offset ?? 0\n const limit = params.limit ?? 50\n if (limit === 0) return { objects: [], hasMore: offset < total, total }\n\n // Add ordering\n const orderBy = params.orderBy ?? \"updatedAt\"\n const order = params.order ?? \"desc\"\n const orderColumn =\n orderBy === \"primaryId\" ? \"primary_id\" : orderBy === \"createdAt\" ? \"created_at\" : \"updated_at\"\n query += ` ORDER BY ${orderColumn} ${order.toUpperCase()}`\n\n // Add pagination\n query += \" LIMIT ? OFFSET ?\"\n args.push(limit + 1, offset) // +1 to check for hasMore\n\n const rows = this.db.query(query).all(...args) as DatabaseRow[]\n const hasMore = rows.length > limit\n const objects = rows.slice(0, limit).map((row) => this.rowToObject(row))\n\n return { objects, hasMore, total }\n }\n private rowToObject(row: DatabaseRow): ObjectRow {\n return {\n projectId: row.project_id,\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n properties: JSON.parse(row.properties),\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n version: row.version,\n lastCommitId: row.last_commit_id,\n }\n }\n\n // Map a query row, attaching `links` when an `expand` pushdown produced them.\n // The base columns map as usual; `_expand` (a `json_object` serialized to TEXT)\n // is parsed and revived into the runtime link shape the core executor's\n // fallback also produces.\n private queryRowToObject(row: ObjectQueryDatabaseRow): ObjectRow {\n const base = this.rowToObject(row)\n const links = reviveExpandedLinks(parseExpandColumn(row._expand))\n return links ? { ...base, links } : base\n }\n\n private rowToLink(row: LinkDatabaseRow): ObjectLinkRow {\n return {\n projectId: row.project_id,\n sourceTypeId: row.source_type_id,\n sourceId: row.source_id,\n linkId: row.link_id,\n targetTypeId: row.target_type_id,\n targetId: row.target_id,\n properties: row.properties ? JSON.parse(row.properties) : undefined,\n createdAt: new Date(row.created_at),\n updatedAt: new Date(row.updated_at),\n lastCommitId: row.last_commit_id,\n }\n }\n\n /**\n * Close the database connection.\n */\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\nfunction assertReconciliationPageLimit(limit: number): void {\n if (!Number.isSafeInteger(limit) || limit <= 0) {\n throw new Error(\"Object reconciliation page limit must be a positive safe integer.\")\n }\n}\n\nfunction readTotal(db: Database, compiled: CompiledObjectQuery): number {\n const row = db.query(compiled.totalSql).get(...compiled.totalArgs) as { total: number }\n return row.total\n}\n\nfunction readFacetBuckets(\n db: Database,\n compiled: CompiledObjectQuery,\n facet: ObjectFacetRequest\n): { value: unknown; count: number }[] {\n const path = sqliteJsonPath(facet.propertyId)\n const rows = db\n .query(\n `\n SELECT\n json_type(input.properties, ?) AS value_type,\n json_extract(input.properties, ?) AS value,\n COUNT(*) AS count\n FROM (${compiled.sql}) AS input\n WHERE json_type(input.properties, ?) IS NOT NULL\n GROUP BY value_type, value\n ORDER BY count DESC, CAST(value AS TEXT) ASC\n LIMIT ?\n `\n )\n .all(path, path, ...compiled.args, path, facet.limit) as FacetDatabaseRow[]\n\n return rows.map((row) => ({\n value: sqliteFacetValue(row.value_type, row.value),\n count: Number(row.count),\n }))\n}\n\nfunction sqliteJsonPath(propertyId: string): string {\n return `$.\"${propertyId.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')}\"`\n}\n\nfunction sqliteFacetValue(valueType: string | null, value: unknown): unknown {\n if (valueType === \"true\") return true\n if (valueType === \"false\") return false\n if (valueType === \"null\") return null\n return value\n}\n\n// The `_expand` column comes back from SQLite as a JSON string (or null/absent\n// when the query carried no expansion); parse it before reviving.\nfunction parseExpandColumn(value: unknown): unknown {\n if (typeof value !== \"string\") return value ?? undefined\n return JSON.parse(value)\n}\n\nfunction reviveExpandedLinks(value: unknown): ObjectRowLinks | undefined {\n if (!isPlainObject(value)) return undefined\n const links: ObjectRowLinks = {}\n for (const [linkId, raw] of Object.entries(value)) {\n links[linkId] = reviveExpandedLinkValue(raw)\n }\n return links\n}\n\n// A \"one\" expansion arrives as a single object or null; a \"many\" expansion as an\n// array (already ordered and trimmed in the database).\nfunction reviveExpandedLinkValue(value: unknown): ExpandedLinkValue {\n if (value === null || value === undefined) return null\n if (Array.isArray(value)) return value.map(reviveExpandedRow)\n return reviveExpandedRow(value)\n}\n\n// Revive one hydrated neighbour from `compileExpansionChildJson`: timestamp\n// strings back to `Date`, null/empty link properties dropped (matching the\n// fallback), and nested links recursed.\nfunction reviveExpandedRow(value: unknown): ExpandedObjectRow {\n const row = isPlainObject(value) ? value : {}\n const expanded: ExpandedObjectRow = {\n projectId: String(row.projectId),\n objectTypeId: String(row.objectTypeId),\n primaryId: String(row.primaryId),\n properties: isPlainObject(row.properties) ? row.properties : {},\n createdAt: new Date(row.createdAt as string),\n updatedAt: new Date(row.updatedAt as string),\n version: Number(row.version),\n lastCommitId: String(row.lastCommitId),\n }\n if (isPlainObject(row.linkProperties) && Object.keys(row.linkProperties).length > 0) {\n expanded.linkProperties = row.linkProperties\n }\n const links = reviveExpandedLinks(row.links)\n if (links) expanded.links = links\n return expanded\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n\nfunction existsProbeQuery(query: ObjectQuery): ObjectQuery {\n return { kind: \"limit\", limit: 1, input: stripOuterRowShape(query) }\n}\n\nfunction stripOuterRowShape(query: ObjectQuery): ObjectQuery {\n switch (query.kind) {\n case \"limit\":\n case \"page\":\n case \"project\":\n case \"sort\":\n return stripOuterRowShape(query.input)\n default:\n return query\n }\n}\n\ninterface DatabaseRow {\n project_id: string\n object_type_id: string\n primary_id: string\n properties: string\n created_at: string\n updated_at: string\n version: number\n last_commit_id: string\n}\n\ninterface ObjectQueryDatabaseRow extends DatabaseRow {\n _cursor_properties?: string\n /** `json_object(linkId, value, ...)` serialized text from an `expand` pushdown; absent otherwise. */\n _expand?: string | null\n}\n\ninterface FacetDatabaseRow {\n value_type: string | null\n value: unknown\n count: number\n}\n\ninterface LinkDatabaseRow {\n project_id: string\n source_type_id: string\n source_id: string\n link_id: string\n target_type_id: string\n target_id: string\n properties: string | null\n created_at: string\n updated_at: string\n last_commit_id: string\n}\n",
|
|
31
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { ProjectionEntityRef } from \"@sixb/core/internal/materialization\"\nimport { MaterializationConflictError } from \"@sixb/core/internal/materialization\"\nimport type {\n AssertSourceMaterializationExecutionInput,\n OntologyCommitRecord,\n OntologyCommitWrite,\n OntologyOutboxRecord,\n OntologySourceRecord,\n StageSourceAssertion,\n} from \"@sixb/core/storage\"\n\nexport {\n assertNonblank,\n assertNonnegativeInteger,\n assertPositiveInteger,\n assertTimestamp,\n canonicalJson,\n linkRefFromColumns,\n objectRefFromColumns,\n originColumns,\n originWhere,\n sourceEntityKey,\n} from \"@sixb/core/internal/ontology-storage-provider\"\n\nexport type SqliteRootOperation = <T>(run: () => Promise<T> | T) => Promise<T>\n\nexport interface SqliteOntologyCommitRow {\n readonly project_id: string\n readonly id: string\n readonly idempotency_key: string\n readonly request_hash: string\n readonly origin_kind: string\n readonly origin_run_id: string | null\n readonly origin_batch_ordinal: number | null\n readonly origin: string\n readonly actor: string | null\n readonly ontology_revision: string\n readonly projection_revision: string | null\n readonly ownership_hash: string | null\n readonly intent: string\n readonly result: string\n readonly committed_at: string\n}\n\nexport interface SqliteOntologySourceRow {\n readonly project_id: string\n readonly source_id: string\n readonly materialization_id: string\n readonly projection_run_id: string\n readonly projection_kind: \"object\" | \"link\"\n readonly protocol: \"replacement\"\n readonly status: OntologySourceRecord[\"status\"]\n readonly execution_token: string | null\n readonly dataset_id: string\n readonly dataset_version_id: string\n readonly dataset_version_created_at: string\n readonly projection_revision: string\n readonly ownership_hash: string\n readonly ontology_revision: string\n readonly root_count: number | null\n readonly assertion_count: number | null\n readonly created_at: string\n readonly ready_at: string | null\n readonly activated_at: string | null\n readonly terminal_at: string | null\n readonly last_commit_id: string | null\n readonly updated_at: string\n}\n\nexport interface SqliteOntologySourceAssertionRow {\n readonly project_id: string\n readonly source_id: string\n readonly materialization_id: string\n readonly entity_kind: \"object\" | \"link\"\n readonly entity_key: string\n readonly entity_sort_key: string\n readonly root_kind: \"object\" | \"link\"\n readonly root_key: string\n readonly root_sort_key: string\n readonly staging_ordinal: number\n readonly root: string\n readonly assertion: string\n}\n\nexport interface SqliteOntologyOverrideRow {\n readonly entity_kind: \"object\" | \"link\"\n readonly value: string\n readonly last_commit_id: string\n readonly updated_at: string\n}\n\nexport interface SqliteOntologyOutboxRow {\n readonly envelope: string\n readonly available_at: string\n readonly attempts: number\n readonly lease_id: string | null\n readonly lease_expires_at: string | null\n readonly published_at: string | null\n readonly last_error: string | null\n readonly created_at: string\n}\n\nexport function parseJson<T>(value: string): T {\n return JSON.parse(value) as T\n}\n\nexport function sourceRecord(row: SqliteOntologySourceRow): OntologySourceRecord {\n return {\n projectId: row.project_id,\n source: { projectionId: row.source_id },\n materializationId: row.materialization_id,\n projectionRunId: row.projection_run_id,\n projectionKind: row.projection_kind,\n protocol: row.protocol,\n status: row.status,\n executionToken: row.execution_token,\n datasetVersion: {\n datasetId: row.dataset_id,\n versionId: row.dataset_version_id,\n createdAt: row.dataset_version_created_at,\n },\n projectionRevision: row.projection_revision,\n ownershipHash: row.ownership_hash,\n ontologyRevision: row.ontology_revision,\n rootCount: row.root_count,\n assertionCount: row.assertion_count,\n createdAt: row.created_at,\n readyAt: row.ready_at,\n activatedAt: row.activated_at,\n terminalAt: row.terminal_at,\n lastCommitId: row.last_commit_id,\n updatedAt: row.updated_at,\n }\n}\n\nexport function sourceAssertion(row: SqliteOntologySourceAssertionRow): StageSourceAssertion {\n return {\n root: parseJson<ProjectionEntityRef>(row.root),\n assertion: parseJson<StageSourceAssertion[\"assertion\"]>(row.assertion),\n stagingOrdinal: row.staging_ordinal,\n }\n}\n\nexport function commitRecord(row: SqliteOntologyCommitRow): OntologyCommitRecord {\n const base = {\n projectId: row.project_id,\n id: row.id,\n idempotencyKey: row.idempotency_key,\n requestHash: row.request_hash,\n origin: parseJson<OntologyCommitWrite[\"origin\"]>(row.origin),\n ...(row.actor === null\n ? {}\n : { actor: parseJson<NonNullable<OntologyCommitWrite[\"actor\"]>>(row.actor) }),\n ontologyRevision: row.ontology_revision,\n ...(row.projection_revision === null ? {} : { projectionRevision: row.projection_revision }),\n ...(row.ownership_hash === null ? {} : { ownershipHash: row.ownership_hash }),\n committedAt: row.committed_at,\n }\n const intent = parseJson<OntologyCommitWrite[\"intent\"]>(row.intent)\n const result = parseJson<OntologyCommitRecord[\"result\"]>(row.result)\n return { ...base, intent, result } as OntologyCommitRecord\n}\n\nexport function outboxRecord(row: SqliteOntologyOutboxRow): OntologyOutboxRecord {\n return {\n envelope: parseJson<OntologyOutboxRecord[\"envelope\"]>(row.envelope),\n availableAt: row.available_at,\n attempts: row.attempts,\n leaseId: row.lease_id,\n leaseExpiresAt: row.lease_expires_at,\n publishedAt: row.published_at,\n lastError: row.last_error,\n createdAt: row.created_at,\n }\n}\n\nexport function assertProjectionExecution(\n db: Database,\n input: {\n readonly projectId: string\n readonly sourceId: string\n readonly projectionRunId: string\n readonly executionToken: string\n readonly identity?: AssertSourceMaterializationExecutionInput[\"identity\"]\n }\n): void {\n const run = db\n .query(\n `\n SELECT projection_id, projection_kind, status, materialization_protocol, execution_token,\n dataset_id, dataset_version_id, dataset_version_created_at,\n ontology_revision, projection_revision, ownership_hash\n FROM projection_runs\n WHERE project_id = ? AND id = ?\n `\n )\n .get(input.projectId, input.projectionRunId) as {\n projection_id: string\n projection_kind: string\n status: string\n materialization_protocol: string | null\n execution_token: string | null\n dataset_id: string\n dataset_version_id: string\n dataset_version_created_at: string | null\n ontology_revision: string | null\n projection_revision: string | null\n ownership_hash: string | null\n } | null\n if (!run || run.status !== \"running\") {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' is missing or is not running.`\n )\n }\n if (run.projection_id !== input.sourceId || run.materialization_protocol !== \"replacement\") {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' does not own replacement source '${input.sourceId}'.`\n )\n }\n if (run.execution_token !== input.executionToken) {\n throw new MaterializationConflictError(\n \"execution-lost\",\n `Projection run '${input.projectionRunId}' execution token is stale.`\n )\n }\n const identity = input.identity\n if (\n identity &&\n (run.projection_kind !== identity.projectionKind ||\n run.materialization_protocol !== identity.protocol ||\n run.dataset_id !== identity.datasetVersion.datasetId ||\n run.dataset_version_id !== identity.datasetVersion.versionId ||\n run.dataset_version_created_at !== identity.datasetVersion.createdAt ||\n run.ontology_revision !== identity.ontologyRevision ||\n run.projection_revision !== identity.projectionRevision ||\n run.ownership_hash !== identity.ownershipHash)\n ) {\n throw new MaterializationConflictError(\n \"run-correlation\",\n `Projection run '${input.projectionRunId}' immutable source identity does not match.`\n )\n }\n}\n\nexport function requireChanges(\n changes: number,\n kind: ConstructorParameters<typeof MaterializationConflictError>[0],\n message: string\n): void {\n if (changes !== 1) throw new MaterializationConflictError(kind, message)\n}\n\nexport function isSqliteConstraintError(error: unknown): boolean {\n if (!(error instanceof Error)) return false\n const details = error as Error & { readonly code?: unknown; readonly errno?: unknown }\n if (typeof details.code === \"string\") {\n return [\n \"SQLITE_CONSTRAINT_CHECK\",\n \"SQLITE_CONSTRAINT_FOREIGNKEY\",\n \"SQLITE_CONSTRAINT_NOTNULL\",\n \"SQLITE_CONSTRAINT_PRIMARYKEY\",\n \"SQLITE_CONSTRAINT_UNIQUE\",\n ].includes(details.code)\n }\n return details.errno === 19\n}\n",
|
|
32
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n GetOntologyCommitByIdempotencyKeyInput,\n GetOntologyCommitByIdInput,\n GetOntologyCommitByOriginInput,\n ListOntologyCommitsInput,\n ListOntologyCommitsResult,\n OntologyCommitRecord,\n OntologyCommitStorage,\n} from \"@sixb/core/storage\"\nimport {\n assertNonblank,\n assertNonnegativeInteger,\n commitRecord,\n originWhere,\n type SqliteOntologyCommitRow,\n type SqliteRootOperation,\n} from \"./shared\"\n\nexport class SqliteOntologyCommitStorage implements OntologyCommitStorage {\n constructor(\n private readonly db: Database,\n private readonly runRootOperation: SqliteRootOperation\n ) {}\n\n async getByIdempotencyKey(\n input: GetOntologyCommitByIdempotencyKeyInput\n ): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n assertNonblank(input.idempotencyKey, \"Ontology commit idempotency key\")\n return this.readOne(\n \"project_id = ? AND idempotency_key = ?\",\n input.projectId,\n input.idempotencyKey\n )\n })\n }\n\n async getById(input: GetOntologyCommitByIdInput): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n assertNonblank(input.id, \"Ontology commit id\")\n return this.readOne(\"project_id = ? AND id = ?\", input.projectId, input.id)\n })\n }\n\n async getByOrigin(input: GetOntologyCommitByOriginInput): Promise<OntologyCommitRecord | null> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n const origin = originWhere(input.origin)\n assertNonblank(origin.runId, \"Ontology commit origin run id\")\n if (origin.batchOrdinal !== null) {\n assertNonnegativeInteger(origin.batchOrdinal, \"Ontology telemetry commit batch ordinal\")\n }\n return origin.batchOrdinal === null\n ? this.readOne(\n \"project_id = ? AND origin_kind = ? AND origin_run_id = ? AND origin_batch_ordinal IS NULL\",\n input.projectId,\n origin.kind,\n origin.runId\n )\n : this.readOne(\n \"project_id = ? AND origin_kind = ? AND origin_run_id = ? AND origin_batch_ordinal = ?\",\n input.projectId,\n origin.kind,\n origin.runId,\n origin.batchOrdinal\n )\n })\n }\n\n async list(input: ListOntologyCommitsInput): Promise<ListOntologyCommitsResult> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology commit project id\")\n if (input.run) assertNonblank(input.run.id, \"Ontology commit run id\")\n const offset = input.offset ?? 0\n const limit = input.limit ?? -1\n assertNonnegativeInteger(offset, \"Ontology commit list offset\")\n if (limit !== -1) assertNonnegativeInteger(limit, \"Ontology commit list limit\")\n const filters = [\"project_id = ?\"]\n const values: (string | number)[] = [input.projectId]\n if (input.run?.kind === \"action\") {\n filters.push(\"origin_kind = 'action' AND origin_run_id = ?\")\n values.push(input.run.id)\n } else if (input.run?.kind === \"projection\") {\n filters.push(\"origin_run_id = ? AND origin_kind IN ('projection', 'telemetry')\")\n values.push(input.run.id)\n }\n const where = filters.join(\" AND \")\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS total FROM ontology_commits WHERE ${where}`)\n .get(...values) as { readonly total: number }\n const direction = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const order =\n input.run?.kind === \"projection\"\n ? `CASE WHEN origin_kind = 'telemetry' THEN origin_batch_ordinal ELSE -1 END ${direction}, committed_at ${direction}, id ${direction}`\n : `committed_at ${direction}, id ${direction}`\n const rows = this.db\n .query(\n `\n SELECT * FROM ontology_commits\n WHERE ${where}\n ORDER BY ${order}\n LIMIT ? OFFSET ?\n `\n )\n .all(...values, limit, offset) as SqliteOntologyCommitRow[]\n const commits = rows.map(commitRecord)\n return {\n commits,\n total: totalRow.total,\n hasMore: offset + commits.length < totalRow.total,\n }\n })\n }\n\n private readOne(\n where: string,\n ...values: readonly (string | number)[]\n ): OntologyCommitRecord | null {\n const row = this.db\n .query(`SELECT * FROM ontology_commits WHERE ${where}`)\n .get(...values) as SqliteOntologyCommitRow | null\n return row ? commitRecord(row) : null\n }\n}\n",
|
|
33
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n EffectiveChangeCounts,\n ExpectedLinkRevision,\n ExpectedObjectRevision,\n} from \"@sixb/core/internal/materialization\"\nimport {\n assertPinnedDatasetWatermark,\n linkRefKey,\n linkRefSortKey,\n linkScopeSortKey,\n MaterializationConflictError,\n objectRefKey,\n objectRefSortKey,\n telemetryPointKey,\n telemetryPointSortKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n assertMaterializationFinalizationCorrelation,\n assertMaterializationHeader,\n assertMaterializationLaneCompletion,\n assertPageRows,\n assertPlanChunkCorrelations,\n assertSourceActivationCorrelation,\n invalidCorrelation,\n sameNonnegativeCounts as sameCounts,\n uniqueSorted,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n ApplyMaterializationChunkInput,\n ApplyMaterializationResult,\n FinalizeMaterializationInput,\n MaterializationCardinalityOccupantWorkRecord,\n MaterializationClassificationWorkRecord,\n MaterializationObjectExistence,\n MaterializationPlanHeader,\n MaterializationPlanWorkRecord,\n MaterializationSession,\n MaterializationStatePage,\n MaterializationWorkPage,\n OntologyCommitRecord,\n OntologyMaterializationStorage,\n ReadMaterializationObjectExistenceInput,\n SourceActivationWrite,\n SourceReplacementStatePage,\n StageMaterializationWorkInput,\n StreamMaterializationStateInput,\n StreamMaterializationWorkInput,\n StreamSourceReplacementStateInput,\n} from \"@sixb/core/storage\"\nimport { stableJsonStringify } from \"@sixb/core/storage\"\nimport {\n type SqliteMaterializationSessionState,\n SqliteMaterializationSessions,\n type SqliteOntologyTransactionContext,\n} from \"./materialization-session\"\nimport {\n linkSortExpression,\n SQLITE_MATERIALIZATION_WORK_TABLE,\n SqliteMaterializationStateReader,\n} from \"./materialization-state\"\nimport { SqliteMaterializationWriter } from \"./materialization-writer\"\nimport {\n assertProjectionExecution,\n canonicalJson,\n commitRecord,\n isSqliteConstraintError,\n originColumns,\n requireChanges,\n type SqliteOntologyCommitRow,\n type SqliteOntologySourceRow,\n} from \"./shared\"\n\nexport class SqliteOntologyMaterializationStorage implements OntologyMaterializationStorage {\n private readonly sessions: SqliteMaterializationSessions\n private readonly writer: SqliteMaterializationWriter\n\n constructor(\n private readonly db: Database,\n context: SqliteOntologyTransactionContext | null\n ) {\n this.sessions = new SqliteMaterializationSessions(db, context)\n this.writer = new SqliteMaterializationWriter(db)\n }\n\n async begin(input: MaterializationPlanHeader): Promise<MaterializationSession> {\n assertMaterializationHeader(input)\n const session = this.sessions.create(input)\n try {\n this.assertCommitAbsent(input)\n const reader = new SqliteMaterializationStateReader(this.db, input.commit.projectId)\n for (const expected of input.expected.sources)\n this.assertSource(expected, input.commit.projectId)\n for (const expected of input.expected.objects) this.assertObject(reader, expected)\n for (const expected of input.expected.links) this.assertLink(reader, expected)\n for (const expected of input.expected.linkScopes) {\n if (\n reader.linkScope(expected.source, expected.linkId).fingerprint !== expected.fingerprint\n ) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link scope changed for ${expected.source.objectTypeId}:${expected.source.primaryId}.${expected.linkId}.`\n )\n }\n }\n for (const expected of input.expected.points) {\n const point = reader.exactPoint(expected.series, expected.at)\n if ((point?.lastCommitId ?? null) !== expected.lastCommitId) {\n throw new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointKey(expected.series, expected.at)} changed.`\n )\n }\n }\n return session.publicSession()\n } catch (error) {\n this.sessions.release(session)\n throw error\n }\n }\n\n async *streamState(\n input: StreamMaterializationStateInput\n ): AsyncIterable<MaterializationStatePage> {\n const session = this.sessions.require(input.session)\n assertPageRows(input.pageRows)\n const reader = new SqliteMaterializationStateReader(this.db, session.header.commit.projectId)\n for await (const request of input.requests) {\n this.sessions.require(input.session)\n const objects = uniqueSorted(request.objects, objectRefKey, objectRefSortKey)\n for (let offset = 0; offset < objects.length; offset += input.pageRows) {\n const page = reader.objectStates(objects.slice(offset, offset + input.pageRows))\n yield { objects: page, links: [], linkScopes: [], points: [] }\n }\n const links = uniqueSorted(request.links, linkRefKey, linkRefSortKey)\n for (let offset = 0; offset < links.length; offset += input.pageRows) {\n const page = reader.linkStates(links.slice(offset, offset + input.pageRows))\n yield { objects: [], links: page, linkScopes: [], points: [] }\n }\n for (const refs of reader.incidentLinks(request.incidentObjects, input.pageRows)) {\n this.sessions.require(input.session)\n yield {\n objects: [],\n links: reader.linkStates(refs),\n linkScopes: [],\n points: [],\n }\n }\n const scopes = uniqueSorted(\n request.linkScopes,\n (scope) =>\n JSON.stringify([scope.source.objectTypeId, scope.source.primaryId, scope.linkId]),\n (scope) => linkScopeSortKey(scope.source, scope.linkId)\n )\n for (let offset = 0; offset < scopes.length; offset += input.pageRows) {\n yield {\n objects: [],\n links: [],\n linkScopes: reader.linkScopes(scopes.slice(offset, offset + input.pageRows)),\n points: [],\n }\n }\n const points = uniqueSorted(\n request.points,\n (point) => telemetryPointKey(point.series, point.at),\n (point) => telemetryPointSortKey(point.series, point.at)\n )\n for (let offset = 0; offset < points.length; offset += input.pageRows) {\n const page = reader.exactPoints(points.slice(offset, offset + input.pageRows))\n if (page.length > 0) yield { objects: [], links: [], linkScopes: [], points: page }\n }\n }\n }\n\n async *streamSourceReplacementState(\n input: StreamSourceReplacementStateInput\n ): AsyncIterable<SourceReplacementStatePage> {\n const session = this.sessions.require(input.session)\n assertPageRows(input.pageRows)\n const replacement = this.requireReplacement(session, input)\n const reader = new SqliteMaterializationStateReader(this.db, session.header.commit.projectId)\n if (input.entityKind === \"object\") {\n if (replacement.projectionKind !== \"object\") {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Link projection replacement cannot stream object state.\"\n )\n }\n if (replacement.objectStreamStarted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Replacement object state may only be streamed once per session.\"\n )\n }\n replacement.objectStreamStarted = true\n for (const identities of reader.replacementIdentities({\n sessionId: session.id,\n sourceId: replacement.sourceId,\n candidateMaterializationId: replacement.candidateMaterializationId,\n previousMaterializationId: replacement.previousMaterializationId,\n kind: \"object\",\n pageRows: input.pageRows,\n })) {\n this.sessions.require(input.session)\n this.sessions.recordReplacementIdentities(session, identities)\n const refs = identities.map((identity) => {\n if (identity.kind !== \"object\") {\n invalidCorrelation(\"Object replacement returned a link identity.\")\n }\n return identity.ref\n })\n const objects = reader.replacementObjectStates(\n replacement.sourceId,\n replacement.candidateMaterializationId,\n refs\n )\n yield { objects, links: [] }\n }\n this.sessions.require(input.session)\n replacement.objectStreamCompleted = true\n return\n }\n\n if (replacement.projectionKind === \"object\" && !replacement.objectStreamCompleted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Object projection replacement must fully stream object state before link state.\"\n )\n }\n if (replacement.linkStreamStarted) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Replacement link state may only be streamed once per session.\"\n )\n }\n replacement.linkStreamStarted = true\n const materializationIds = [\n replacement.candidateMaterializationId,\n ...(replacement.previousMaterializationId ? [replacement.previousMaterializationId] : []),\n ]\n for (const identities of reader.replacementIdentities({\n sessionId: session.id,\n sourceId: replacement.sourceId,\n candidateMaterializationId: replacement.candidateMaterializationId,\n previousMaterializationId: replacement.previousMaterializationId,\n kind: \"link\",\n pageRows: input.pageRows,\n })) {\n this.sessions.require(input.session)\n this.sessions.recordReplacementIdentities(session, identities)\n const linkIdentities = identities.map((identity) => {\n if (identity.kind !== \"link\") {\n invalidCorrelation(\"Link replacement returned an object identity.\")\n }\n return identity\n })\n const links = reader.replacementLinkStates(\n replacement.sourceId,\n replacement.candidateMaterializationId,\n materializationIds,\n linkIdentities\n )\n yield { objects: [], links }\n }\n this.sessions.require(input.session)\n replacement.linkStreamCompleted = true\n }\n\n async stageWork(input: StageMaterializationWorkInput): Promise<void> {\n this.sessions.stage(input)\n }\n\n streamWork(input: StreamMaterializationWorkInput): AsyncIterable<MaterializationWorkPage> {\n assertPageRows(input.pageRows)\n return this.sessions.stream(input)\n }\n\n async readObjectExistence(\n input: ReadMaterializationObjectExistenceInput\n ): Promise<readonly MaterializationObjectExistence[]> {\n const session = this.sessions.require(input.session)\n return this.sessions.readObjectExistence(session, input.refs)\n }\n\n async applyChunk(input: ApplyMaterializationChunkInput): Promise<void> {\n const session = this.sessions.require(input.session)\n const { commit } = session.header\n assertPlanChunkCorrelations(input.chunk, commit)\n const planCount = session.appliedPlanCount\n const outboxCount = session.appliedOutboxCount\n this.sessions.assertChunkSequence(session, input.chunk)\n this.db.run(\"SAVEPOINT sixb_ontology_apply_chunk\")\n try {\n this.writer.apply(commit.projectId, commit.id, input.chunk)\n this.db.run(\"RELEASE SAVEPOINT sixb_ontology_apply_chunk\")\n } catch (error) {\n this.db.run(\"ROLLBACK TO SAVEPOINT sixb_ontology_apply_chunk\")\n this.db.run(\"RELEASE SAVEPOINT sixb_ontology_apply_chunk\")\n session.appliedPlanCount = planCount\n session.appliedOutboxCount = outboxCount\n throw error\n }\n }\n\n async finalize(input: FinalizeMaterializationInput): Promise<ApplyMaterializationResult> {\n const session = this.sessions.require(input.session)\n this.assertCommitAbsent(session.header)\n this.assertFinalization(session, input)\n for (const activation of input.finalization.sourceActivations) {\n this.activateSource(session, activation)\n }\n const record = this.insertCommit(session.header, input)\n this.sessions.release(session)\n return { commit: record }\n }\n\n deactivateSessions(): void {\n this.sessions.deactivateAll()\n }\n\n private requireReplacement(\n session: SqliteMaterializationSessionState,\n input: StreamSourceReplacementStateInput\n ): NonNullable<SqliteMaterializationSessionState[\"replacement\"]> {\n if (session.replacement) {\n if (\n session.replacement.sourceId !== input.source.projectionId ||\n session.replacement.candidateMaterializationId !== input.candidateMaterializationId\n ) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Materialization session already owns another replacement union.\"\n )\n }\n return session.replacement\n }\n const projectId = session.header.commit.projectId\n const candidate = this.getSource(\n projectId,\n input.source.projectionId,\n input.candidateMaterializationId\n )\n if (!candidate || candidate.status !== \"ready\" || candidate.execution_token === null) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n `Candidate source materialization '${input.candidateMaterializationId}' is missing or is not ready.`\n )\n }\n assertProjectionExecution(this.db, {\n projectId,\n sourceId: input.source.projectionId,\n projectionRunId: candidate.projection_run_id,\n executionToken: candidate.execution_token,\n })\n const previous = this.getActiveSource(projectId, input.source.projectionId)\n if (\n candidate.protocol !== \"replacement\" ||\n (previous &&\n (previous.protocol !== candidate.protocol ||\n previous.projection_kind !== candidate.projection_kind))\n ) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Source replacement kind or protocol does not match its active materialization.\"\n )\n }\n session.replacement = {\n sourceId: input.source.projectionId,\n candidateMaterializationId: input.candidateMaterializationId,\n previousMaterializationId: previous?.materialization_id ?? null,\n projectionKind: candidate.projection_kind,\n objectStreamStarted: false,\n objectStreamCompleted: false,\n linkStreamStarted: false,\n linkStreamCompleted: false,\n }\n return session.replacement\n }\n\n private assertCommitAbsent(header: MaterializationPlanHeader): void {\n const origin = originColumns(header.commit.origin)\n const duplicate = this.db\n .query(\n `\n SELECT CASE\n WHEN id = ? THEN 'id'\n WHEN idempotency_key = ? THEN 'idempotency'\n ELSE 'origin'\n END AS duplicate\n FROM ontology_commits\n WHERE project_id = ? AND (\n id = ? OR idempotency_key = ? OR (\n ? IS NOT NULL AND origin_kind = ? AND origin_run_id = ?\n AND (origin_batch_ordinal IS ? OR origin_batch_ordinal = ?)\n )\n )\n LIMIT 1\n `\n )\n .get(\n header.commit.id,\n header.commit.idempotencyKey,\n header.commit.projectId,\n header.commit.id,\n header.commit.idempotencyKey,\n origin.runId,\n origin.kind,\n origin.runId,\n origin.batchOrdinal,\n origin.batchOrdinal\n ) as { readonly duplicate: \"id\" | \"idempotency\" | \"origin\" } | null\n if (!duplicate) return\n if (duplicate.duplicate === \"origin\") {\n throw new MaterializationConflictError(\n \"run-correlation\",\n \"Ontology commit origin already has an authoritative commit.\"\n )\n }\n throw new MaterializationConflictError(\n \"idempotency\",\n duplicate.duplicate === \"id\"\n ? `Ontology commit '${header.commit.id}' already exists.`\n : \"Ontology idempotency key already exists.\"\n )\n }\n\n private assertSource(\n expected: MaterializationPlanHeader[\"expected\"][\"sources\"][number],\n projectId: string\n ): void {\n const active = this.getActiveSource(projectId, expected.source.projectionId)\n if (\n (active?.materialization_id ?? null) !== expected.activeMaterializationId ||\n (active?.last_commit_id ?? null) !== expected.lastCommitId\n ) {\n throw new MaterializationConflictError(\n \"projection-fence\",\n `Source '${expected.source.projectionId}' changed.`\n )\n }\n }\n\n private assertObject(\n reader: SqliteMaterializationStateReader,\n expected: ExpectedObjectRevision\n ): void {\n const row = reader.effectiveObjectRevision(expected.ref)\n if (!expected.exists) {\n if (row) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected object ${objectRefKey(expected.ref)} to be absent.`\n )\n }\n return\n }\n if (!row || row.version !== expected.version || row.lastCommitId !== expected.lastCommitId) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected object ${objectRefKey(expected.ref)} changed.`\n )\n }\n }\n\n private assertLink(\n reader: SqliteMaterializationStateReader,\n expected: ExpectedLinkRevision\n ): void {\n const lastCommitId = reader.effectiveLinkLastCommit(expected.ref)\n if (!expected.exists) {\n if (lastCommitId !== undefined) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link ${linkRefKey(expected.ref)} to be absent.`\n )\n }\n return\n }\n if (lastCommitId === undefined || lastCommitId !== expected.lastCommitId) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Expected link ${linkRefKey(expected.ref)} changed.`\n )\n }\n }\n\n private assertFinalization(\n session: SqliteMaterializationSessionState,\n input: FinalizeMaterializationInput\n ): void {\n const { commit } = session.header\n const { result } = input.finalization\n assertMaterializationFinalizationCorrelation(session, input)\n const laneCounts = this.sessions.laneCounts(session)\n assertMaterializationLaneCompletion(session, laneCounts)\n this.assertFinalCardinality(session)\n const eventCount = laneCounts.event\n const outbox = this.db\n .query(\n `\n SELECT COUNT(*) AS count, MIN(commit_ordinal) AS minimum, MAX(commit_ordinal) AS maximum\n FROM ontology_outbox WHERE project_id = ? AND commit_id = ?\n `\n )\n .get(commit.projectId, commit.id) as {\n readonly count: number\n readonly minimum: number | null\n readonly maximum: number | null\n }\n if (\n outbox.count !== eventCount ||\n (eventCount > 0 && (outbox.minimum !== 0 || outbox.maximum !== eventCount - 1))\n ) {\n invalidCorrelation(\"Outbox event ordinals must be contiguous from zero.\")\n }\n\n if (commit.intent.kind === \"telemetry\") {\n const classifiedPoints = this.db\n .query(\n `\n SELECT COUNT(*) AS count FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = 'classification'\n AND json_extract(payload, '$.entityKind') = 'point'\n `\n )\n .get(session.id) as { readonly count: number }\n if (classifiedPoints.count !== commit.intent.pointCount) {\n invalidCorrelation(\n \"Telemetry point classification coverage does not match the commit intent.\"\n )\n }\n if (\n result.kind !== \"telemetry\" ||\n !sameCounts(result, this.telemetryCounts(session, commit.intent.pointCount))\n ) {\n invalidCorrelation(\"Telemetry result counts do not correlate with finalized work.\")\n }\n }\n if (commit.intent.kind === \"projection\") {\n if (result.kind !== \"projection\") return\n this.sessions.assertClassificationCoverage(session)\n if (!sameCounts(result.counts, this.projectionCounts(session))) {\n invalidCorrelation(\"Projection result counts do not correlate with finalized work.\")\n }\n }\n }\n\n private assertFinalCardinality(session: SqliteMaterializationSessionState): void {\n const duplicate = this.db\n .query(\n `\n SELECT json_extract(payload, '$.scopeSortKey') AS scope_key\n FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = 'cardinality'\n AND json_extract(payload, '$.occupied') = 1\n GROUP BY scope_key HAVING COUNT(*) > 1 LIMIT 1\n `\n )\n .get(session.id)\n if (duplicate) {\n invalidCorrelation(\"Materialization cardinality work violates cardinality-one.\")\n }\n const records = this.sessions.records(\n session,\n \"cardinality\"\n ) as MaterializationCardinalityOccupantWorkRecord[]\n const scopes = new Map<string, MaterializationCardinalityOccupantWorkRecord>()\n for (const record of records) scopes.set(record.scopeSortKey, record)\n for (const record of scopes.values()) {\n const effective = this.db\n .query(\n `\n SELECT ${linkSortExpression()} AS sort_key FROM links\n WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?\n ORDER BY sort_key\n `\n )\n .all(\n session.header.commit.projectId,\n record.ref.source.objectTypeId,\n record.ref.source.primaryId,\n record.ref.linkId\n ) as { readonly sort_key: string }[]\n const occupied = records\n .filter((candidate) => candidate.scopeSortKey === record.scopeSortKey && candidate.occupied)\n .map((candidate) => candidate.linkSortKey)\n .sort()\n if (\n stableJsonStringify(effective.map((row) => row.sort_key)) !== stableJsonStringify(occupied)\n ) {\n invalidCorrelation(\n \"Materialization cardinality work does not match the final effective link scope.\"\n )\n }\n }\n }\n\n private projectionCounts(session: SqliteMaterializationSessionState): EffectiveChangeCounts {\n const classifications = this.sessions.records(\n session,\n \"classification\"\n ) as MaterializationClassificationWorkRecord[]\n const plans = this.sessions.records(session, \"plan\") as MaterializationPlanWorkRecord[]\n const counts: MutableEffectiveChangeCounts = {\n objectsCreated: 0,\n objectsUpdated: 0,\n objectsDeleted: 0,\n objectsUnchanged: classifications.filter((record) => record.entityKind === \"object\").length,\n linksCreated: 0,\n linksUpdated: 0,\n linksDeleted: 0,\n linksUnchanged: classifications.filter((record) => record.entityKind === \"link\").length,\n }\n for (const record of plans) {\n switch (record.item.kind) {\n case \"object-upsert\":\n if (record.item.value.expected.exists) counts.objectsUpdated += 1\n else counts.objectsCreated += 1\n counts.objectsUnchanged -= 1\n break\n case \"object-delete\":\n counts.objectsDeleted += 1\n counts.objectsUnchanged -= 1\n break\n case \"link-upsert\":\n if (record.item.value.expected.exists) counts.linksUpdated += 1\n else counts.linksCreated += 1\n counts.linksUnchanged -= 1\n break\n case \"link-delete\":\n counts.linksDeleted += 1\n counts.linksUnchanged -= 1\n break\n }\n }\n return counts\n }\n\n private telemetryCounts(session: SqliteMaterializationSessionState, pointCount: number) {\n let pointsCreated = 0\n let pointsUpdated = 0\n let latestObjectsChanged = 0\n for (const record of this.sessions.records(\n session,\n \"plan\"\n ) as MaterializationPlanWorkRecord[]) {\n if (record.item.kind === \"point-upsert\") {\n if (record.item.value.expected.lastCommitId === null) pointsCreated += 1\n else pointsUpdated += 1\n } else if (record.item.kind === \"object-upsert\") {\n latestObjectsChanged += 1\n }\n }\n return {\n pointsCreated,\n pointsUpdated,\n pointsUnchanged: pointCount - pointsCreated - pointsUpdated,\n latestObjectsChanged,\n }\n }\n\n private activateSource(\n session: SqliteMaterializationSessionState,\n activation: SourceActivationWrite\n ): void {\n const { commit } = session.header\n assertSourceActivationCorrelation(session, activation)\n const candidate = this.getSource(\n commit.projectId,\n activation.source.projectionId,\n activation.materializationId\n )\n if (!candidate || candidate.status !== \"ready\" || candidate.execution_token === null) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n \"Source activation candidate is missing or is not ready.\"\n )\n }\n assertProjectionExecution(this.db, {\n projectId: commit.projectId,\n sourceId: activation.source.projectionId,\n projectionRunId: activation.execution.projectionRunId,\n executionToken: activation.execution.executionToken,\n })\n if (\n candidate.projection_run_id !== activation.execution.projectionRunId ||\n candidate.execution_token !== activation.execution.executionToken ||\n candidate.projection_kind !== activation.projectionKind ||\n candidate.protocol !== activation.protocol ||\n candidate.dataset_id !== activation.datasetVersion.datasetId ||\n candidate.dataset_version_id !== activation.datasetVersion.versionId ||\n candidate.dataset_version_created_at !== activation.datasetVersion.createdAt ||\n candidate.projection_revision !== activation.projectionRevision ||\n candidate.ownership_hash !== activation.ownershipHash ||\n candidate.ontology_revision !== activation.ontologyRevision ||\n candidate.ready_at === null ||\n activation.updatedAt < candidate.ready_at\n ) {\n invalidCorrelation(\"Source activation does not match its ready candidate identity.\")\n }\n this.assertSource(activation.expected, commit.projectId)\n const previous = this.getActiveSource(commit.projectId, activation.source.projectionId)\n if (previous) {\n assertPinnedDatasetWatermark(\n {\n datasetId: previous.dataset_id,\n versionId: previous.dataset_version_id,\n createdAt: previous.dataset_version_created_at,\n },\n activation.datasetVersion,\n \"Source activation\"\n )\n if (activation.updatedAt < previous.updated_at) {\n invalidCorrelation(\"Source activation cannot precede the active materialization update.\")\n }\n requireChanges(\n this.db\n .query(\n `\n UPDATE ontology_sources\n SET status = 'superseded', execution_token = NULL, terminal_at = ?, updated_at = ?\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND status = 'active' AND last_commit_id = ?\n `\n )\n .run(\n activation.updatedAt,\n activation.updatedAt,\n commit.projectId,\n activation.source.projectionId,\n previous.materialization_id,\n activation.expected.lastCommitId\n ).changes,\n \"projection-fence\",\n `Source '${activation.source.projectionId}' changed.`\n )\n }\n requireChanges(\n this.db\n .query(\n `\n UPDATE ontology_sources\n SET status = 'active', execution_token = NULL, activated_at = ?,\n last_commit_id = ?, updated_at = ?\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND status = 'ready' AND execution_token = ?\n `\n )\n .run(\n activation.updatedAt,\n activation.lastCommitId,\n activation.updatedAt,\n commit.projectId,\n activation.source.projectionId,\n activation.materializationId,\n activation.execution.executionToken\n ).changes,\n \"source-materialization\",\n \"Source activation candidate changed.\"\n )\n }\n\n private insertCommit(\n header: MaterializationPlanHeader,\n input: FinalizeMaterializationInput\n ): OntologyCommitRecord {\n const { commit } = header\n const origin = originColumns(commit.origin)\n try {\n this.db\n .query(\n `\n INSERT INTO ontology_commits (\n project_id, id, idempotency_key, request_hash,\n origin_kind, origin_run_id, origin_batch_ordinal, origin, actor,\n ontology_revision, projection_revision, ownership_hash,\n intent, result, committed_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, json(?), json(?), ?, ?, ?, json(?), json(?), ?)\n `\n )\n .run(\n commit.projectId,\n commit.id,\n commit.idempotencyKey,\n commit.requestHash,\n origin.kind,\n origin.runId,\n origin.batchOrdinal,\n canonicalJson(commit.origin),\n commit.actor === undefined ? null : canonicalJson(commit.actor),\n commit.ontologyRevision,\n commit.projectionRevision ?? null,\n commit.ownershipHash ?? null,\n canonicalJson(commit.intent),\n canonicalJson(input.finalization.result),\n commit.committedAt\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw new MaterializationConflictError(\n \"idempotency\",\n \"Ontology commit identity already exists.\"\n )\n }\n throw error\n }\n const row = this.db\n .query(\"SELECT * FROM ontology_commits WHERE project_id = ? AND id = ?\")\n .get(commit.projectId, commit.id) as SqliteOntologyCommitRow\n return commitRecord(row)\n }\n\n private getActiveSource(projectId: string, sourceId: string): SqliteOntologySourceRow | null {\n return this.db\n .query(\n `SELECT * FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND status = 'active'`\n )\n .get(projectId, sourceId) as SqliteOntologySourceRow | null\n }\n\n private getSource(\n projectId: string,\n sourceId: string,\n materializationId: string\n ): SqliteOntologySourceRow | null {\n return this.db\n .query(\n `SELECT * FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?`\n )\n .get(projectId, sourceId, materializationId) as SqliteOntologySourceRow | null\n }\n}\n\ntype MutableEffectiveChangeCounts = {\n -readonly [TKey in keyof EffectiveChangeCounts]: EffectiveChangeCounts[TKey]\n}\n",
|
|
34
|
+
"import type { Database } from \"bun:sqlite\"\nimport {\n linkRefKey,\n MaterializationConflictError,\n objectRefKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n correlateMaterializationChunk,\n duplicateMaterializationWork as duplicateWork,\n invalidCorrelation,\n materializationPlanItems,\n ProviderMaterializationSessionState,\n type ProviderMaterializationTransactionLifecycle,\n prepareMaterializationWork,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n MaterializationEventWorkRecord,\n MaterializationPlanChunk,\n MaterializationPlanHeader,\n MaterializationPlanWorkItem,\n MaterializationSession,\n MaterializationWorkPage,\n MaterializationWorkRecord,\n StageMaterializationWorkInput,\n StreamMaterializationWorkInput,\n} from \"@sixb/core/storage\"\nimport {\n type ReplacementIdentity,\n SQLITE_MATERIALIZATION_WORK_TABLE,\n SQLITE_REPLACEMENT_WORK_TABLE,\n} from \"./materialization-state\"\nimport { canonicalJson, isSqliteConstraintError, parseJson } from \"./shared\"\n\nexport interface SqliteOntologyTransactionContext {\n readonly id: object\n readonly materializations: ProviderMaterializationTransactionLifecycle\n active: boolean\n}\n\nexport class SqliteMaterializationSessionState extends ProviderMaterializationSessionState {}\n\nexport class SqliteMaterializationSessions {\n private readonly sessions = new WeakMap<object, SqliteMaterializationSessionState>()\n private readonly live = new Set<SqliteMaterializationSessionState>()\n\n constructor(\n private readonly db: Database,\n private readonly context: SqliteOntologyTransactionContext | null\n ) {}\n\n create(header: MaterializationPlanHeader): SqliteMaterializationSessionState {\n if (!this.context?.active) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Materialization sessions require an active storage transaction.\"\n )\n }\n this.ensureTables()\n const session = new SqliteMaterializationSessionState(structuredClone(header), this.context.id)\n this.sessions.set(session.providerToken, session)\n this.live.add(session)\n this.context.materializations.register(session.providerToken)\n return session\n }\n\n require(session: MaterializationSession): SqliteMaterializationSessionState {\n const value = this.sessions.get(session.providerToken)\n if (\n !value ||\n !value.active ||\n !this.context?.active ||\n value.transactionId !== this.context.id\n ) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Materialization session is inactive.\"\n )\n }\n return value\n }\n\n release(session: SqliteMaterializationSessionState): void {\n if (!session.active) return\n this.deleteWork(session.id)\n session.active = false\n session.replacement = null\n this.live.delete(session)\n this.context?.materializations.complete(session.providerToken)\n }\n\n deactivateAll(): void {\n for (const session of this.live) this.release(session)\n }\n\n stage(input: StageMaterializationWorkInput): void {\n const session = this.require(input.session)\n const records = prepareMaterializationWork(session, input)\n const insert = this.db.query(\n `\n INSERT INTO ${SQLITE_MATERIALIZATION_WORK_TABLE} (\n session_id, record_key, unique_key, kind, lane,\n major_order, minor_order, sort_one, sort_two, payload\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, json(?))\n `\n )\n try {\n for (const { record, uniqueKey, columns } of records) {\n insert.run(\n session.id,\n record.recordKey,\n uniqueKey,\n record.kind,\n columns.lane,\n columns.majorOrder,\n columns.minorOrder,\n columns.sortOne,\n columns.sortTwo,\n canonicalJson(record)\n )\n }\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw duplicateWork(input.records[0]?.recordKey ?? \"unknown\")\n }\n throw error\n }\n }\n\n async *stream(input: StreamMaterializationWorkInput): AsyncIterable<MaterializationWorkPage> {\n const session = this.require(input.session)\n const stream = session.workStreams[input.order]\n if (stream.started) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Materialization ${input.order} work may only be streamed once per session.`\n )\n }\n stream.started = true\n session.workSealed = true\n let offset = 0\n while (true) {\n this.require(input.session)\n const rows = this.db\n .query(\n `\n SELECT payload\n FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND lane = ?\n ORDER BY major_order, minor_order, sort_one, sort_two, record_key\n LIMIT ? OFFSET ?\n `\n )\n .all(session.id, input.order, input.pageRows, offset) as { readonly payload: string }[]\n if (rows.length === 0) break\n const records = rows.map((row) =>\n parseJson<MaterializationWorkRecord>(row.payload)\n ) as MaterializationWorkPage[\"records\"]\n offset += records.length\n stream.emittedCount = offset\n yield { records }\n }\n this.require(input.session)\n stream.completed = true\n }\n\n readObjectExistence(\n session: SqliteMaterializationSessionState,\n refs: readonly { readonly objectTypeId: string; readonly primaryId: string }[]\n ): readonly {\n readonly ref: { readonly objectTypeId: string; readonly primaryId: string }\n readonly exists: boolean\n }[] {\n const lookup = this.db.query(\n `\n SELECT payload FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND unique_key = ? AND kind = 'object-existence'\n `\n )\n return refs.flatMap((ref) => {\n const key = `object-existence:${JSON.stringify([ref.objectTypeId, ref.primaryId])}`\n const row = lookup.get(session.id, key) as { readonly payload: string } | null\n if (!row) return []\n const record = parseJson<\n Extract<MaterializationWorkRecord, { readonly kind: \"object-existence\" }>\n >(row.payload)\n return [{ ref: record.ref, exists: record.exists }]\n })\n }\n\n assertChunkSequence(\n session: SqliteMaterializationSessionState,\n chunk: MaterializationPlanChunk\n ): void {\n const items = materializationPlanItems(chunk)\n const progress = correlateMaterializationChunk(\n session,\n chunk,\n items,\n this.planItems(session, session.appliedPlanCount, items.length),\n this.eventRecords(session, session.appliedOutboxCount, chunk.outbox.length)\n )\n session.appliedPlanCount = progress.appliedPlanCount\n session.appliedOutboxCount = progress.appliedOutboxCount\n }\n\n recordReplacementIdentities(\n session: SqliteMaterializationSessionState,\n identities: readonly ReplacementIdentity[]\n ): void {\n const upsert = this.db.query(\n `\n INSERT INTO ${SQLITE_REPLACEMENT_WORK_TABLE} (\n session_id, entity_kind, identity_key, diff_required\n ) VALUES (?, ?, ?, ?)\n ON CONFLICT(session_id, entity_kind, identity_key) DO UPDATE SET\n diff_required = MAX(diff_required, excluded.diff_required)\n `\n )\n for (const identity of identities) {\n upsert.run(\n session.id,\n identity.kind,\n identity.kind === \"object\" ? objectRefKey(identity.ref) : linkRefKey(identity.ref),\n identity.diffRequired ? 1 : 0\n )\n }\n }\n\n count(session: SqliteMaterializationSessionState, kind: string): number {\n const row = this.db\n .query(\n `SELECT COUNT(*) AS count FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = ?`\n )\n .get(session.id, kind) as { readonly count: number }\n return row.count\n }\n\n laneCounts(session: SqliteMaterializationSessionState): {\n readonly apply: number\n readonly cardinality: number\n readonly event: number\n } {\n const rows = this.db\n .query(\n `SELECT lane, COUNT(*) AS count FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND lane <> 'none'\n GROUP BY lane`\n )\n .all(session.id) as {\n readonly lane: \"apply\" | \"cardinality\" | \"event\"\n readonly count: number\n }[]\n const counts = { apply: 0, cardinality: 0, event: 0 }\n for (const row of rows) counts[row.lane] = row.count\n return counts\n }\n\n records(session: SqliteMaterializationSessionState, kind?: string): MaterializationWorkRecord[] {\n const rows = this.db\n .query(\n `SELECT payload FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? ${kind ? \"AND kind = ?\" : \"\"}`\n )\n .all(...(kind ? [session.id, kind] : [session.id])) as { readonly payload: string }[]\n return rows.map((row) => parseJson<MaterializationWorkRecord>(row.payload))\n }\n\n assertClassificationCoverage(session: SqliteMaterializationSessionState): void {\n if (!session.replacement) return\n const expectedObject = session.replacement.projectionKind === \"object\" ? 1 : 0\n const mismatch = this.db\n .query(\n `\n WITH expected AS (\n SELECT entity_kind, identity_key\n FROM ${SQLITE_REPLACEMENT_WORK_TABLE}\n WHERE session_id = ? AND diff_required = 1\n AND (entity_kind = 'link' OR ? = 1)\n ), actual AS (\n SELECT json_extract(payload, '$.entityKind') AS entity_kind,\n json_extract(payload, '$.identityKey') AS identity_key\n FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = 'classification'\n AND json_extract(payload, '$.entityKind') IN ('object', 'link')\n ), differences AS (\n SELECT * FROM expected EXCEPT SELECT * FROM actual\n UNION ALL\n SELECT * FROM actual EXCEPT SELECT * FROM expected\n )\n SELECT 1 FROM differences LIMIT 1\n `\n )\n .get(session.id, expectedObject, session.id)\n const pointClassifications = this.db\n .query(\n `\n SELECT 1 FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = 'classification'\n AND json_extract(payload, '$.entityKind') = 'point'\n LIMIT 1\n `\n )\n .get(session.id)\n if (mismatch || pointClassifications) {\n invalidCorrelation(\n \"Projection replacement classification coverage does not match its streamed state.\"\n )\n }\n }\n\n private planItems(\n session: SqliteMaterializationSessionState,\n offset: number,\n limit: number\n ): MaterializationPlanWorkItem[] {\n if (limit === 0) return []\n const rows = this.db\n .query(\n `\n SELECT payload FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND lane = 'apply'\n ORDER BY major_order, minor_order, sort_one, sort_two, record_key\n LIMIT ? OFFSET ?\n `\n )\n .all(session.id, limit, offset) as { readonly payload: string }[]\n return rows.map((row) => {\n const record = parseJson<Extract<MaterializationWorkRecord, { readonly kind: \"plan\" }>>(\n row.payload\n )\n return record.item\n })\n }\n\n private eventRecords(\n session: SqliteMaterializationSessionState,\n offset: number,\n limit: number\n ): MaterializationEventWorkRecord[] {\n if (limit === 0) return []\n const rows = this.db\n .query(\n `\n SELECT payload FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND lane = 'event'\n ORDER BY major_order, minor_order, sort_one, sort_two, record_key\n LIMIT ? OFFSET ?\n `\n )\n .all(session.id, limit, offset) as { readonly payload: string }[]\n return rows.map((row) => parseJson<MaterializationEventWorkRecord>(row.payload))\n }\n\n private ensureTables(): void {\n this.db.run(`\n CREATE TEMP TABLE IF NOT EXISTS ${SQLITE_MATERIALIZATION_WORK_TABLE} (\n session_id TEXT NOT NULL,\n record_key TEXT NOT NULL,\n unique_key TEXT NOT NULL,\n kind TEXT NOT NULL,\n lane TEXT NOT NULL,\n major_order INTEGER NOT NULL,\n minor_order INTEGER NOT NULL,\n sort_one TEXT NOT NULL,\n sort_two TEXT NOT NULL,\n payload TEXT NOT NULL CHECK (json_valid(payload)),\n PRIMARY KEY (session_id, record_key),\n UNIQUE (session_id, unique_key)\n );\n CREATE INDEX IF NOT EXISTS idx_ontology_materialization_work_lane\n ON ${SQLITE_MATERIALIZATION_WORK_TABLE}(\n session_id, lane, major_order, minor_order, sort_one, sort_two, record_key\n );\n CREATE TEMP TABLE IF NOT EXISTS ${SQLITE_REPLACEMENT_WORK_TABLE} (\n session_id TEXT NOT NULL,\n entity_kind TEXT NOT NULL,\n identity_key TEXT NOT NULL,\n diff_required INTEGER NOT NULL CHECK (diff_required IN (0, 1)),\n PRIMARY KEY (session_id, entity_kind, identity_key)\n );\n `)\n }\n\n private deleteWork(sessionId: string): void {\n this.db\n .query(`DELETE FROM ${SQLITE_MATERIALIZATION_WORK_TABLE} WHERE session_id = ?`)\n .run(sessionId)\n this.db\n .query(`DELETE FROM ${SQLITE_REPLACEMENT_WORK_TABLE} WHERE session_id = ?`)\n .run(sessionId)\n }\n}\n",
|
|
35
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n EffectiveLinkSnapshot,\n EffectiveObjectSnapshot,\n OntologyLinkRef,\n OntologyObjectRef,\n ProjectionEntityRef,\n TelemetrySeriesRef,\n} from \"@sixb/core/internal/materialization\"\nimport {\n linkRefKey,\n linkScopeSortKey,\n MaterializationConflictError,\n objectRefKey,\n projectionEntityKey,\n telemetryPointSortKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n appendScopeSnapshot,\n finishScopeAccumulator,\n startScopeAccumulator,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n MaterializationLinkScopeState,\n MaterializationLinkState,\n MaterializationObjectState,\n SourceReplacementLinkState,\n SourceReplacementObjectState,\n StoredLinkOverride,\n StoredObjectOverride,\n StoredSourceAssertion,\n StoredSourceLinkAssertion,\n StoredSourceObjectAssertion,\n StoredTelemetryPoint,\n} from \"@sixb/core/storage\"\nimport {\n canonicalJson,\n linkRefFromColumns,\n objectRefFromColumns,\n parseJson,\n type SqliteOntologyOverrideRow,\n type SqliteOntologySourceAssertionRow,\n} from \"./shared\"\n\nexport const SQLITE_MATERIALIZATION_WORK_TABLE = \"ontology_materialization_work\"\nexport const SQLITE_REPLACEMENT_WORK_TABLE = \"ontology_replacement_work\"\n\ninterface EffectiveObjectRow {\n readonly object_type_id: string\n readonly primary_id: string\n readonly properties: string\n readonly created_at: string\n readonly updated_at: string\n readonly version: number\n readonly last_commit_id: string | null\n}\n\ninterface EffectiveLinkRow {\n readonly source_type_id: string\n readonly source_id: string\n readonly link_id: string\n readonly target_type_id: string\n readonly target_id: string\n readonly properties: string | null\n readonly created_at: string\n readonly updated_at: string\n readonly last_commit_id: string | null\n}\n\ninterface TelemetryRow {\n readonly object_type_id: string\n readonly object_id: string\n readonly property_id: string\n readonly value: string\n readonly unit: string | null\n readonly at: string\n readonly last_commit_id: string | null\n}\n\ninterface LinkScopeRow extends EffectiveLinkRow {\n readonly scope_sort_key: string\n}\n\ninterface ObjectOverrideRow extends SqliteOntologyOverrideRow {\n readonly object_type_id: string\n readonly primary_id: string\n}\n\ninterface LinkOverrideRow extends SqliteOntologyOverrideRow {\n readonly source_type_id: string\n readonly source_primary_id: string\n readonly link_id: string\n readonly target_type_id: string\n readonly target_primary_id: string\n}\n\ninterface ReplacementSources {\n readonly owned: ReadonlySet<string>\n readonly byMaterialization: ReadonlyMap<string, ReadonlyMap<string, StoredSourceAssertion>>\n}\n\nexport type ReplacementIdentity =\n | {\n readonly kind: \"object\"\n readonly ref: OntologyObjectRef\n readonly sortKey: string\n readonly diffRequired: true\n }\n | {\n readonly kind: \"link\"\n readonly ref: OntologyLinkRef\n readonly sortKey: string\n readonly diffRequired: boolean\n }\n\ninterface ReplacementIdentityInput {\n readonly sessionId: string\n readonly sourceId: string\n readonly candidateMaterializationId: string\n readonly previousMaterializationId: string | null\n readonly kind: \"object\" | \"link\"\n readonly pageRows: number\n}\n\nexport class SqliteMaterializationStateReader {\n constructor(\n private readonly db: Database,\n readonly projectId: string\n ) {}\n\n objectState(ref: OntologyObjectRef): MaterializationObjectState {\n return this.objectStates([ref])[0]!\n }\n\n objectStates(refs: readonly OntologyObjectRef[]): readonly MaterializationObjectState[] {\n if (refs.length === 0) return []\n const requested = canonicalJson(\n refs.map((ref) => ({ objectTypeId: ref.objectTypeId, primaryId: ref.primaryId }))\n )\n const requestedObjects = `\n SELECT DISTINCT json_extract(value, '$.objectTypeId') AS object_type_id,\n json_extract(value, '$.primaryId') AS primary_id\n FROM json_each(?)\n `\n const effectiveRows = this.db\n .query(\n `WITH requested AS (${requestedObjects})\n SELECT objects.* FROM objects\n JOIN requested USING (object_type_id, primary_id)\n WHERE objects.project_id = ?`\n )\n .all(requested, this.projectId) as EffectiveObjectRow[]\n const sourceRows = this.db\n .query(\n `WITH requested AS (${requestedObjects})\n SELECT rows.* FROM ontology_source_rows AS rows\n JOIN requested USING (object_type_id, primary_id)\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ? AND rows.entity_kind = 'object'\n AND sources.status = 'active'`\n )\n .all(requested, this.projectId) as SqliteOntologySourceAssertionRow[]\n const overrideRows = this.db\n .query(\n `WITH requested AS (${requestedObjects})\n SELECT overrides.* FROM ontology_overrides AS overrides\n JOIN requested USING (object_type_id, primary_id)\n WHERE overrides.project_id = ? AND overrides.entity_kind = 'object'`\n )\n .all(requested, this.projectId) as ObjectOverrideRow[]\n const telemetryRows = this.db\n .query(\n `WITH requested AS (${requestedObjects}), ranked AS (\n SELECT timeseries.*,\n ROW_NUMBER() OVER (\n PARTITION BY timeseries.object_type_id, timeseries.object_id,\n timeseries.property_id\n ORDER BY timeseries.at DESC\n ) AS rank\n FROM timeseries\n JOIN requested\n ON requested.object_type_id = timeseries.object_type_id\n AND requested.primary_id = timeseries.object_id\n WHERE timeseries.project_id = ?\n )\n SELECT * FROM ranked WHERE rank = 1`\n )\n .all(requested, this.projectId) as TelemetryRow[]\n\n const effective = new Map(\n effectiveRows.map((row) => [objectRefKey(objectRefFromColumns(row)), row] as const)\n )\n const sources = activeSourceMap(sourceRows)\n const overrides = new Map(\n overrideRows.map(\n (row) => [objectRefKey(objectRefFromColumns(row)), storedObjectOverride(row)] as const\n )\n )\n const telemetry = new Map<string, StoredTelemetryPoint[]>()\n for (const row of telemetryRows) {\n const key = objectRefKey({ objectTypeId: row.object_type_id, primaryId: row.object_id })\n const points = telemetry.get(key) ?? []\n points.push(storedPoint(row))\n telemetry.set(key, points)\n }\n for (const points of telemetry.values()) {\n points.sort((left, right) =>\n telemetryPointSortKey(left.series, left.at).localeCompare(\n telemetryPointSortKey(right.series, right.at)\n )\n )\n }\n\n return refs.map((ref) => {\n const key = objectRefKey(ref)\n const effectiveRow = effective.get(key)\n return {\n ref: structuredClone(ref),\n source: sourceObject(sources.get(projectionEntityKey({ kind: \"object\", ref }))),\n override: overrides.get(key) ?? null,\n effective: effectiveRow ? effectiveObjectSnapshot(effectiveRow) : null,\n latestTelemetry: telemetry.get(key) ?? [],\n }\n })\n }\n\n linkState(ref: OntologyLinkRef): MaterializationLinkState {\n return this.linkStates([ref])[0]!\n }\n\n linkStates(refs: readonly OntologyLinkRef[]): readonly MaterializationLinkState[] {\n if (refs.length === 0) return []\n const requested = canonicalJson(\n refs.map((ref) => ({\n sourceTypeId: ref.source.objectTypeId,\n sourceId: ref.source.primaryId,\n linkId: ref.linkId,\n targetTypeId: ref.target.objectTypeId,\n targetId: ref.target.primaryId,\n }))\n )\n const effectiveRequest = `\n SELECT DISTINCT json_extract(value, '$.sourceTypeId') AS source_type_id,\n json_extract(value, '$.sourceId') AS source_id,\n json_extract(value, '$.linkId') AS link_id,\n json_extract(value, '$.targetTypeId') AS target_type_id,\n json_extract(value, '$.targetId') AS target_id\n FROM json_each(?)\n `\n const sourceRequest = `\n SELECT DISTINCT json_extract(value, '$.sourceTypeId') AS source_type_id,\n json_extract(value, '$.sourceId') AS source_primary_id,\n json_extract(value, '$.linkId') AS link_id,\n json_extract(value, '$.targetTypeId') AS target_type_id,\n json_extract(value, '$.targetId') AS target_primary_id\n FROM json_each(?)\n `\n const effectiveRows = this.db\n .query(\n `WITH requested AS (${effectiveRequest})\n SELECT links.* FROM links\n JOIN requested USING (source_type_id, source_id, link_id, target_type_id, target_id)\n WHERE links.project_id = ?`\n )\n .all(requested, this.projectId) as EffectiveLinkRow[]\n const sourceRows = this.db\n .query(\n `WITH requested AS (${sourceRequest})\n SELECT rows.* FROM ontology_source_rows AS rows\n JOIN requested USING (\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n )\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ? AND rows.entity_kind = 'link'\n AND sources.status = 'active'`\n )\n .all(requested, this.projectId) as SqliteOntologySourceAssertionRow[]\n const overrideRows = this.db\n .query(\n `WITH requested AS (${sourceRequest})\n SELECT overrides.* FROM ontology_overrides AS overrides\n JOIN requested USING (\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n )\n WHERE overrides.project_id = ? AND overrides.entity_kind = 'link'`\n )\n .all(requested, this.projectId) as LinkOverrideRow[]\n const effective = new Map(\n effectiveRows.map((row) => [linkRefKey(linkRefFromColumns(row)), row] as const)\n )\n const sources = activeSourceMap(sourceRows)\n const overrides = new Map(\n overrideRows.map(\n (row) => [linkRefKey(linkRefFromOverrideColumns(row)), storedLinkOverride(row)] as const\n )\n )\n return refs.map((ref) => {\n const key = linkRefKey(ref)\n const effectiveRow = effective.get(key)\n return {\n ref: structuredClone(ref),\n source: sourceLink(sources.get(projectionEntityKey({ kind: \"link\", ref }))),\n override: overrides.get(key) ?? null,\n effective: effectiveRow ? effectiveLinkSnapshot(effectiveRow) : null,\n }\n })\n }\n\n exactPoint(series: TelemetrySeriesRef, at: string): StoredTelemetryPoint | null {\n return this.exactPoints([{ series, at }])[0] ?? null\n }\n\n exactPoints(\n points: readonly { readonly series: TelemetrySeriesRef; readonly at: string }[]\n ): readonly StoredTelemetryPoint[] {\n if (points.length === 0) return []\n const requested = canonicalJson(\n points.map(({ series, at }) => ({\n objectTypeId: series.object.objectTypeId,\n objectId: series.object.primaryId,\n propertyId: series.propertyId,\n at,\n }))\n )\n const rows = this.db\n .query(\n `WITH requested AS (\n SELECT DISTINCT json_extract(value, '$.objectTypeId') AS object_type_id,\n json_extract(value, '$.objectId') AS object_id,\n json_extract(value, '$.propertyId') AS property_id,\n json_extract(value, '$.at') AS at\n FROM json_each(?)\n )\n SELECT timeseries.* FROM timeseries\n JOIN requested USING (object_type_id, object_id, property_id, at)\n WHERE timeseries.project_id = ?`\n )\n .all(requested, this.projectId) as TelemetryRow[]\n const found = new Map(\n rows.map((row) => {\n const point = storedPoint(row)\n return [telemetryPointSortKey(point.series, point.at), point] as const\n })\n )\n return points.flatMap((point) => {\n const stored = found.get(telemetryPointSortKey(point.series, point.at))\n return stored ? [stored] : []\n })\n }\n\n linkScopes(\n scopes: readonly { readonly source: OntologyObjectRef; readonly linkId: string }[]\n ): readonly MaterializationLinkScopeState[] {\n if (scopes.length === 0) return []\n const requested = scopes.map(({ source, linkId }) => ({\n scopeSortKey: linkScopeSortKey(source, linkId),\n sourceTypeId: source.objectTypeId,\n sourceId: source.primaryId,\n linkId,\n }))\n const accumulators = new Map(\n scopes.map(({ source, linkId }) => {\n const key = linkScopeSortKey(source, linkId)\n return [key, startScopeAccumulator(source, linkId, key)] as const\n })\n )\n const rows = this.db\n .query(\n `\n WITH requested AS (\n SELECT DISTINCT\n json_extract(value, '$.scopeSortKey') AS scope_sort_key,\n json_extract(value, '$.sourceTypeId') AS source_type_id,\n json_extract(value, '$.sourceId') AS source_id,\n json_extract(value, '$.linkId') AS link_id\n FROM json_each(?)\n )\n SELECT requested.scope_sort_key, links.*\n FROM links\n JOIN requested USING (source_type_id, source_id, link_id)\n WHERE links.project_id = ?\n ORDER BY requested.scope_sort_key, ${linkSortExpression(\"links\")}\n `\n )\n .iterate(canonicalJson(requested), this.projectId) as Iterable<LinkScopeRow>\n for (const row of rows) {\n const accumulator = accumulators.get(row.scope_sort_key)\n if (!accumulator) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Unexpected link scope '${row.scope_sort_key}' returned by storage.`\n )\n }\n appendScopeSnapshot(accumulator, effectiveLinkSnapshot(row))\n }\n return scopes.map(({ source, linkId }) =>\n finishScopeAccumulator(accumulators.get(linkScopeSortKey(source, linkId))!)\n )\n }\n\n linkScope(source: OntologyObjectRef, linkId: string): MaterializationLinkScopeState {\n const [scope] = this.linkScopes([{ source, linkId }])\n if (!scope) {\n throw new MaterializationConflictError(\n \"effective-state\",\n \"Link scope lookup returned no row.\"\n )\n }\n return scope\n }\n\n *incidentLinks(\n objects: readonly OntologyObjectRef[],\n pageRows: number\n ): Iterable<OntologyLinkRef[]> {\n if (objects.length === 0) return\n const values = objects.map(() => \"(?, ?)\").join(\", \")\n const args = objects.flatMap((ref) => [ref.objectTypeId, ref.primaryId])\n let cursor: string | null = null\n while (true) {\n const rows = this.db\n .query(\n `\n WITH requested(object_type_id, primary_id) AS (VALUES ${values}),\n authority_links AS (\n SELECT source_type_id, source_id, link_id, target_type_id, target_id\n FROM links WHERE project_id = ?\n UNION\n SELECT source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n FROM ontology_overrides\n WHERE project_id = ? AND entity_kind = 'link'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id, rows.link_id,\n rows.target_type_id, rows.target_primary_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ? AND rows.entity_kind = 'link' AND sources.status = 'active'\n ), selected AS (\n SELECT DISTINCT links.*,\n ${linkSortExpression(\"links\")} AS sort_key\n FROM authority_links AS links\n WHERE EXISTS (\n SELECT 1 FROM requested\n WHERE (requested.object_type_id = links.source_type_id\n AND requested.primary_id = links.source_id)\n OR (requested.object_type_id = links.target_type_id\n AND requested.primary_id = links.target_id)\n )\n )\n SELECT * FROM selected\n WHERE (? IS NULL OR sort_key > ?)\n ORDER BY sort_key\n LIMIT ?\n `\n )\n .all(\n ...args,\n this.projectId,\n this.projectId,\n this.projectId,\n cursor,\n cursor,\n pageRows\n ) as (EffectiveLinkRow & { readonly sort_key: string })[]\n if (rows.length === 0) break\n yield rows.map(linkRefFromColumns)\n cursor = rows[rows.length - 1]?.sort_key ?? null\n }\n }\n\n *replacementIdentities(input: ReplacementIdentityInput): Iterable<ReplacementIdentity[]> {\n let cursor: string | null = null\n while (true) {\n if (input.kind === \"object\") {\n const rows = this.replacementObjectRows(input, cursor)\n if (rows.length === 0) break\n yield rows.map((row) => ({\n kind: \"object\",\n ref: { objectTypeId: row.object_type_id, primaryId: row.primary_id },\n sortKey: row.sort_key,\n diffRequired: true,\n }))\n cursor = rows[rows.length - 1]?.sort_key ?? null\n continue\n }\n const rows = this.replacementLinkRows(input, cursor)\n if (rows.length === 0) break\n yield rows.map((row) => ({\n kind: \"link\",\n ref: linkRefFromColumns(row),\n sortKey: row.sort_key,\n diffRequired: row.diff_required === 1,\n }))\n cursor = rows[rows.length - 1]?.sort_key ?? null\n }\n }\n\n replacementObjectStates(\n sourceId: string,\n candidateMaterializationId: string,\n refs: readonly OntologyObjectRef[]\n ): readonly SourceReplacementObjectState[] {\n const base = this.objectStates(refs)\n const candidates = this.replacementSources(\n sourceId,\n [candidateMaterializationId],\n refs.map((ref) => ({ kind: \"object\" as const, ref }))\n )\n return base.map((state) => ({\n ref: state.ref,\n candidateSource: sourceObject(\n candidates.byMaterialization\n .get(candidateMaterializationId)\n ?.get(projectionEntityKey({ kind: \"object\", ref: state.ref }))\n ),\n override: state.override,\n effective: state.effective,\n latestTelemetry: state.latestTelemetry,\n }))\n }\n\n replacementLinkStates(\n sourceId: string,\n candidateMaterializationId: string,\n materializationIds: readonly string[],\n identities: readonly Extract<ReplacementIdentity, { readonly kind: \"link\" }>[]\n ): readonly SourceReplacementLinkState[] {\n const refs = identities.map((identity) => identity.ref)\n const base = this.linkStates(refs)\n const replacements = this.replacementSources(\n sourceId,\n materializationIds,\n refs.map((ref) => ({ kind: \"link\" as const, ref }))\n )\n const candidate = replacements.byMaterialization.get(candidateMaterializationId)\n return base.map((state, index) => {\n const key = projectionEntityKey({ kind: \"link\", ref: state.ref })\n return {\n ref: state.ref,\n candidateSource: replacements.owned.has(key)\n ? sourceLink(candidate?.get(key))\n : state.source,\n override: state.override,\n effective: state.effective,\n diffRequired: identities[index]!.diffRequired,\n }\n })\n }\n\n effectiveObjectRevision(ref: OntologyObjectRef): {\n readonly version: number\n readonly lastCommitId: string | null\n } | null {\n const row = this.db\n .query(\n `SELECT version, last_commit_id FROM objects\n WHERE project_id = ? AND object_type_id = ? AND primary_id = ?`\n )\n .get(this.projectId, ref.objectTypeId, ref.primaryId) as {\n readonly version: number\n readonly last_commit_id: string | null\n } | null\n return row ? { version: row.version, lastCommitId: row.last_commit_id } : null\n }\n\n effectiveLinkLastCommit(ref: OntologyLinkRef): string | null | undefined {\n const row = this.db\n .query(\n `\n SELECT last_commit_id FROM links\n WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?\n AND target_type_id = ? AND target_id = ?\n `\n )\n .get(\n this.projectId,\n ref.source.objectTypeId,\n ref.source.primaryId,\n ref.linkId,\n ref.target.objectTypeId,\n ref.target.primaryId\n ) as { readonly last_commit_id: string | null } | null\n return row ? row.last_commit_id : undefined\n }\n\n overrideLastCommit(kind: \"object\" | \"link\", entityKey: string): string | null {\n const row = this.db\n .query(\n `SELECT last_commit_id FROM ontology_overrides\n WHERE project_id = ? AND entity_kind = ? AND entity_key = ?`\n )\n .get(this.projectId, kind, entityKey) as { readonly last_commit_id: string } | null\n return row?.last_commit_id ?? null\n }\n\n private replacementSources(\n sourceId: string,\n materializationIds: readonly string[],\n refs: readonly ProjectionEntityRef[]\n ): ReplacementSources {\n if (materializationIds.length === 0 || refs.length === 0) {\n return { owned: new Set(), byMaterialization: new Map() }\n }\n const requestedKeys = canonicalJson(refs.map((ref) => projectionEntityKey(ref)))\n const requestedMaterializations = canonicalJson([...new Set(materializationIds)])\n const rows = this.db\n .query(\n `WITH requested_entities AS (\n SELECT value AS entity_key FROM json_each(?)\n ), requested_materializations AS (\n SELECT value AS materialization_id FROM json_each(?)\n )\n SELECT rows.* FROM ontology_source_rows AS rows\n JOIN requested_entities USING (entity_key)\n JOIN requested_materializations USING (materialization_id)\n WHERE rows.project_id = ? AND rows.source_id = ?`\n )\n .all(\n requestedKeys,\n requestedMaterializations,\n this.projectId,\n sourceId\n ) as SqliteOntologySourceAssertionRow[]\n const owned = new Set<string>()\n const byMaterialization = new Map<string, Map<string, StoredSourceAssertion>>()\n for (const row of rows) {\n const source = storedSource(row)\n const key = projectionEntityKey(source.assertion)\n owned.add(key)\n const materialization = byMaterialization.get(row.materialization_id) ?? new Map()\n materialization.set(key, source)\n byMaterialization.set(row.materialization_id, materialization)\n }\n return { owned, byMaterialization }\n }\n\n private replacementObjectRows(\n input: ReplacementIdentityInput,\n cursor: string | null\n ): (EffectiveObjectRow & { readonly sort_key: string })[] {\n return this.db\n .query(\n `\n SELECT DISTINCT object_type_id, primary_id, entity_sort_key AS sort_key\n FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND entity_kind = 'object'\n AND materialization_id IN (?, COALESCE(?, ''))\n AND (? IS NULL OR entity_sort_key > ?)\n ORDER BY sort_key\n LIMIT ?\n `\n )\n .all(\n this.projectId,\n input.sourceId,\n input.candidateMaterializationId,\n input.previousMaterializationId,\n cursor,\n cursor,\n input.pageRows\n ) as (EffectiveObjectRow & { readonly sort_key: string })[]\n }\n\n private replacementLinkRows(\n input: ReplacementIdentityInput,\n cursor: string | null\n ): (EffectiveLinkRow & { readonly sort_key: string; readonly diff_required: number })[] {\n return this.db\n .query(\n `\n WITH incident_objects AS (\n SELECT\n json_extract(payload, '$.ref.objectTypeId') AS object_type_id,\n json_extract(payload, '$.ref.primaryId') AS primary_id\n FROM ${SQLITE_MATERIALIZATION_WORK_TABLE}\n WHERE session_id = ? AND kind = 'incident-object'\n ), authority_links AS (\n SELECT source_type_id, source_id, link_id, target_type_id, target_id\n FROM links WHERE project_id = ?\n UNION\n SELECT source_type_id, source_primary_id, link_id, target_type_id, target_primary_id\n FROM ontology_overrides\n WHERE project_id = ? AND entity_kind = 'link'\n UNION\n SELECT rows.source_type_id, rows.source_primary_id, rows.link_id,\n rows.target_type_id, rows.target_primary_id\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ? AND rows.entity_kind = 'link' AND sources.status = 'active'\n ), replacement_links AS (\n SELECT source_type_id, source_primary_id AS source_id, link_id,\n target_type_id, target_primary_id AS target_id\n FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND entity_kind = 'link'\n AND materialization_id IN (?, COALESCE(?, ''))\n ), incident_links AS (\n SELECT links.* FROM authority_links AS links\n WHERE EXISTS (\n SELECT 1 FROM incident_objects\n WHERE (incident_objects.object_type_id = links.source_type_id\n AND incident_objects.primary_id = links.source_id)\n OR (incident_objects.object_type_id = links.target_type_id\n AND incident_objects.primary_id = links.target_id)\n )\n ), diff_links AS (\n SELECT * FROM replacement_links\n UNION SELECT * FROM incident_links\n ), affected_scopes AS (\n SELECT DISTINCT source_type_id, source_id, link_id FROM diff_links\n ), all_links AS (\n SELECT *, 1 AS diff_required FROM diff_links\n UNION ALL\n SELECT links.source_type_id, links.source_id, links.link_id,\n links.target_type_id, links.target_id, 0 AS diff_required\n FROM links\n JOIN affected_scopes USING (source_type_id, source_id, link_id)\n WHERE links.project_id = ?\n ), selected AS (\n SELECT source_type_id, source_id, link_id, target_type_id, target_id,\n ${linkSortExpression(\"all_links\")} AS sort_key,\n MAX(diff_required) AS diff_required\n FROM all_links\n GROUP BY source_type_id, source_id, link_id, target_type_id, target_id\n )\n SELECT * FROM selected\n WHERE (? IS NULL OR sort_key > ?)\n ORDER BY sort_key\n LIMIT ?\n `\n )\n .all(\n input.sessionId,\n this.projectId,\n this.projectId,\n this.projectId,\n this.projectId,\n input.sourceId,\n input.candidateMaterializationId,\n input.previousMaterializationId,\n this.projectId,\n cursor,\n cursor,\n input.pageRows\n ) as (EffectiveLinkRow & { readonly sort_key: string; readonly diff_required: number })[]\n }\n}\n\nfunction activeSourceMap(\n rows: readonly SqliteOntologySourceAssertionRow[]\n): ReadonlyMap<string, StoredSourceAssertion> {\n const result = new Map<string, StoredSourceAssertion>()\n for (const row of rows) {\n const source = storedSource(row)\n const key = projectionEntityKey(source.assertion)\n if (result.has(key)) {\n throw new MaterializationConflictError(\n \"source-materialization\",\n `Multiple active sources assert ${key}.`\n )\n }\n result.set(key, source)\n }\n return result\n}\n\nfunction sourceObject(\n source: StoredSourceAssertion | undefined\n): StoredSourceObjectAssertion | null {\n return source?.assertion.kind === \"object\" ? (source as StoredSourceObjectAssertion) : null\n}\n\nfunction sourceLink(source: StoredSourceAssertion | undefined): StoredSourceLinkAssertion | null {\n return source?.assertion.kind === \"link\" ? (source as StoredSourceLinkAssertion) : null\n}\n\nfunction storedObjectOverride(row: ObjectOverrideRow): StoredObjectOverride {\n const ref = objectRefFromColumns(row)\n return {\n ref,\n value: parseJson<StoredObjectOverride[\"value\"]>(row.value),\n lastCommitId: row.last_commit_id,\n updatedAt: row.updated_at,\n }\n}\n\nfunction storedLinkOverride(row: LinkOverrideRow): StoredLinkOverride {\n const ref = linkRefFromOverrideColumns(row)\n return {\n ref,\n value: parseJson<StoredLinkOverride[\"value\"]>(row.value),\n lastCommitId: row.last_commit_id,\n updatedAt: row.updated_at,\n }\n}\n\nfunction linkRefFromOverrideColumns(row: LinkOverrideRow): OntologyLinkRef {\n return {\n source: { objectTypeId: row.source_type_id, primaryId: row.source_primary_id },\n linkId: row.link_id,\n target: { objectTypeId: row.target_type_id, primaryId: row.target_primary_id },\n }\n}\n\nfunction storedSource(row: SqliteOntologySourceAssertionRow): StoredSourceAssertion {\n return {\n source: { projectionId: row.source_id },\n materializationId: row.materialization_id,\n root: parseJson<StoredSourceAssertion[\"root\"]>(row.root),\n assertion: parseJson<StoredSourceAssertion[\"assertion\"]>(row.assertion),\n stagingOrdinal: row.staging_ordinal,\n } as StoredSourceAssertion\n}\n\nfunction effectiveObjectSnapshot(row: EffectiveObjectRow): EffectiveObjectSnapshot {\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Effective object ${row.object_type_id}:${row.primary_id} lacks materializer provenance.`\n )\n }\n return {\n ref: objectRefFromColumns(row),\n properties: parseJson<EffectiveObjectSnapshot[\"properties\"]>(row.properties),\n version: row.version,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastCommitId: row.last_commit_id,\n }\n}\n\nfunction effectiveLinkSnapshot(row: EffectiveLinkRow): EffectiveLinkSnapshot {\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"effective-state\",\n `Effective link ${linkRefKey(linkRefFromColumns(row))} lacks materializer provenance.`\n )\n }\n return {\n ref: linkRefFromColumns(row),\n ...(row.properties === null\n ? {}\n : {\n properties: parseJson<NonNullable<EffectiveLinkSnapshot[\"properties\"]>>(row.properties),\n }),\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n lastCommitId: row.last_commit_id,\n }\n}\n\nfunction storedPoint(row: TelemetryRow): StoredTelemetryPoint {\n if (!row.last_commit_id) {\n throw new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointSortKey(\n {\n object: { objectTypeId: row.object_type_id, primaryId: row.object_id },\n propertyId: row.property_id,\n },\n row.at\n )} lacks materializer provenance.`\n )\n }\n return {\n series: {\n object: { objectTypeId: row.object_type_id, primaryId: row.object_id },\n propertyId: row.property_id,\n },\n value: parseJson<StoredTelemetryPoint[\"value\"]>(row.value),\n ...(row.unit === null ? {} : { unit: row.unit }),\n at: row.at,\n lastCommitId: row.last_commit_id,\n }\n}\n\nexport function objectSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return `LOWER(HEX(CAST(json_array(${prefix}object_type_id, ${prefix}primary_id) AS BLOB)))`\n}\n\nexport function linkSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return `LOWER(HEX(CAST(json_array(${prefix}source_type_id, ${prefix}source_id, ${prefix}link_id, ${prefix}target_type_id, ${prefix}target_id) AS BLOB)))`\n}\n\nexport function pointSortExpression(alias?: string): string {\n const prefix = alias ? `${alias}.` : \"\"\n return `LOWER(HEX(CAST(json_array(${prefix}object_type_id, ${prefix}object_id, ${prefix}property_id, ${prefix}at) AS BLOB)))`\n}\n",
|
|
36
|
+
"import type { Database } from \"bun:sqlite\"\nimport {\n linkRefKey,\n MaterializationConflictError,\n objectRefKey,\n telemetryPointKey,\n} from \"@sixb/core/internal/materialization\"\nimport {\n effectiveConflict,\n type OverrideEntity,\n overrideEntityColumns as overrideColumns,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n ExactEffectiveLinkWrite,\n ExactEffectiveObjectWrite,\n MaterializationPlanChunk,\n} from \"@sixb/core/storage\"\nimport { assertTimestamp, canonicalJson, isSqliteConstraintError, requireChanges } from \"./shared\"\n\n/** Applies one already-validated exact plan chunk to SQLite authority tables. */\nexport class SqliteMaterializationWriter {\n constructor(private readonly db: Database) {}\n\n apply(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {\n this.applyOverrides(projectId, chunk)\n this.applyEffective(projectId, chunk)\n this.applyTimeseries(projectId, chunk)\n this.applyOutbox(projectId, commitId, chunk)\n }\n\n private applyOverrides(projectId: string, chunk: MaterializationPlanChunk): void {\n const upsert = (\n entity: OverrideEntity,\n item:\n | (typeof chunk.overrides.objectUpserts)[number]\n | (typeof chunk.overrides.linkUpserts)[number]\n ): void => {\n const kind = entity.kind\n const key = kind === \"object\" ? objectRefKey(entity.ref) : linkRefKey(entity.ref)\n const columns = overrideColumns(entity)\n if (item.expectedLastCommitId === null) {\n try {\n this.db\n .query(\n `\n INSERT INTO ontology_overrides (\n project_id, entity_kind, entity_key, entity_sort_key,\n object_type_id, primary_id, source_type_id, source_primary_id,\n link_id, target_type_id, target_primary_id,\n value, last_commit_id, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, json(?), ?, ?)\n `\n )\n .run(\n projectId,\n kind,\n key,\n columns.sortKey,\n columns.objectTypeId,\n columns.primaryId,\n columns.sourceTypeId,\n columns.sourcePrimaryId,\n columns.linkId,\n columns.targetTypeId,\n columns.targetPrimaryId,\n canonicalJson(item.value),\n item.lastCommitId,\n item.updatedAt\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw effectiveConflict(`Expected ${kind} override changed.`)\n }\n throw error\n }\n } else {\n requireChanges(\n this.db\n .query(\n `\n UPDATE ontology_overrides\n SET value = json(?), last_commit_id = ?, updated_at = ?\n WHERE project_id = ? AND entity_kind = ? AND entity_key = ?\n AND last_commit_id = ?\n `\n )\n .run(\n canonicalJson(item.value),\n item.lastCommitId,\n item.updatedAt,\n projectId,\n kind,\n key,\n item.expectedLastCommitId\n ).changes,\n \"effective-state\",\n `Expected ${kind} override changed.`\n )\n }\n }\n for (const item of chunk.overrides.objectUpserts) {\n upsert({ kind: \"object\", ref: item.ref }, item)\n }\n for (const item of chunk.overrides.objectDeletes) {\n requireChanges(\n this.db\n .query(\n `DELETE FROM ontology_overrides\n WHERE project_id = ? AND entity_kind = 'object' AND entity_key = ? AND last_commit_id = ?`\n )\n .run(projectId, objectRefKey(item.ref), item.expectedLastCommitId).changes,\n \"effective-state\",\n \"Expected object override changed.\"\n )\n }\n for (const item of chunk.overrides.linkUpserts) {\n upsert({ kind: \"link\", ref: item.ref }, item)\n }\n for (const item of chunk.overrides.linkDeletes) {\n requireChanges(\n this.db\n .query(\n `DELETE FROM ontology_overrides\n WHERE project_id = ? AND entity_kind = 'link' AND entity_key = ? AND last_commit_id = ?`\n )\n .run(projectId, linkRefKey(item.ref), item.expectedLastCommitId).changes,\n \"effective-state\",\n \"Expected link override changed.\"\n )\n }\n }\n\n private applyEffective(projectId: string, chunk: MaterializationPlanChunk): void {\n for (const item of chunk.effective.linkDeletes) {\n requireChanges(\n this.db\n .query(\n `\n DELETE FROM links\n WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?\n AND target_type_id = ? AND target_id = ? AND last_commit_id = ?\n `\n )\n .run(\n projectId,\n item.ref.source.objectTypeId,\n item.ref.source.primaryId,\n item.ref.linkId,\n item.ref.target.objectTypeId,\n item.ref.target.primaryId,\n item.expected.lastCommitId\n ).changes,\n \"effective-state\",\n `Expected link ${linkRefKey(item.ref)} changed.`\n )\n }\n for (const item of chunk.effective.objectDeletes) {\n requireChanges(\n this.db\n .query(\n `DELETE FROM objects\n WHERE project_id = ? AND object_type_id = ? AND primary_id = ?\n AND version = ? AND last_commit_id = ?`\n )\n .run(\n projectId,\n item.ref.objectTypeId,\n item.ref.primaryId,\n item.expected.version,\n item.expected.lastCommitId\n ).changes,\n \"effective-state\",\n `Expected object ${objectRefKey(item.ref)} changed.`\n )\n }\n for (const item of chunk.effective.objectUpserts) this.applyObject(projectId, item)\n for (const item of chunk.effective.linkUpserts) this.applyLink(projectId, item)\n }\n\n private applyObject(projectId: string, item: ExactEffectiveObjectWrite): void {\n const { row, expected } = item\n if (!expected.exists) {\n try {\n this.db\n .query(\n `\n INSERT INTO objects (\n project_id, object_type_id, primary_id, properties, created_at,\n updated_at, version, last_commit_id\n ) VALUES (?, ?, ?, json(?), ?, ?, ?, ?)\n `\n )\n .run(\n projectId,\n row.ref.objectTypeId,\n row.ref.primaryId,\n canonicalJson(row.properties),\n row.createdAt,\n row.updatedAt,\n row.version,\n row.lastCommitId\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw effectiveConflict(`Expected object ${objectRefKey(row.ref)} to be absent.`)\n }\n throw error\n }\n return\n }\n requireChanges(\n this.db\n .query(\n `\n UPDATE objects\n SET properties = json(?), created_at = ?, updated_at = ?, version = ?,\n last_commit_id = ?\n WHERE project_id = ? AND object_type_id = ? AND primary_id = ?\n AND version = ? AND last_commit_id = ?\n `\n )\n .run(\n canonicalJson(row.properties),\n row.createdAt,\n row.updatedAt,\n row.version,\n row.lastCommitId,\n projectId,\n row.ref.objectTypeId,\n row.ref.primaryId,\n expected.version,\n expected.lastCommitId\n ).changes,\n \"effective-state\",\n `Expected object ${objectRefKey(row.ref)} changed.`\n )\n }\n\n private applyLink(projectId: string, item: ExactEffectiveLinkWrite): void {\n const { row, expected } = item\n if (!expected.exists) {\n try {\n this.db\n .query(\n `\n INSERT INTO links (\n project_id, source_type_id, source_id, link_id, target_type_id, target_id,\n properties, created_at, updated_at, last_commit_id\n ) VALUES (?, ?, ?, ?, ?, ?, json(?), ?, ?, ?)\n `\n )\n .run(\n projectId,\n row.ref.source.objectTypeId,\n row.ref.source.primaryId,\n row.ref.linkId,\n row.ref.target.objectTypeId,\n row.ref.target.primaryId,\n row.properties === undefined ? null : canonicalJson(row.properties),\n row.createdAt,\n row.updatedAt,\n row.lastCommitId\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw effectiveConflict(`Expected link ${linkRefKey(row.ref)} to be absent.`)\n }\n throw error\n }\n return\n }\n requireChanges(\n this.db\n .query(\n `\n UPDATE links\n SET properties = json(?), created_at = ?, updated_at = ?,\n last_commit_id = ?\n WHERE project_id = ? AND source_type_id = ? AND source_id = ? AND link_id = ?\n AND target_type_id = ? AND target_id = ? AND last_commit_id = ?\n `\n )\n .run(\n row.properties === undefined ? null : canonicalJson(row.properties),\n row.createdAt,\n row.updatedAt,\n row.lastCommitId,\n projectId,\n row.ref.source.objectTypeId,\n row.ref.source.primaryId,\n row.ref.linkId,\n row.ref.target.objectTypeId,\n row.ref.target.primaryId,\n expected.lastCommitId\n ).changes,\n \"effective-state\",\n `Expected link ${linkRefKey(row.ref)} changed.`\n )\n }\n\n private applyTimeseries(projectId: string, chunk: MaterializationPlanChunk): void {\n for (const item of chunk.timeseries.pointUpserts) {\n const { point, expected } = item\n if (expected.lastCommitId === null) {\n try {\n this.db\n .query(\n `\n INSERT INTO timeseries (\n project_id, object_type_id, object_id, property_id,\n value, unit, at, last_commit_id\n ) VALUES (?, ?, ?, ?, json(?), ?, ?, ?)\n `\n )\n .run(\n projectId,\n point.series.object.objectTypeId,\n point.series.object.primaryId,\n point.series.propertyId,\n canonicalJson(point.value),\n point.unit ?? null,\n point.at,\n point.lastCommitId\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw new MaterializationConflictError(\n \"timeseries-point\",\n `Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`\n )\n }\n throw error\n }\n } else {\n requireChanges(\n this.db\n .query(\n `\n UPDATE timeseries\n SET value = json(?), unit = ?, last_commit_id = ?\n WHERE project_id = ? AND object_type_id = ? AND object_id = ?\n AND property_id = ? AND at = ? AND last_commit_id = ?\n `\n )\n .run(\n canonicalJson(point.value),\n point.unit ?? null,\n point.lastCommitId,\n projectId,\n point.series.object.objectTypeId,\n point.series.object.primaryId,\n point.series.propertyId,\n point.at,\n expected.lastCommitId\n ).changes,\n \"timeseries-point\",\n `Telemetry point ${telemetryPointKey(point.series, point.at)} changed.`\n )\n }\n }\n }\n\n private applyOutbox(projectId: string, commitId: string, chunk: MaterializationPlanChunk): void {\n const insert = this.db.query(\n `\n INSERT INTO ontology_outbox (\n project_id, id, commit_id, commit_ordinal, envelope,\n available_at, attempts, lease_id, lease_expires_at,\n published_at, last_error, created_at\n ) VALUES (?, ?, ?, ?, json(?), ?, 0, NULL, NULL, NULL, NULL, ?)\n `\n )\n for (const item of chunk.outbox) {\n assertTimestamp(item.availableAt, \"Outbox availableAt\")\n assertTimestamp(item.createdAt, \"Outbox createdAt\")\n try {\n insert.run(\n projectId,\n item.envelope.id,\n commitId,\n item.envelope.commitOrdinal,\n canonicalJson(item.envelope),\n item.availableAt,\n item.createdAt\n )\n } catch (error) {\n if (isSqliteConstraintError(error)) {\n throw effectiveConflict(`Duplicate outbox event '${item.envelope.id}'.`)\n }\n throw error\n }\n }\n }\n}\n",
|
|
37
|
+
"import type { Database } from \"bun:sqlite\"\nimport {\n MaterializationConflictError,\n MaterializationValidationError,\n} from \"@sixb/core/internal/materialization\"\nimport type {\n ClaimedOntologyOutboxRow,\n ClaimOntologyOutboxInput,\n CompleteOntologyOutboxLeaseInput,\n OntologyOutboxStorage,\n OntologyOutboxSummary,\n PurgePublishedOntologyOutboxInput,\n RescheduleOntologyOutboxLeaseInput,\n SummarizeOntologyOutboxInput,\n} from \"@sixb/core/storage\"\nimport {\n assertNonblank,\n assertPositiveInteger,\n assertTimestamp,\n outboxRecord,\n type SqliteOntologyOutboxRow,\n type SqliteRootOperation,\n} from \"./shared\"\n\nexport class SqliteOntologyOutboxStorage implements OntologyOutboxStorage {\n constructor(\n private readonly db: Database,\n private readonly runRootOperation: SqliteRootOperation\n ) {}\n\n async claim(input: ClaimOntologyOutboxInput): Promise<readonly ClaimedOntologyOutboxRow[]> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertPositiveInteger(input.limit, \"Ontology outbox limit\")\n const now = assertTimestamp(input.now, \"Ontology outbox claim time\")\n const leaseExpiry = assertTimestamp(input.leaseExpiresAt, \"Ontology outbox lease expiry\")\n assertNonblank(input.leaseId, \"Ontology outbox lease id\")\n if (leaseExpiry <= now) {\n throw new MaterializationValidationError(\n \"Ontology outbox lease expiry must be later than the claim time.\"\n )\n }\n\n const rows = this.db\n .query(\n `\n UPDATE ontology_outbox\n SET attempts = attempts + 1, lease_id = ?, lease_expires_at = ?\n WHERE rowid IN (\n SELECT rowid\n FROM ontology_outbox\n WHERE project_id = ? AND published_at IS NULL AND available_at <= ?\n AND (lease_expires_at IS NULL OR lease_expires_at <= ?)\n ORDER BY created_at, commit_id, commit_ordinal\n LIMIT ?\n )\n RETURNING envelope, available_at, attempts, lease_id, lease_expires_at,\n published_at, last_error, created_at\n `\n )\n .all(\n input.leaseId,\n input.leaseExpiresAt,\n input.projectId,\n input.now,\n input.now,\n input.limit\n ) as SqliteOntologyOutboxRow[]\n return rows\n .map((row) => outboxRecord(row))\n .sort(\n (left, right) =>\n left.createdAt.localeCompare(right.createdAt) ||\n left.envelope.id.localeCompare(right.envelope.id)\n )\n .map((record) => {\n if (record.leaseId === null || record.leaseExpiresAt === null) {\n throw new MaterializationConflictError(\n \"outbox-lease\",\n \"Ontology outbox claim returned an unpaired lease.\"\n )\n }\n return { ...record, leaseId: record.leaseId, leaseExpiresAt: record.leaseExpiresAt }\n })\n })\n }\n\n async markPublished(input: CompleteOntologyOutboxLeaseInput): Promise<void> {\n await this.runRootOperation(() => {\n assertLeaseInput(input)\n assertTimestamp(input.publishedAt, \"Ontology outbox publishedAt\")\n const ids = validateLeaseIds(input.ids)\n const changed = this.db\n .query(\n `\n WITH requested(id) AS MATERIALIZED (\n SELECT CAST(value AS TEXT) FROM json_each(?)\n ), leased(id) AS MATERIALIZED (\n SELECT outbox.id FROM ontology_outbox AS outbox\n JOIN requested USING (id)\n WHERE outbox.project_id = ? AND outbox.lease_id = ?\n AND outbox.lease_expires_at IS NOT NULL\n ), eligible(id) AS (\n SELECT id FROM leased WHERE (SELECT COUNT(*) FROM leased) = ?\n )\n UPDATE ontology_outbox\n SET published_at = ?, lease_id = NULL, lease_expires_at = NULL\n WHERE project_id = ? AND id IN (SELECT id FROM eligible)\n AND lease_id = ? AND lease_expires_at IS NOT NULL\n `\n )\n .run(\n JSON.stringify(ids),\n input.projectId,\n input.leaseId,\n ids.length,\n input.publishedAt,\n input.projectId,\n input.leaseId\n ).changes\n if (changed !== ids.length) throw leaseConflict()\n })\n }\n\n async reschedule(input: RescheduleOntologyOutboxLeaseInput): Promise<void> {\n await this.runRootOperation(() => {\n assertLeaseInput(input)\n assertTimestamp(input.availableAt, \"Ontology outbox availableAt\")\n const ids = validateLeaseIds(input.ids)\n const changed = this.db\n .query(\n `\n WITH requested(id) AS MATERIALIZED (\n SELECT CAST(value AS TEXT) FROM json_each(?)\n ), leased(id) AS MATERIALIZED (\n SELECT outbox.id FROM ontology_outbox AS outbox\n JOIN requested USING (id)\n WHERE outbox.project_id = ? AND outbox.lease_id = ?\n AND outbox.lease_expires_at IS NOT NULL\n ), eligible(id) AS (\n SELECT id FROM leased WHERE (SELECT COUNT(*) FROM leased) = ?\n )\n UPDATE ontology_outbox\n SET available_at = ?, last_error = ?, lease_id = NULL, lease_expires_at = NULL\n WHERE project_id = ? AND id IN (SELECT id FROM eligible)\n AND lease_id = ? AND lease_expires_at IS NOT NULL\n `\n )\n .run(\n JSON.stringify(ids),\n input.projectId,\n input.leaseId,\n ids.length,\n input.availableAt,\n input.error,\n input.projectId,\n input.leaseId\n ).changes\n if (changed !== ids.length) throw leaseConflict()\n })\n }\n\n async purgePublished(input: PurgePublishedOntologyOutboxInput): Promise<number> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertPositiveInteger(input.limit, \"Ontology outbox limit\")\n assertTimestamp(input.publishedBefore, \"Ontology outbox purge cutoff\")\n return this.db\n .query(\n `\n DELETE FROM ontology_outbox\n WHERE rowid IN (\n SELECT rowid FROM ontology_outbox\n WHERE project_id = ? AND published_at IS NOT NULL AND published_at < ?\n ORDER BY published_at, id\n LIMIT ?\n )\n `\n )\n .run(input.projectId, input.publishedBefore, input.limit).changes\n })\n }\n\n async summarize(input: SummarizeOntologyOutboxInput): Promise<OntologyOutboxSummary> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n const summary = this.db\n .query(\n `\n SELECT COUNT(*) AS pending_count,\n MIN(created_at) AS oldest_pending_at,\n SUM(CASE WHEN attempts > 0 THEN 1 ELSE 0 END) AS retrying_count,\n COALESCE(MAX(attempts), 0) AS max_attempts\n FROM ontology_outbox\n WHERE project_id = ? AND published_at IS NULL\n `\n )\n .get(input.projectId) as {\n readonly pending_count: number\n readonly oldest_pending_at: string | null\n readonly retrying_count: number | null\n readonly max_attempts: number\n }\n return {\n pendingCount: summary.pending_count,\n oldestPendingAt: summary.oldest_pending_at,\n retryingCount: summary.retrying_count ?? 0,\n maxAttempts: summary.max_attempts,\n }\n })\n }\n}\n\nfunction validateLeaseIds(ids: readonly string[]): string[] {\n const seen = new Set<string>()\n for (const id of ids) {\n assertNonblank(id, \"Ontology outbox event id\")\n if (seen.has(id)) {\n throw new MaterializationValidationError(`Ontology outbox lease batch repeats event '${id}'.`)\n }\n seen.add(id)\n }\n return [...seen]\n}\n\nfunction assertLeaseInput(input: {\n readonly projectId: string\n readonly ids: readonly string[]\n readonly leaseId: string\n}): void {\n assertNonblank(input.projectId, \"Ontology outbox project id\")\n assertNonblank(input.leaseId, \"Ontology outbox lease id\")\n}\n\nfunction leaseConflict(): MaterializationConflictError {\n return new MaterializationConflictError(\"outbox-lease\", \"Ontology outbox lease does not match.\")\n}\n",
|
|
38
|
+
"import type { Database } from \"bun:sqlite\"\nimport { MaterializationValidationError } from \"@sixb/core/internal/materialization\"\nimport {\n assertSourceBeginInput as assertBeginInput,\n assertSourceExecutionIdentity as assertExecutionIdentity,\n assertSourceProject as assertProjectAndSource,\n assertSourceCandidateOwner,\n assertSourceWriteIdentity as assertWriteIdentity,\n sourceEntityColumns as entityColumns,\n isExactStagingManifest,\n reconcileSourceStageRows,\n type SourceStageRow,\n sourceConflict,\n sourceMaterializationIdentity,\n sourceStageRow,\n sourceStageRows,\n utf8SortKey,\n} from \"@sixb/core/internal/ontology-storage-provider\"\nimport type {\n AbandonSourceMaterializationCandidateInput,\n AbandonSourceMaterializationInput,\n AssertSourceMaterializationExecutionInput,\n BeginSourceMaterializationInput,\n CleanupTerminalSourceMaterializationsInput,\n CleanupTerminalSourceMaterializationsResult,\n GetActiveOntologySourceInput,\n MarkSourceMaterializationReadyInput,\n OntologySourceRecord,\n OntologySourceStorage,\n ReclaimSourceMaterializationInput,\n StageSourceRowsInput,\n StageSourceRowsResult,\n SummarizeTerminalSourceMaterializationsInput,\n TerminalSourceMaterializationSummary,\n} from \"@sixb/core/storage\"\nimport {\n assertNonblank,\n assertNonnegativeInteger,\n assertPositiveInteger,\n assertProjectionExecution,\n assertTimestamp,\n canonicalJson,\n type SqliteOntologySourceAssertionRow,\n type SqliteOntologySourceRow,\n type SqliteRootOperation,\n sourceAssertion,\n sourceRecord,\n} from \"./shared\"\n\nexport class SqliteOntologySourceStorage implements OntologySourceStorage {\n constructor(\n private readonly db: Database,\n private readonly runRootOperation: SqliteRootOperation\n ) {}\n\n async beginMaterialization(\n input: BeginSourceMaterializationInput\n ): Promise<OntologySourceRecord> {\n return this.runRootOperation(() => {\n assertBeginInput(input)\n this.assertExecution(input, sourceMaterializationIdentity(input))\n const existing = this.getManifest(\n input.projectId,\n input.source.projectionId,\n input.materializationId\n )\n if (existing) {\n if (isExactStagingManifest(sourceRecord(existing), input)) return sourceRecord(existing)\n throw sourceConflict(\n `Source materialization '${input.materializationId}' already exists with different identity or state.`\n )\n }\n\n const candidate = this.db\n .query(\n `\n SELECT 1\n FROM ontology_sources\n WHERE project_id = ? AND projection_run_id = ?\n AND status IN ('staging', 'ready')\n LIMIT 1\n `\n )\n .get(input.projectId, input.execution.projectionRunId)\n if (candidate) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' already has a nonterminal source materialization; reclaim it before beginning another.`\n )\n }\n\n this.db\n .query(\n `\n INSERT INTO ontology_sources (\n project_id, source_id, materialization_id, projection_run_id,\n projection_kind, protocol, status, execution_token,\n dataset_id, dataset_version_id, dataset_version_created_at,\n projection_revision, ownership_hash, ontology_revision,\n root_count, assertion_count, created_at, ready_at, activated_at,\n terminal_at, last_commit_id, updated_at\n ) VALUES (?, ?, ?, ?, ?, 'replacement', 'staging', ?, ?, ?, ?, ?, ?, ?,\n NULL, NULL, ?, NULL, NULL, NULL, NULL, ?)\n `\n )\n .run(\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n input.execution.projectionRunId,\n input.projectionKind,\n input.execution.executionToken,\n input.datasetVersion.datasetId,\n input.datasetVersion.versionId,\n input.datasetVersion.createdAt,\n input.projectionRevision,\n input.ownershipHash,\n input.ontologyRevision,\n input.createdAt,\n input.createdAt\n )\n return sourceRecord(\n this.requireManifest(input.projectId, input.source.projectionId, input.materializationId)\n )\n })\n }\n\n async stageRows(input: StageSourceRowsInput): Promise<StageSourceRowsResult> {\n return this.runRootOperation(() => {\n assertWriteIdentity(input)\n this.assertExecution(input)\n const manifest = this.requireManifest(\n input.projectId,\n input.source.projectionId,\n input.materializationId\n )\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n if (manifest.status !== \"staging\") {\n throw sourceConflict(\n `Source materialization '${input.materializationId}' is '${manifest.status}' and cannot accept rows.`\n )\n }\n\n const rows = sourceStageRows(manifest.projection_kind, input.rows)\n const existing = this.findStageRows(input, rows)\n const { pending, unchanged } = reconcileSourceStageRows(rows, existing)\n this.insertStageRows(input, pending)\n return { inserted: pending.length, unchanged }\n })\n }\n\n async markReady(input: MarkSourceMaterializationReadyInput): Promise<OntologySourceRecord> {\n return this.runRootOperation(() => {\n assertWriteIdentity(input)\n assertTimestamp(input.readyAt, \"Source readyAt\", true)\n assertNonnegativeInteger(input.rootCount, \"Source root count\")\n assertNonnegativeInteger(input.assertionCount, \"Source assertion count\")\n this.assertExecution(input)\n const manifest = this.requireManifest(\n input.projectId,\n input.source.projectionId,\n input.materializationId\n )\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n if (manifest.status === \"ready\") {\n if (\n manifest.root_count === input.rootCount &&\n manifest.assertion_count === input.assertionCount &&\n manifest.ready_at === input.readyAt\n ) {\n return sourceRecord(manifest)\n }\n throw sourceConflict(\n `Source materialization '${input.materializationId}' was marked ready with different counts or time.`\n )\n }\n if (manifest.status !== \"staging\") {\n throw sourceConflict(\n `Source materialization '${input.materializationId}' cannot transition from '${manifest.status}' to 'ready'.`\n )\n }\n if (input.readyAt < manifest.created_at) {\n throw new MaterializationValidationError(\"Source readyAt cannot precede source createdAt.\")\n }\n this.assertReadyState(manifest, input.rootCount, input.assertionCount)\n const result = this.db\n .query(\n `\n UPDATE ontology_sources\n SET status = 'ready', root_count = ?, assertion_count = ?, ready_at = ?, updated_at = ?\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND status = 'staging' AND execution_token = ?\n `\n )\n .run(\n input.rootCount,\n input.assertionCount,\n input.readyAt,\n input.readyAt,\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n input.execution.executionToken\n )\n if (result.changes !== 1) {\n throw sourceConflict(`Source materialization '${input.materializationId}' changed.`)\n }\n return sourceRecord(\n this.requireManifest(input.projectId, input.source.projectionId, input.materializationId)\n )\n })\n }\n\n async getActive(input: GetActiveOntologySourceInput): Promise<OntologySourceRecord | null> {\n return this.runRootOperation(() => {\n assertProjectAndSource(input)\n const row = this.db\n .query(\n `\n SELECT * FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND status = 'active'\n `\n )\n .get(input.projectId, input.source.projectionId) as SqliteOntologySourceRow | null\n return row ? sourceRecord(row) : null\n })\n }\n\n async abandon(input: AbandonSourceMaterializationCandidateInput): Promise<OntologySourceRecord>\n async abandon(input: ReclaimSourceMaterializationInput): Promise<OntologySourceRecord | null>\n async abandon(input: AbandonSourceMaterializationInput): Promise<OntologySourceRecord | null> {\n return this.runRootOperation(() => {\n assertProjectAndSource(input)\n assertExecutionIdentity(input.execution.projectionRunId, input.execution.executionToken)\n assertTimestamp(input.abandonedAt, \"Source abandonedAt\", true)\n this.assertExecution(input)\n return input.kind === \"candidate\"\n ? this.abandonCandidate(input)\n : this.abandonForReclaim(input)\n })\n }\n\n async cleanupTerminal(\n input: CleanupTerminalSourceMaterializationsInput\n ): Promise<CleanupTerminalSourceMaterializationsResult> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Terminal source cleanup project id\")\n assertTimestamp(input.terminalBefore, \"Terminal source cleanup cutoff\", true)\n assertPositiveInteger(input.limit, \"Terminal source cleanup limit\")\n const manifests = this.db\n .query(\n `\n SELECT * FROM ontology_sources\n WHERE project_id = ? AND status IN ('superseded', 'abandoned')\n AND terminal_at < ?\n ORDER BY terminal_at, source_id, materialization_id\n LIMIT ?\n `\n )\n .all(input.projectId, input.terminalBefore, input.limit) as SqliteOntologySourceRow[]\n let remaining = input.limit\n let rowsDeleted = 0\n let materializationsDeleted = 0\n for (const manifest of manifests) {\n if (remaining === 0) break\n const deleted = this.db\n .query(\n `\n DELETE FROM ontology_source_rows\n WHERE rowid IN (\n SELECT rows.rowid\n FROM ontology_source_rows AS rows\n JOIN ontology_sources AS sources\n ON sources.project_id = rows.project_id\n AND sources.source_id = rows.source_id\n AND sources.materialization_id = rows.materialization_id\n WHERE rows.project_id = ? AND rows.source_id = ? AND rows.materialization_id = ?\n AND sources.status IN ('superseded', 'abandoned')\n AND sources.terminal_at = ? AND sources.terminal_at < ?\n ORDER BY rows.entity_sort_key\n LIMIT ?\n )\n `\n )\n .run(\n manifest.project_id,\n manifest.source_id,\n manifest.materialization_id,\n manifest.terminal_at,\n input.terminalBefore,\n remaining\n ).changes\n rowsDeleted += deleted\n remaining -= deleted\n if (remaining === 0) break\n const removed = this.db\n .query(\n `\n DELETE FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND status IN ('superseded', 'abandoned')\n AND terminal_at = ? AND terminal_at < ?\n AND NOT EXISTS (\n SELECT 1 FROM ontology_source_rows AS rows\n WHERE rows.project_id = ontology_sources.project_id\n AND rows.source_id = ontology_sources.source_id\n AND rows.materialization_id = ontology_sources.materialization_id\n )\n `\n )\n .run(\n manifest.project_id,\n manifest.source_id,\n manifest.materialization_id,\n manifest.terminal_at,\n input.terminalBefore\n ).changes\n materializationsDeleted += removed\n remaining -= removed\n }\n return { rowsDeleted, materializationsDeleted }\n })\n }\n\n async summarizeTerminal(\n input: SummarizeTerminalSourceMaterializationsInput\n ): Promise<TerminalSourceMaterializationSummary> {\n return this.runRootOperation(() => {\n assertNonblank(input.projectId, \"Terminal source summary project id\")\n const summary = this.db\n .query(\n `\n SELECT COUNT(*) AS terminal_count, MIN(terminal_at) AS oldest_terminal_at\n FROM ontology_sources\n WHERE project_id = ? AND status IN ('superseded', 'abandoned')\n `\n )\n .get(input.projectId) as {\n readonly terminal_count: number\n readonly oldest_terminal_at: string | null\n }\n return {\n count: summary.terminal_count,\n oldestTerminalAt: summary.oldest_terminal_at,\n }\n })\n }\n\n private abandonCandidate(\n input: AbandonSourceMaterializationCandidateInput\n ): OntologySourceRecord {\n const manifest = this.requireManifest(\n input.projectId,\n input.source.projectionId,\n input.materializationId\n )\n if (manifest.status === \"abandoned\") {\n if (\n manifest.projection_run_id === input.execution.projectionRunId &&\n manifest.terminal_at === input.abandonedAt\n ) {\n return sourceRecord(manifest)\n }\n throw sourceConflict(\n `Source materialization '${input.materializationId}' was abandoned by another execution or at another time.`\n )\n }\n assertSourceCandidateOwner(sourceRecord(manifest), input.execution)\n return this.transitionToAbandoned(manifest, input.abandonedAt)\n }\n\n private abandonForReclaim(input: ReclaimSourceMaterializationInput): OntologySourceRecord | null {\n const candidates = this.db\n .query(\n `\n SELECT * FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND projection_run_id = ?\n AND status IN ('staging', 'ready')\n `\n )\n .all(\n input.projectId,\n input.source.projectionId,\n input.execution.projectionRunId\n ) as SqliteOntologySourceRow[]\n if (\n candidates.some((candidate) => candidate.execution_token === input.execution.executionToken)\n ) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' already has a source materialization owned by the current execution.`\n )\n }\n if (candidates.length > 1) {\n throw sourceConflict(\n `Projection run '${input.execution.projectionRunId}' has multiple nonterminal source materializations.`\n )\n }\n return candidates[0] ? this.transitionToAbandoned(candidates[0], input.abandonedAt) : null\n }\n\n private transitionToAbandoned(\n manifest: SqliteOntologySourceRow,\n abandonedAt: string\n ): OntologySourceRecord {\n if (\n abandonedAt < manifest.created_at ||\n (manifest.ready_at !== null && abandonedAt < manifest.ready_at)\n ) {\n throw new MaterializationValidationError(\n \"Source abandonedAt cannot precede source creation or readiness.\"\n )\n }\n const changed = this.db\n .query(\n `\n UPDATE ontology_sources\n SET status = 'abandoned', execution_token = NULL, terminal_at = ?, updated_at = ?\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND status IN ('staging', 'ready')\n `\n )\n .run(\n abandonedAt,\n abandonedAt,\n manifest.project_id,\n manifest.source_id,\n manifest.materialization_id\n ).changes\n if (changed !== 1) {\n throw sourceConflict(\n `Source materialization '${manifest.materialization_id}' cannot transition to 'abandoned'.`\n )\n }\n return sourceRecord(\n this.requireManifest(manifest.project_id, manifest.source_id, manifest.materialization_id)\n )\n }\n\n private assertReadyState(\n manifest: SqliteOntologySourceRow,\n rootCount: number,\n assertionCount: number\n ): void {\n const counts = this.db\n .query(\n `\n SELECT COUNT(*) AS assertions, COUNT(DISTINCT root_key) AS roots,\n COUNT(DISTINCT staging_ordinal) AS ordinals,\n MIN(staging_ordinal) AS min_ordinal, MAX(staging_ordinal) AS max_ordinal\n FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n `\n )\n .get(manifest.project_id, manifest.source_id, manifest.materialization_id) as {\n assertions: number\n roots: number\n ordinals: number\n min_ordinal: number | null\n max_ordinal: number | null\n }\n if (\n counts.assertions !== assertionCount ||\n counts.roots !== rootCount ||\n counts.ordinals !== rootCount ||\n (rootCount > 0 && (counts.min_ordinal !== 0 || counts.max_ordinal !== rootCount - 1))\n ) {\n throw new MaterializationValidationError(\n \"Source ready counts do not match the staged roots and assertions.\"\n )\n }\n const invalid = this.db\n .query(\n manifest.projection_kind === \"link\"\n ? `\n SELECT root_key\n FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n GROUP BY root_key\n HAVING COUNT(*) <> 1 OR MIN(root_kind) <> 'link' OR MIN(entity_kind) <> 'link'\n OR MIN(root_key) <> MIN(entity_key)\n LIMIT 1\n `\n : `\n SELECT root_key\n FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n GROUP BY root_key\n HAVING MIN(root_kind) <> 'object'\n OR SUM(CASE WHEN entity_kind = 'object' AND entity_key = root_key THEN 1 ELSE 0 END) <> 1\n OR SUM(CASE\n WHEN entity_kind = 'object' AND entity_key <> root_key THEN 1\n WHEN entity_kind = 'link' AND (\n source_type_id <> root_object_type_id OR source_primary_id <> root_primary_id\n ) THEN 1\n ELSE 0\n END) <> 0\n LIMIT 1\n `\n )\n .get(manifest.project_id, manifest.source_id, manifest.materialization_id)\n if (invalid) {\n throw new MaterializationValidationError(\n manifest.projection_kind === \"link\"\n ? \"Link projection roots must contain exactly their matching link assertion.\"\n : \"Object projection roots must contain exactly their matching object assertion plus links sourced from that root.\"\n )\n }\n }\n\n private findStageRows(\n input: StageSourceRowsInput,\n rows: readonly SourceStageRow[]\n ): readonly SourceStageRow[] {\n if (rows.length === 0) return []\n const rootSortKeys = [...new Set(rows.map((row) => utf8SortKey(row.rootKey)))]\n const ordinals = [...new Set(rows.map((row) => row.row.stagingOrdinal))]\n const entitySortKeys = [...new Set(rows.map((row) => utf8SortKey(row.entityKey)))]\n const existing = this.db\n .query(\n `\n SELECT * FROM ontology_source_rows\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n AND (\n root_sort_key IN (SELECT CAST(value AS TEXT) FROM json_each(?))\n OR staging_ordinal IN (SELECT CAST(value AS INTEGER) FROM json_each(?))\n OR entity_sort_key IN (SELECT CAST(value AS TEXT) FROM json_each(?))\n )\n `\n )\n .all(\n input.projectId,\n input.source.projectionId,\n input.materializationId,\n JSON.stringify(rootSortKeys),\n JSON.stringify(ordinals),\n JSON.stringify(entitySortKeys)\n ) as SqliteOntologySourceAssertionRow[]\n return existing.map((row) => sourceStageRow(sourceAssertion(row)))\n }\n\n private insertStageRows(input: StageSourceRowsInput, rows: readonly SourceStageRow[]): void {\n if (rows.length === 0) return\n const payload = rows.map(({ entityKey, rootKey, row }) => {\n const entity = entityColumns(row.assertion)\n const root = entityColumns(row.root)\n return {\n entityKind: row.assertion.kind,\n entityKey,\n entitySortKey: utf8SortKey(entityKey),\n rootKind: row.root.kind,\n rootKey,\n rootSortKey: utf8SortKey(rootKey),\n stagingOrdinal: row.stagingOrdinal,\n root: row.root,\n assertion: row.assertion,\n objectTypeId: entity.objectTypeId,\n primaryId: entity.primaryId,\n sourceTypeId: entity.sourceTypeId,\n sourcePrimaryId: entity.sourcePrimaryId,\n linkId: entity.linkId,\n targetTypeId: entity.targetTypeId,\n targetPrimaryId: entity.targetPrimaryId,\n rootObjectTypeId: root.objectTypeId,\n rootPrimaryId: root.primaryId,\n rootSourceTypeId: root.sourceTypeId,\n rootSourcePrimaryId: root.sourcePrimaryId,\n rootLinkId: root.linkId,\n rootTargetTypeId: root.targetTypeId,\n rootTargetPrimaryId: root.targetPrimaryId,\n }\n })\n this.db\n .query(\n `\n WITH staged(value) AS (SELECT value FROM json_each(?))\n INSERT INTO ontology_source_rows (\n project_id, source_id, materialization_id,\n entity_kind, entity_key, entity_sort_key,\n root_kind, root_key, root_sort_key, staging_ordinal,\n root, assertion,\n object_type_id, primary_id,\n source_type_id, source_primary_id, link_id, target_type_id, target_primary_id,\n root_object_type_id, root_primary_id,\n root_source_type_id, root_source_primary_id, root_link_id,\n root_target_type_id, root_target_primary_id\n )\n SELECT\n ?, ?, ?,\n json_extract(value, '$.entityKind'), json_extract(value, '$.entityKey'),\n json_extract(value, '$.entitySortKey'),\n json_extract(value, '$.rootKind'), json_extract(value, '$.rootKey'),\n json_extract(value, '$.rootSortKey'), json_extract(value, '$.stagingOrdinal'),\n json(json_extract(value, '$.root')), json(json_extract(value, '$.assertion')),\n json_extract(value, '$.objectTypeId'), json_extract(value, '$.primaryId'),\n json_extract(value, '$.sourceTypeId'), json_extract(value, '$.sourcePrimaryId'),\n json_extract(value, '$.linkId'), json_extract(value, '$.targetTypeId'),\n json_extract(value, '$.targetPrimaryId'),\n json_extract(value, '$.rootObjectTypeId'), json_extract(value, '$.rootPrimaryId'),\n json_extract(value, '$.rootSourceTypeId'),\n json_extract(value, '$.rootSourcePrimaryId'), json_extract(value, '$.rootLinkId'),\n json_extract(value, '$.rootTargetTypeId'), json_extract(value, '$.rootTargetPrimaryId')\n FROM staged\n `\n )\n .run(\n canonicalJson(payload),\n input.projectId,\n input.source.projectionId,\n input.materializationId\n )\n }\n\n private assertExecution(\n input: {\n readonly projectId: string\n readonly source: { readonly projectionId: string }\n readonly execution: { readonly projectionRunId: string; readonly executionToken: string }\n },\n identity?: AssertSourceMaterializationExecutionInput[\"identity\"]\n ): void {\n assertProjectionExecution(this.db, {\n projectId: input.projectId,\n sourceId: input.source.projectionId,\n projectionRunId: input.execution.projectionRunId,\n executionToken: input.execution.executionToken,\n ...(identity ? { identity } : {}),\n })\n }\n\n private getManifest(\n projectId: string,\n sourceId: string,\n materializationId: string\n ): SqliteOntologySourceRow | null {\n return this.db\n .query(\n `\n SELECT * FROM ontology_sources\n WHERE project_id = ? AND source_id = ? AND materialization_id = ?\n `\n )\n .get(projectId, sourceId, materializationId) as SqliteOntologySourceRow | null\n }\n\n private requireManifest(\n projectId: string,\n sourceId: string,\n materializationId: string\n ): SqliteOntologySourceRow {\n const row = this.getManifest(projectId, sourceId, materializationId)\n if (!row) throw sourceConflict(`Source materialization '${materializationId}' does not exist.`)\n return row\n }\n}\n",
|
|
39
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { OntologyStorage } from \"@sixb/core/storage\"\nimport { SqliteOntologyCommitStorage } from \"./commits\"\nimport type { SqliteOntologyTransactionContext } from \"./materialization-session\"\nimport { SqliteOntologyMaterializationStorage } from \"./materializations\"\nimport { SqliteOntologyOutboxStorage } from \"./outbox\"\nimport type { SqliteRootOperation } from \"./shared\"\nimport { SqliteOntologySourceStorage } from \"./sources\"\n\nexport class SqliteOntologyStorage implements OntologyStorage {\n readonly commits: SqliteOntologyCommitStorage\n readonly sources: SqliteOntologySourceStorage\n readonly materializations: SqliteOntologyMaterializationStorage\n readonly outbox: SqliteOntologyOutboxStorage\n\n constructor(input: {\n readonly db: Database\n readonly runRootOperation: SqliteRootOperation\n readonly transactionContext: SqliteOntologyTransactionContext | null\n }) {\n this.commits = new SqliteOntologyCommitStorage(input.db, input.runRootOperation)\n this.sources = new SqliteOntologySourceStorage(input.db, input.runRootOperation)\n this.materializations = new SqliteOntologyMaterializationStorage(\n input.db,\n input.transactionContext\n )\n this.outbox = new SqliteOntologyOutboxStorage(input.db, input.runRootOperation)\n }\n\n deactivateSessions(): void {\n this.materializations.deactivateSessions()\n }\n}\n\nexport type { SqliteOntologyTransactionContext } from \"./materialization-session\"\n",
|
|
40
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { DatasetVersionRef } from \"@sixb/core/lake-storage\"\nimport type {\n FinishPipelineRunInput,\n FinishPipelineStepRunInput,\n ListLatestPipelineRunsInput,\n ListLatestPipelineRunsResult,\n ListPipelineRunsInput,\n ListPipelineRunsResult,\n ListPipelineStepRunsInput,\n ListPipelineStepRunsResult,\n PipelineRunFailure,\n PipelineRunRecord,\n PipelineRunStorage,\n PipelineStepRunRecord,\n StartPipelineRunInput,\n StartPipelineStepRunInput,\n} from \"@sixb/core/storage\"\nimport { PipelineRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n appendRunListFilters,\n hasEmptyStatuses,\n queryRunList,\n type SqliteValue,\n} from \"./run-list-query\"\nimport { isUniqueConstraintError } from \"./storage-errors\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqlitePipelineRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqlitePipelineRunStorage implements PipelineRunStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqlitePipelineRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async start(input: StartPipelineRunInput): Promise<PipelineRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO pipeline_runs (\n project_id,\n id,\n pipeline_id,\n status,\n started_at\n ) VALUES (?, ?, ?, ?, ?)\n `\n )\n .run(input.projectId, input.id, input.pipelineId, \"running\", startedAt.toISOString())\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n const record = await this.getById({ projectId: input.projectId, id: input.id })\n if (!record) {\n throw new PipelineRunError(\n `[SixbSqlite] Failed to load pipeline run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return record\n }\n\n async finish(input: FinishPipelineRunInput): Promise<PipelineRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM pipeline_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as PipelineRunDatabaseRow | null\n\n if (!existing) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE pipeline_runs\n SET\n status = ?,\n finished_at = ?,\n output_dataset_id = ?,\n output_version_id = ?,\n error_name = ?,\n error_message = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\" ? (input.output?.datasetId ?? null) : null,\n input.status === \"succeeded\" ? (input.output?.versionId ?? null) : null,\n input.status === \"succeeded\" ? null : (input.error?.name ?? null),\n input.status === \"succeeded\" ? null : (input.error?.message ?? null),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM pipeline_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as PipelineRunDatabaseRow\n\n return rowToPipelineRunRecord(updated)\n })()\n }\n\n async startStep(input: StartPipelineStepRunInput): Promise<PipelineStepRunRecord> {\n return this.db.transaction(() => {\n const pipelineRun = this.db\n .query(\"SELECT * FROM pipeline_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.pipelineRunId) as PipelineRunDatabaseRow | null\n\n if (!pipelineRun) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run '${input.pipelineRunId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (pipelineRun.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run '${input.pipelineRunId}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n if (pipelineRun.pipeline_id !== input.pipelineId) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline step run '${input.id}' pipeline '${input.pipelineId}' does not match pipeline run '${input.pipelineRunId}' pipeline '${pipelineRun.pipeline_id}'.`\n )\n }\n\n const startedAt = input.startedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO pipeline_step_runs (\n project_id,\n id,\n pipeline_run_id,\n pipeline_id,\n step_id,\n dataset_id,\n mode,\n status,\n started_at,\n inputs\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.pipelineRunId,\n input.pipelineId,\n input.stepId,\n input.datasetId,\n input.mode,\n \"running\",\n startedAt.toISOString(),\n serializeDatasetVersionRefs(input.inputs)\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline step run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n const row = this.db\n .query(\"SELECT * FROM pipeline_step_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as PipelineStepRunDatabaseRow | null\n\n if (!row) {\n throw new PipelineRunError(\n `[SixbSqlite] Failed to load pipeline step run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return rowToPipelineStepRunRecord(row)\n })()\n }\n\n async finishStep(input: FinishPipelineStepRunInput): Promise<PipelineStepRunRecord> {\n assertOptionalNonNegativeInteger(input.rowsWritten, \"rowsWritten\")\n\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM pipeline_step_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as PipelineStepRunDatabaseRow | null\n\n if (!existing) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline step run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline step run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n if (input.status === \"succeeded\" && input.output.datasetId !== existing.dataset_id) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline step run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.dataset_id}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE pipeline_step_runs\n SET\n status = ?,\n finished_at = ?,\n output_version_id = ?,\n rows_written = ?,\n error_name = ?,\n error_message = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\" ? input.output.versionId : null,\n input.rowsWritten ?? existing.rows_written ?? null,\n input.status === \"succeeded\" ? null : (input.error?.name ?? null),\n input.status === \"succeeded\" ? null : (input.error?.message ?? null),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM pipeline_step_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as PipelineStepRunDatabaseRow\n\n return rowToPipelineStepRunRecord(updated)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<PipelineRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM pipeline_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as PipelineRunDatabaseRow | null\n\n return row ? rowToPipelineRunRecord(row) : null\n }\n\n async list(input: ListPipelineRunsInput): Promise<ListPipelineRunsResult> {\n if (hasEmptyStatuses(input) || input.pipelineIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.pipelineId) {\n whereClauses.push(\"pipeline_id = ?\")\n args.push(input.pipelineId)\n }\n\n if (input.pipelineIds) {\n whereClauses.push(`pipeline_id IN (${input.pipelineIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.pipelineIds)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<PipelineRunDatabaseRow>({\n db: this.db,\n tableName: \"pipeline_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToPipelineRunRecord),\n hasMore,\n total,\n }\n }\n\n async listLatestByPipelineIds(\n input: ListLatestPipelineRunsInput\n ): Promise<ListLatestPipelineRunsResult> {\n const rows = queryLatestRunsByOwnerId<PipelineRunDatabaseRow>({\n db: this.db,\n tableName: \"pipeline_runs\",\n ownerColumn: \"pipeline_id\",\n ownerIds: input.pipelineIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.pipeline_id,\n })\n\n return {\n runs: rows.map(rowToPipelineRunRecord),\n }\n }\n\n async listSteps(input: ListPipelineStepRunsInput): Promise<ListPipelineStepRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n steps: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.pipelineRunId) {\n whereClauses.push(\"pipeline_run_id = ?\")\n args.push(input.pipelineRunId)\n }\n\n if (input.pipelineId) {\n whereClauses.push(\"pipeline_id = ?\")\n args.push(input.pipelineId)\n }\n\n if (input.stepId) {\n whereClauses.push(\"step_id = ?\")\n args.push(input.stepId)\n }\n\n if (input.datasetId) {\n whereClauses.push(\"dataset_id = ?\")\n args.push(input.datasetId)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<PipelineStepRunDatabaseRow>({\n db: this.db,\n tableName: \"pipeline_step_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n steps: rows.map(rowToPipelineStepRunRecord),\n hasMore,\n total,\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\nfunction serializeDatasetVersionRefs(refs: readonly DatasetVersionRef[]): string {\n return JSON.stringify(refs)\n}\n\nfunction parseDatasetVersionRefs(value: string): readonly DatasetVersionRef[] {\n return JSON.parse(value) as readonly DatasetVersionRef[]\n}\n\nfunction toFailure(row: {\n readonly error_name: string | null\n readonly error_message: string | null\n}): PipelineRunFailure | undefined {\n if (!row.error_message) {\n return undefined\n }\n\n return {\n name: row.error_name ?? undefined,\n message: row.error_message,\n }\n}\n\nfunction rowToPipelineRunRecord(row: PipelineRunDatabaseRow): PipelineRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n pipelineId: row.pipeline_id,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n output:\n row.output_dataset_id && row.output_version_id\n ? {\n datasetId: row.output_dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n error: toFailure(row),\n }\n}\n\nfunction rowToPipelineStepRunRecord(row: PipelineStepRunDatabaseRow): PipelineStepRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n pipelineRunId: row.pipeline_run_id,\n pipelineId: row.pipeline_id,\n stepId: row.step_id,\n datasetId: row.dataset_id,\n mode: row.mode,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n inputs: parseDatasetVersionRefs(row.inputs),\n output: row.output_version_id\n ? {\n datasetId: row.dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n rowsWritten: row.rows_written ?? undefined,\n error: toFailure(row),\n }\n}\n\nfunction assertOptionalNonNegativeInteger(value: number | undefined, fieldName: string): void {\n if (value !== undefined && (!Number.isInteger(value) || value < 0)) {\n throw new PipelineRunError(\n `[SixbSqlite] Pipeline run ${fieldName} must be a non-negative integer.`\n )\n }\n}\n\ninterface PipelineRunDatabaseRow {\n project_id: string\n id: string\n pipeline_id: string\n status: PipelineRunRecord[\"status\"]\n started_at: string\n finished_at: string | null\n output_dataset_id: string | null\n output_version_id: string | null\n error_name: string | null\n error_message: string | null\n}\n\ninterface PipelineStepRunDatabaseRow {\n project_id: string\n id: string\n pipeline_run_id: string\n pipeline_id: string\n step_id: string\n dataset_id: string\n mode: PipelineStepRunRecord[\"mode\"]\n status: PipelineStepRunRecord[\"status\"]\n started_at: string\n finished_at: string | null\n inputs: string\n output_version_id: string | null\n rows_written: number | null\n error_name: string | null\n error_message: string | null\n}\n",
|
|
41
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { SqliteValue } from \"./run-list-query\"\n\ntype SqliteLatestRunTarget =\n | { readonly tableName: \"pipeline_runs\"; readonly ownerColumn: \"pipeline_id\" }\n | { readonly tableName: \"projection_runs\"; readonly ownerColumn: \"projection_id\" }\n | { readonly tableName: \"sync_runs\"; readonly ownerColumn: \"sync_id\" }\n | { readonly tableName: \"workflow_runs\"; readonly ownerColumn: \"workflow_id\" }\n\nexport function queryLatestRunsByOwnerId<TRow>(\n input: {\n readonly db: Database\n readonly ownerIds: readonly string[]\n readonly projectId: string\n readonly ownerIdFor: (row: TRow) => string\n } & SqliteLatestRunTarget\n): readonly TRow[] {\n const ownerIds = [...new Set(input.ownerIds)]\n if (ownerIds.length === 0) {\n return []\n }\n\n const placeholders = ownerIds.map(() => \"?\").join(\", \")\n const rows = input.db\n .query(\n `\n SELECT *\n FROM (\n SELECT\n *,\n ROW_NUMBER() OVER (\n PARTITION BY ${input.ownerColumn}\n ORDER BY started_at DESC, id DESC\n ) AS sixb_latest_rank\n FROM ${input.tableName}\n WHERE project_id = ? AND ${input.ownerColumn} IN (${placeholders})\n )\n WHERE sixb_latest_rank = 1\n `\n )\n .all(input.projectId, ...ownerIds) as (TRow & { sixb_latest_rank: SqliteValue })[]\n\n const latestByOwnerId = new Map(rows.map((row) => [input.ownerIdFor(row), row]))\n\n return ownerIds.flatMap((ownerId) => {\n const row = latestByOwnerId.get(ownerId)\n return row ? [row] : []\n })\n}\n",
|
|
42
|
+
"import type { Database } from \"bun:sqlite\"\nimport { randomUUID } from \"node:crypto\"\nimport {\n advanceProjectionTelemetry,\n assertGenericProgressDoesNotAdvanceTelemetry,\n assertProjectionMissingTarget,\n assertProjectionRunExecution,\n assertProjectionRunListWindow,\n assertProjectionRunNonEmpty,\n assertProjectionRunRunning,\n assertProjectionRunStartInput,\n createProjectionRunClaim,\n immutableDatasetVersionConflict,\n mergeProjectionRunProgress,\n type PersistedProjectionRunRecord,\n planProjectionRunFinish,\n planProjectionRunReclaim,\n projectionRunNotFound,\n publicProjectionRunRecord,\n requireTelemetryProjectionRun,\n restoreProjectionRun,\n type StoredProjectionRunRecord,\n staleProjectionRunExecution,\n} from \"@sixb/core/internal/projection-run-storage-provider\"\nimport type {\n AdvanceProjectionTelemetryCheckpointInput,\n FinishProjectionRunInput,\n ListLatestProjectionRunsInput,\n ListLatestProjectionRunsResult,\n ListProjectionRunsInput,\n ListProjectionRunsResult,\n LockProjectionRunForMaterializationInput,\n ProjectionKind,\n ProjectionRunClaim,\n ProjectionRunProgress,\n ProjectionRunRecord,\n ProjectionRunStatus,\n ProjectionRunStorage,\n RecordProjectionMissingTargetInput,\n StartOrReclaimProjectionRunInput,\n TelemetryProjectionRunRecord,\n UpdateProjectionRunInput,\n} from \"@sixb/core/storage\"\nimport { ProjectionRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n runImmediateTransaction,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteProjectionRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteProjectionRunStorage implements ProjectionRunStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteProjectionRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async startOrReclaim(input: StartOrReclaimProjectionRunInput): Promise<ProjectionRunClaim> {\n return runImmediateTransaction(this.db, () => {\n assertProjectionRunStartInput(input)\n\n const metadataConflict = this.db\n .query(\n `\n SELECT 1 FROM projection_runs\n WHERE project_id = ? AND id <> ? AND dataset_id = ? AND dataset_version_id = ?\n AND dataset_version_created_at IS NOT NULL\n AND dataset_version_created_at <> ?\n LIMIT 1\n `\n )\n .get(\n input.projectId,\n input.id,\n input.identity.datasetVersion.datasetId,\n input.identity.datasetVersion.versionId,\n input.identity.datasetVersion.createdAt\n )\n if (metadataConflict) {\n throw immutableDatasetVersionConflict(input.identity)\n }\n\n const existing = this.findRow(input.projectId, input.id)\n let attempt = 1\n if (existing) {\n const existingRecord = restoreProjectionRunRow(existing)\n attempt = planProjectionRunReclaim(existingRecord, input).attempt\n }\n\n const executionToken = createFreshExecutionToken(existing?.execution_token ?? null)\n\n if (existing) {\n const result = this.db\n .query(\n `\n UPDATE projection_runs\n SET attempt = ?, execution_token = ?\n WHERE project_id = ? AND id = ? AND status = 'running' AND execution_token = ?\n `\n )\n .run(attempt, executionToken, input.projectId, input.id, existing.execution_token)\n if (result.changes !== 1) throw staleProjectionRunExecution(input.id)\n } else {\n try {\n this.db\n .query(\n `\n INSERT INTO projection_runs (\n project_id,\n id,\n projection_id,\n projection_kind,\n materialization_protocol,\n dataset_id,\n dataset_version_id,\n dataset_version_created_at,\n ontology_revision,\n projection_revision,\n ownership_hash,\n object_type_id,\n source_object_type_id,\n target_object_type_id,\n status,\n started_at,\n attempt,\n execution_token,\n fixed_batch_size,\n next_batch_ordinal,\n next_row_offset,\n input_exhausted,\n source_rows_read,\n source_rows_skipped\n ) VALUES (\n ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', ?, 1, ?, ?, ?, ?, ?,\n 0, 0\n )\n `\n )\n .run(\n input.projectId,\n input.id,\n input.identity.projectionId,\n input.identity.projectionKind,\n input.identity.protocol,\n input.identity.datasetVersion.datasetId,\n input.identity.datasetVersion.versionId,\n input.identity.datasetVersion.createdAt,\n input.identity.ontologyRevision,\n input.identity.projectionRevision,\n input.identity.ownershipHash,\n \"objectTypeId\" in input.target ? input.target.objectTypeId : null,\n \"sourceObjectTypeId\" in input.target ? input.target.sourceObjectTypeId : null,\n \"sourceObjectTypeId\" in input.target ? input.target.targetObjectTypeId : null,\n (input.startedAt ?? new Date()).toISOString(),\n executionToken,\n input.fixedBatchSize ?? null,\n input.fixedBatchSize === undefined ? null : 0,\n input.fixedBatchSize === undefined ? null : 0,\n input.fixedBatchSize === undefined ? null : 0\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new ProjectionRunError(\n `[SixbSqlite] Projection run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n throw error\n }\n }\n\n return projectionRunClaim(this.requireRow(input.projectId, input.id))\n })\n }\n\n async lockForMaterialization(\n input: LockProjectionRunForMaterializationInput\n ): Promise<ProjectionRunRecord> {\n return rowToProjectionRunRecord(this.requireMaterializationExecution(input))\n }\n\n async update(input: UpdateProjectionRunInput): Promise<ProjectionRunRecord> {\n return runImmediateTransaction(this.db, () => {\n const existingRow = this.requireMaterializationExecution(input)\n const existing = restoreProjectionRunRow(existingRow)\n assertGenericProgressDoesNotAdvanceTelemetry(existing, input.progress)\n const progress = mergeProjectionRunProgress(existing.progress, input.progress)\n const result = this.updateProgress(existingRow, progress, input.executionToken)\n if (result !== 1) throw staleProjectionRunExecution(input.id)\n return rowToProjectionRunRecord(this.requireRow(input.projectId, input.id))\n })\n }\n\n async finish(input: FinishProjectionRunInput): Promise<ProjectionRunRecord> {\n return runImmediateTransaction(this.db, () => {\n const existingRow = this.requireMaterializationExecution(input)\n const plan = planProjectionRunFinish(restoreProjectionRunRow(existingRow), input)\n const result = this.db\n .query(\n `\n UPDATE projection_runs\n SET\n status = ?,\n finished_at = ?,\n execution_token = NULL,\n source_rows_read = ?,\n source_rows_skipped = ?,\n input_exhausted = ?,\n error_message = ?\n WHERE project_id = ? AND id = ? AND status = 'running' AND execution_token = ?\n `\n )\n .run(\n input.status,\n plan.finishedAt.toISOString(),\n plan.progress.sourceRowsRead,\n plan.progress.sourceRowsSkipped,\n plan.inputExhausted ? 1 : existingRow.input_exhausted,\n plan.errorMessage ?? null,\n input.projectId,\n input.id,\n input.executionToken\n )\n if (result.changes !== 1) throw staleProjectionRunExecution(input.id)\n return rowToProjectionRunRecord(this.requireRow(input.projectId, input.id))\n })\n }\n\n async advanceTelemetryCheckpoint(\n input: AdvanceProjectionTelemetryCheckpointInput\n ): Promise<TelemetryProjectionRunRecord> {\n return runImmediateTransaction(this.db, () => {\n const existing = this.requireMaterializationExecution(input)\n const advance = advanceProjectionTelemetry(restoreProjectionRunRow(existing), input)\n const result = this.db\n .query(\n `\n UPDATE projection_runs\n SET\n next_batch_ordinal = ?,\n next_row_offset = ?,\n input_exhausted = ?,\n source_rows_read = ?,\n source_rows_skipped = ?,\n missing_target_object_type_id = NULL,\n missing_target_object_id = NULL,\n missing_target_batch_ordinal = NULL,\n missing_target_first_seen_at = NULL\n WHERE project_id = ? AND id = ? AND status = 'running' AND execution_token = ?\n AND next_batch_ordinal = ? AND input_exhausted = 0\n `\n )\n .run(\n advance.checkpoint.nextBatchOrdinal,\n advance.checkpoint.nextRowOffset,\n advance.checkpoint.inputExhausted ? 1 : 0,\n advance.progress.sourceRowsRead,\n advance.progress.sourceRowsSkipped,\n input.projectId,\n input.id,\n input.executionToken,\n input.batchOrdinal\n )\n if (result.changes !== 1) throw staleProjectionRunExecution(input.id)\n return rowToTelemetryProjectionRunRecord(this.requireRow(input.projectId, input.id))\n })\n }\n\n async recordMissingTarget(\n input: RecordProjectionMissingTargetInput\n ): Promise<TelemetryProjectionRunRecord> {\n return runImmediateTransaction(this.db, () => {\n const existing = this.requireMaterializationExecution(input)\n const missingTarget = assertProjectionMissingTarget(\n requireTelemetryProjectionRun(restoreProjectionRunRow(existing)),\n input.missingTarget\n )\n const result = this.db\n .query(\n `\n UPDATE projection_runs\n SET\n missing_target_object_type_id = ?,\n missing_target_object_id = ?,\n missing_target_batch_ordinal = ?,\n missing_target_first_seen_at = ?\n WHERE project_id = ? AND id = ? AND status = 'running' AND execution_token = ?\n AND next_batch_ordinal = ?\n `\n )\n .run(\n missingTarget.objectTypeId,\n missingTarget.objectId,\n missingTarget.batchOrdinal,\n missingTarget.firstSeenAt.toISOString(),\n input.projectId,\n input.id,\n input.executionToken,\n missingTarget.batchOrdinal\n )\n if (result.changes !== 1) throw staleProjectionRunExecution(input.id)\n return rowToTelemetryProjectionRunRecord(this.requireRow(input.projectId, input.id))\n })\n }\n\n async getById(params: { projectId: string; id: string }): Promise<ProjectionRunRecord | null> {\n const row = this.findRow(params.projectId, params.id)\n return row ? rowToProjectionRunRecord(row) : null\n }\n\n async list(input: ListProjectionRunsInput): Promise<ListProjectionRunsResult> {\n assertProjectionRunNonEmpty(input.projectId, \"projectId\")\n\n if (input.statuses && input.statuses.length === 0) {\n return { runs: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: (string | number)[] = [input.projectId]\n\n if (input.projectionId) {\n whereClauses.push(\"projection_id = ?\")\n args.push(input.projectionId)\n }\n if (input.projectionKind) {\n whereClauses.push(\"projection_kind = ?\")\n args.push(input.projectionKind)\n }\n if (input.datasetId) {\n whereClauses.push(\"dataset_id = ?\")\n args.push(input.datasetId)\n }\n if (input.datasetVersionId) {\n whereClauses.push(\"dataset_version_id = ?\")\n args.push(input.datasetVersionId)\n }\n if (input.objectTypeIds) {\n if (input.objectTypeIds.length === 0) {\n return { runs: [], hasMore: false, total: 0 }\n }\n const placeholders = input.objectTypeIds.map(() => \"?\").join(\", \")\n whereClauses.push(\n `(object_type_id IN (${placeholders})` +\n ` OR (source_object_type_id IN (${placeholders})` +\n ` AND target_object_type_id IN (${placeholders})))`\n )\n args.push(...input.objectTypeIds, ...input.objectTypeIds, ...input.objectTypeIds)\n }\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n if (input.startedAfter) {\n whereClauses.push(\"started_at >= ?\")\n args.push(input.startedAfter.toISOString())\n }\n if (input.startedBefore) {\n whereClauses.push(\"started_at <= ?\")\n args.push(input.startedBefore.toISOString())\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n const limit = input.limit\n\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM projection_runs ${where}`)\n .get(...args) as { count: number }\n\n let query = `\n SELECT * FROM projection_runs\n ${where}\n ORDER BY started_at ${order}, id ${order}\n `\n const queryArgs = [...args]\n\n if (limit !== undefined) {\n assertProjectionRunListWindow(limit, \"limit\")\n assertProjectionRunListWindow(offset, \"offset\")\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(limit, offset)\n } else if (offset > 0) {\n assertProjectionRunListWindow(offset, \"offset\")\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = this.db.query(query).all(...queryArgs) as DatabaseRow[]\n const runs = rows.map(rowToProjectionRunRecord)\n return { runs, hasMore: offset + runs.length < totalRow.count, total: totalRow.count }\n }\n\n async listLatestByProjectionIds(\n input: ListLatestProjectionRunsInput\n ): Promise<ListLatestProjectionRunsResult> {\n const rows = queryLatestRunsByOwnerId<DatabaseRow>({\n db: this.db,\n tableName: \"projection_runs\",\n ownerColumn: \"projection_id\",\n ownerIds: input.projectionIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.projection_id,\n })\n return { runs: rows.map(rowToProjectionRunRecord) }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private updateProgress(\n existing: DatabaseRow,\n progress: ProjectionRunProgress,\n executionToken: string\n ): number {\n const args: (string | number)[] = [\n progress.sourceRowsRead,\n progress.sourceRowsSkipped,\n existing.project_id,\n existing.id,\n executionToken,\n ]\n const result = this.db\n .query(\n `\n UPDATE projection_runs\n SET\n source_rows_read = ?,\n source_rows_skipped = ?\n WHERE project_id = ? AND id = ? AND status = 'running'\n AND execution_token = ?\n `\n )\n .run(...args)\n return result.changes\n }\n\n private requireMaterializationExecution(\n input: LockProjectionRunForMaterializationInput\n ): DatabaseRow {\n const row = this.requireRunning(input.projectId, input.id)\n assertProjectionRunExecution(restoreProjectionRunRow(row), input)\n return row\n }\n\n private requireRunning(projectId: string, id: string): DatabaseRow {\n const row = this.requireRow(projectId, id)\n assertProjectionRunRunning(restoreProjectionRunRow(row))\n return row\n }\n\n private findRow(projectId: string, id: string): DatabaseRow | null {\n return this.db\n .query(\"SELECT * FROM projection_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as DatabaseRow | null\n }\n\n private requireRow(projectId: string, id: string): DatabaseRow {\n assertProjectionRunNonEmpty(projectId, \"projectId\")\n assertProjectionRunNonEmpty(id, \"id\")\n const row = this.findRow(projectId, id)\n if (!row) throw projectionRunNotFound(projectId, id)\n return row\n }\n}\n\nfunction createFreshExecutionToken(previous: string | null): string {\n let token = randomUUID()\n while (token === previous) token = randomUUID()\n return token\n}\n\nfunction rowToProjectionRunRecord(row: DatabaseRow): ProjectionRunRecord {\n return publicProjectionRunRecord(restoreProjectionRunRow(row))\n}\n\nfunction restoreProjectionRunRow(row: DatabaseRow): StoredProjectionRunRecord {\n const persisted: PersistedProjectionRunRecord = {\n id: row.id,\n projectId: row.project_id,\n projectionId: row.projection_id,\n projectionKind: row.projection_kind,\n protocol: row.materialization_protocol ?? undefined,\n datasetId: row.dataset_id,\n datasetVersionId: row.dataset_version_id,\n datasetVersionCreatedAt: row.dataset_version_created_at ?? undefined,\n ontologyRevision: row.ontology_revision ?? undefined,\n projectionRevision: row.projection_revision ?? undefined,\n ownershipHash: row.ownership_hash ?? undefined,\n objectTypeId: row.object_type_id ?? undefined,\n sourceObjectTypeId: row.source_object_type_id ?? undefined,\n targetObjectTypeId: row.target_object_type_id ?? undefined,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n attempt: databaseSafeInteger(row.attempt, \"attempt\"),\n executionToken: row.execution_token ?? undefined,\n fixedBatchSize: optionalDatabaseSafeInteger(row.fixed_batch_size, \"fixedBatchSize\"),\n nextBatchOrdinal: optionalDatabaseSafeInteger(row.next_batch_ordinal, \"nextBatchOrdinal\"),\n nextRowOffset: optionalDatabaseSafeInteger(row.next_row_offset, \"nextRowOffset\"),\n inputExhausted: row.input_exhausted === null ? undefined : row.input_exhausted === 1,\n missingTargetObjectTypeId: row.missing_target_object_type_id ?? undefined,\n missingTargetObjectId: row.missing_target_object_id ?? undefined,\n missingTargetBatchOrdinal: optionalDatabaseSafeInteger(\n row.missing_target_batch_ordinal,\n \"missingTargetBatchOrdinal\"\n ),\n missingTargetFirstSeenAt: row.missing_target_first_seen_at\n ? new Date(row.missing_target_first_seen_at)\n : undefined,\n progress: {\n sourceRowsRead: databaseSafeInteger(row.source_rows_read, \"sourceRowsRead\"),\n sourceRowsSkipped: databaseSafeInteger(row.source_rows_skipped, \"sourceRowsSkipped\"),\n },\n errorMessage: row.error_message ?? undefined,\n }\n return restoreProjectionRun(persisted)\n}\n\nfunction projectionRunClaim(row: DatabaseRow): ProjectionRunClaim {\n return createProjectionRunClaim(restoreProjectionRunRow(row))\n}\n\nfunction rowToTelemetryProjectionRunRecord(row: DatabaseRow): TelemetryProjectionRunRecord {\n return requireTelemetryProjectionRun(rowToProjectionRunRecord(row))\n}\n\nfunction optionalDatabaseSafeInteger(value: number | null, fieldName: string): number | undefined {\n return value === null ? undefined : databaseSafeInteger(value, fieldName)\n}\n\nfunction databaseSafeInteger(value: number, fieldName: string): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new ProjectionRunError(\n `[SixbSqlite] Projection run persisted ${fieldName} is not a non-negative safe integer.`\n )\n }\n return value\n}\n\nfunction isUniqueConstraintError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(\"UNIQUE constraint failed\")\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n projection_id: string\n projection_kind: ProjectionKind\n materialization_protocol: \"replacement\" | \"telemetry\" | null\n dataset_id: string\n dataset_version_id: string\n dataset_version_created_at: string | null\n ontology_revision: string | null\n projection_revision: string | null\n ownership_hash: string | null\n object_type_id: string | null\n source_object_type_id: string | null\n target_object_type_id: string | null\n status: ProjectionRunStatus\n started_at: string\n finished_at: string | null\n attempt: number\n execution_token: string | null\n fixed_batch_size: number | null\n next_batch_ordinal: number | null\n next_row_offset: number | null\n input_exhausted: 0 | 1 | null\n missing_target_object_type_id: string | null\n missing_target_object_id: string | null\n missing_target_batch_ordinal: number | null\n missing_target_first_seen_at: string | null\n source_rows_read: number\n source_rows_skipped: number\n error_message: string | null\n}\n",
|
|
43
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { RuleEventSubject } from \"@sixb/core\"\nimport type {\n ListActiveRuleStatesInput,\n ListActiveRuleStatesResult,\n ListRuleStatesReconciliationPageInput,\n ListRuleStatesReconciliationPageResult,\n RuleStateRecord,\n RuleStateTransitionEvent,\n RulesStorage,\n StoredRuleResolvedEvent,\n StoredRuleTriggeredEvent,\n} from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n runImmediateTransaction,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteRulesStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteRulesStorage implements RulesStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteRulesStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async getActive(params: {\n projectId: string\n ruleId: string\n subject: RuleEventSubject\n }): Promise<RuleStateRecord | null> {\n const row = this.db\n .query(\n `\n SELECT\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n FROM rule_states\n WHERE project_id = ?\n AND rule_id = ?\n AND subject_kind = ?\n AND object_type_id = ?\n AND primary_id = ?\n `\n )\n .get(\n params.projectId,\n params.ruleId,\n params.subject.kind,\n params.subject.objectTypeId,\n params.subject.primaryId\n ) as SqliteRuleStateRow | null\n\n return row ? rowToRuleStateRecord(row) : null\n }\n\n async getActiveBatch(params: {\n projectId: string\n items: readonly {\n readonly ruleId: string\n readonly subject: RuleEventSubject\n }[]\n }): Promise<readonly RuleStateRecord[]> {\n if (params.items.length === 0) return []\n const rows = this.db\n .query(\n `\n WITH requested AS (\n SELECT\n json_extract(value, '$.ruleId') AS rule_id,\n json_extract(value, '$.subject.kind') AS subject_kind,\n json_extract(value, '$.subject.objectTypeId') AS object_type_id,\n json_extract(value, '$.subject.primaryId') AS primary_id\n FROM json_each(?)\n )\n SELECT states.project_id, states.rule_id, states.subject_kind,\n states.object_type_id, states.primary_id, states.triggered_at\n FROM rule_states AS states\n JOIN requested USING (rule_id, subject_kind, object_type_id, primary_id)\n WHERE states.project_id = ?\n `\n )\n .all(JSON.stringify(params.items), params.projectId) as SqliteRuleStateRow[]\n return rows.map(rowToRuleStateRecord)\n }\n\n async listActive(input: ListActiveRuleStatesInput): Promise<ListActiveRuleStatesResult> {\n if (input.objectTypeIds?.length === 0) {\n return { states: [], hasMore: false, total: 0 }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: (string | number)[] = [input.projectId]\n\n if (input.ruleId) {\n whereClauses.push(\"rule_id = ?\")\n args.push(input.ruleId)\n }\n\n if (input.objectTypeId) {\n whereClauses.push(\"object_type_id = ?\")\n args.push(input.objectTypeId)\n }\n\n if (input.objectTypeIds) {\n whereClauses.push(`object_type_id IN (${input.objectTypeIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.objectTypeIds)\n }\n\n if (input.primaryId) {\n whereClauses.push(\"primary_id = ?\")\n args.push(input.primaryId)\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n const limit = input.limit\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM rule_states ${where}`)\n .get(...args) as { count: number }\n\n let query = `\n SELECT\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n FROM rule_states\n ${where}\n ORDER BY triggered_at ${order}, rule_id ${order}, object_type_id ${order}, primary_id ${order}\n `\n const queryArgs = [...args]\n\n if (limit !== undefined) {\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(limit, offset)\n } else if (offset > 0) {\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = this.db.query(query).all(...queryArgs) as SqliteRuleStateRow[]\n const states = rows.map(rowToRuleStateRecord)\n\n return {\n states,\n hasMore: offset + states.length < totalRow.count,\n total: totalRow.count,\n }\n }\n\n async listReconciliationPage(\n input: ListRuleStatesReconciliationPageInput\n ): Promise<ListRuleStatesReconciliationPageResult> {\n assertPositiveLimit(input.limit)\n const rows = this.db\n .query(\n `\n SELECT project_id, rule_id, subject_kind, object_type_id, primary_id, triggered_at\n FROM rule_states\n WHERE project_id = ? AND subject_kind = 'object'\n AND (\n ? IS NULL OR\n (rule_id, object_type_id, primary_id) > (?, ?, ?)\n )\n ORDER BY rule_id ASC, object_type_id ASC, primary_id ASC\n LIMIT ?\n `\n )\n .all(\n input.projectId,\n input.after?.ruleId ?? null,\n input.after?.ruleId ?? null,\n input.after?.objectTypeId ?? null,\n input.after?.primaryId ?? null,\n input.limit + 1\n ) as SqliteRuleStateRow[]\n return reconciliationPage(rows, input.limit)\n }\n\n async applyTriggered(event: StoredRuleTriggeredEvent): Promise<void> {\n this.db\n .query(\n `\n INSERT INTO rule_states (\n project_id,\n rule_id,\n subject_kind,\n object_type_id,\n primary_id,\n triggered_at\n ) VALUES (?, ?, ?, ?, ?, ?)\n ON CONFLICT(project_id, rule_id, subject_kind, object_type_id, primary_id)\n DO UPDATE SET triggered_at = excluded.triggered_at\n `\n )\n .run(\n event.projectId,\n event.payload.ruleId,\n event.payload.subject.kind,\n event.payload.subject.objectTypeId,\n event.payload.subject.primaryId,\n event.payload.triggeredAt\n )\n }\n\n async applyResolved(event: StoredRuleResolvedEvent): Promise<void> {\n this.db\n .query(\n `\n DELETE FROM rule_states\n WHERE project_id = ?\n AND rule_id = ?\n AND subject_kind = ?\n AND object_type_id = ?\n AND primary_id = ?\n `\n )\n .run(\n event.projectId,\n event.payload.ruleId,\n event.payload.subject.kind,\n event.payload.subject.objectTypeId,\n event.payload.subject.primaryId\n )\n }\n\n async applyTransitions(events: readonly RuleStateTransitionEvent[]): Promise<void> {\n if (events.length === 0) return\n const rows = events.map(transitionRow)\n\n runImmediateTransaction(this.db, () => {\n this.db\n .query(\n `\n WITH transitions AS (\n SELECT\n json_extract(value, '$.type') AS type,\n json_extract(value, '$.projectId') AS project_id,\n json_extract(value, '$.ruleId') AS rule_id,\n json_extract(value, '$.subjectKind') AS subject_kind,\n json_extract(value, '$.objectTypeId') AS object_type_id,\n json_extract(value, '$.primaryId') AS primary_id,\n json_extract(value, '$.transitionAt') AS transition_at\n FROM json_each(?)\n )\n INSERT INTO rule_states (\n project_id, rule_id, subject_kind, object_type_id, primary_id, triggered_at\n )\n SELECT project_id, rule_id, subject_kind, object_type_id, primary_id, transition_at\n FROM transitions\n WHERE type = 'rule.triggered'\n ON CONFLICT(project_id, rule_id, subject_kind, object_type_id, primary_id)\n DO UPDATE SET triggered_at = excluded.triggered_at\n `\n )\n .run(JSON.stringify(rows))\n\n this.db\n .query(\n `\n WITH transitions AS (\n SELECT\n json_extract(value, '$.type') AS type,\n json_extract(value, '$.projectId') AS project_id,\n json_extract(value, '$.ruleId') AS rule_id,\n json_extract(value, '$.subjectKind') AS subject_kind,\n json_extract(value, '$.objectTypeId') AS object_type_id,\n json_extract(value, '$.primaryId') AS primary_id\n FROM json_each(?)\n )\n DELETE FROM rule_states\n WHERE EXISTS (\n SELECT 1 FROM transitions\n WHERE transitions.type = 'rule.resolved'\n AND transitions.project_id = rule_states.project_id\n AND transitions.rule_id = rule_states.rule_id\n AND transitions.subject_kind = rule_states.subject_kind\n AND transitions.object_type_id = rule_states.object_type_id\n AND transitions.primary_id = rule_states.primary_id\n )\n `\n )\n .run(JSON.stringify(rows))\n })\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\nfunction transitionRow(event: RuleStateTransitionEvent) {\n return {\n type: event.type,\n projectId: event.projectId,\n ruleId: event.payload.ruleId,\n subjectKind: event.payload.subject.kind,\n objectTypeId: event.payload.subject.objectTypeId,\n primaryId: event.payload.subject.primaryId,\n transitionAt:\n event.type === \"rule.triggered\" ? event.payload.triggeredAt : event.payload.resolvedAt,\n }\n}\n\nfunction reconciliationPage(\n rows: readonly SqliteRuleStateRow[],\n limit: number\n): ListRuleStatesReconciliationPageResult {\n const hasMore = rows.length > limit\n const states = rows.slice(0, limit).map(rowToRuleStateRecord)\n const last = states.at(-1)\n return {\n states,\n ...(hasMore && last\n ? {\n next: {\n ruleId: last.ruleId,\n objectTypeId: last.subject.objectTypeId,\n primaryId: last.subject.primaryId,\n },\n }\n : {}),\n }\n}\n\nfunction assertPositiveLimit(limit: number): void {\n if (!Number.isSafeInteger(limit) || limit <= 0) {\n throw new Error(\"Rules reconciliation page limit must be a positive safe integer.\")\n }\n}\n\ninterface SqliteRuleStateRow {\n readonly project_id: string\n readonly rule_id: string\n readonly subject_kind: RuleEventSubject[\"kind\"]\n readonly object_type_id: string\n readonly primary_id: string\n readonly triggered_at: string\n}\n\nfunction rowToRuleStateRecord(row: SqliteRuleStateRow): RuleStateRecord {\n return {\n projectId: row.project_id,\n ruleId: row.rule_id,\n subject: {\n kind: row.subject_kind,\n objectTypeId: row.object_type_id,\n primaryId: row.primary_id,\n },\n triggeredAt: row.triggered_at,\n }\n}\n",
|
|
44
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { JsonValue } from \"@sixb/core\"\nimport type {\n FinishSyncRunInput,\n ListLatestSyncRunsInput,\n ListLatestSyncRunsResult,\n ListSyncRunsInput,\n ListSyncRunsResult,\n StartSyncRunInput,\n SyncRunFailure,\n SyncRunRecord,\n SyncRunStorage,\n} from \"@sixb/core/storage\"\nimport { SyncRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n appendRunListFilters,\n hasEmptyStatuses,\n queryRunList,\n type SqliteValue,\n} from \"./run-list-query\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteSyncRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteSyncRunStorage implements SyncRunStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteSyncRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async start(input: StartSyncRunInput): Promise<SyncRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO sync_runs (\n project_id,\n id,\n sync_id,\n dataset_id,\n mode,\n status,\n started_at,\n expected_latest_version_id,\n commit_message\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.syncId,\n input.datasetId,\n input.mode,\n \"running\",\n startedAt.toISOString(),\n input.expectedLatestVersionId ?? null,\n input.commitMessage ?? null\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new SyncRunError(\n `[SixbSqlite] Sync run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n const record = await this.getById({ projectId: input.projectId, id: input.id })\n if (!record) {\n throw new SyncRunError(\n `[SixbSqlite] Failed to load sync run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return record\n }\n\n async finish(input: FinishSyncRunInput): Promise<SyncRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM sync_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow | null\n\n if (!existing) {\n throw new SyncRunError(\n `[SixbSqlite] Sync run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (input.status === \"succeeded\") {\n if (input.output && input.output.datasetId !== existing.dataset_id) {\n throw new SyncRunError(\n `[SixbSqlite] Sync run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.dataset_id}'.`\n )\n }\n if (!input.output && (existing.mode !== \"append\" || input.rowsRead !== 0)) {\n throw new SyncRunError(\n `[SixbSqlite] Sync run '${input.id}' may omit its output only for an empty append.`\n )\n }\n }\n\n this.db\n .query(\n `\n UPDATE sync_runs\n SET\n status = ?,\n finished_at = ?,\n rows_read = ?,\n output_version_id = ?,\n error_name = ?,\n error_message = ?,\n checkpoint = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\"\n ? input.rowsRead\n : (input.rowsRead ?? existing.rows_read ?? null),\n input.status === \"succeeded\" ? (input.output?.versionId ?? null) : null,\n input.status === \"succeeded\" ? null : (input.error?.name ?? null),\n input.status === \"succeeded\" ? null : (input.error?.message ?? null),\n input.status === \"succeeded\" ? serializeCheckpoint(input.checkpoint) : null,\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM sync_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as DatabaseRow\n\n return rowToSyncRunRecord(updated)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<SyncRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM sync_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as DatabaseRow | null\n\n return row ? rowToSyncRunRecord(row) : null\n }\n\n async list(input: ListSyncRunsInput): Promise<ListSyncRunsResult> {\n if (hasEmptyStatuses(input) || input.syncIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.syncId) {\n whereClauses.push(\"sync_id = ?\")\n args.push(input.syncId)\n }\n\n if (input.syncIds) {\n whereClauses.push(`sync_id IN (${input.syncIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.syncIds)\n }\n\n if (input.datasetId) {\n whereClauses.push(\"dataset_id = ?\")\n args.push(input.datasetId)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<DatabaseRow>({\n db: this.db,\n tableName: \"sync_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToSyncRunRecord),\n hasMore,\n total,\n }\n }\n\n async listLatestBySyncIds(input: ListLatestSyncRunsInput): Promise<ListLatestSyncRunsResult> {\n const rows = queryLatestRunsByOwnerId<DatabaseRow>({\n db: this.db,\n tableName: \"sync_runs\",\n ownerColumn: \"sync_id\",\n ownerIds: input.syncIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.sync_id,\n })\n\n return {\n runs: rows.map(rowToSyncRunRecord),\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\nfunction serializeCheckpoint(checkpoint: JsonValue | undefined): string | null {\n return checkpoint !== undefined ? JSON.stringify(checkpoint) : null\n}\n\nfunction parseCheckpoint(value: string | null | undefined): JsonValue | undefined {\n return value != null ? (JSON.parse(value) as JsonValue) : undefined\n}\n\nfunction toSyncRunFailure(row: DatabaseRow): SyncRunFailure | undefined {\n if (!row.error_message) {\n return undefined\n }\n\n return {\n name: row.error_name ?? undefined,\n message: row.error_message,\n }\n}\n\nfunction rowToSyncRunRecord(row: DatabaseRow): SyncRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n syncId: row.sync_id,\n datasetId: row.dataset_id,\n mode: row.mode,\n status: row.status,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n rowsRead: row.rows_read ?? undefined,\n output: row.output_version_id\n ? {\n datasetId: row.dataset_id,\n versionId: row.output_version_id,\n }\n : undefined,\n expectedLatestVersionId: row.expected_latest_version_id ?? undefined,\n commitMessage: row.commit_message ?? undefined,\n error: toSyncRunFailure(row),\n checkpoint: parseCheckpoint(row.checkpoint),\n }\n}\n\nfunction isUniqueConstraintError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(\"UNIQUE constraint failed\")\n}\n\ninterface DatabaseRow {\n project_id: string\n id: string\n sync_id: string\n dataset_id: string\n mode: SyncRunRecord[\"mode\"]\n status: SyncRunRecord[\"status\"]\n started_at: string\n finished_at: string | null\n rows_read: number | null\n output_version_id: string | null\n expected_latest_version_id: string | null\n commit_message: string | null\n error_name: string | null\n error_message: string | null\n checkpoint: string | null\n}\n",
|
|
45
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n TimeseriesHistoryBatchInput,\n TimeseriesHistoryBatchResult,\n TimeseriesPoint,\n TimeseriesStorage,\n} from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteTimeseriesStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\n/**\n * SQLite-based TimeseriesStorage implementation.\n *\n * Stores time-series data with efficient querying for history and latest values.\n */\nexport class SqliteTimeseriesStorage implements TimeseriesStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteTimeseriesStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async getHistory(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n propertyId: string\n from?: Date\n to?: Date\n limit?: number\n order?: \"asc\" | \"desc\"\n }): Promise<readonly TimeseriesPoint[]> {\n let query = `\n SELECT * FROM timeseries\n WHERE project_id = ? AND object_type_id = ? AND object_id = ? AND property_id = ?\n `\n const args: (string | number | null)[] = [\n params.projectId,\n params.objectTypeId,\n params.objectId,\n params.propertyId,\n ]\n\n if (params.from) {\n query += \" AND at >= ?\"\n args.push(params.from.toISOString())\n }\n\n if (params.to) {\n query += \" AND at <= ?\"\n args.push(params.to.toISOString())\n }\n\n query += ` ORDER BY at ${params.order === \"desc\" ? \"DESC\" : \"ASC\"}`\n\n if (params.limit !== undefined) {\n query += \" LIMIT ?\"\n args.push(params.limit)\n }\n\n const rows = this.db.query(query).all(...args) as DatabaseRow[]\n\n return rows.map((row) => this.rowToPoint(row))\n }\n\n async getHistoryBatch(\n input: TimeseriesHistoryBatchInput\n ): Promise<readonly TimeseriesHistoryBatchResult[]> {\n if (input.series.length === 0) {\n return []\n }\n\n const order = input.order === \"desc\" ? \"DESC\" : \"ASC\"\n const values = input.series.map(() => \"(?, ?, ?, ?)\").join(\", \")\n const args: (string | number | null)[] = []\n\n input.series.forEach((series, index) => {\n args.push(index, series.objectTypeId, series.objectId, series.propertyId)\n })\n\n let query = `\n WITH requested(series_index, object_type_id, object_id, property_id) AS (\n VALUES ${values}\n ),\n ranked AS (\n SELECT\n requested.series_index,\n timeseries.*,\n ROW_NUMBER() OVER (\n PARTITION BY requested.series_index\n ORDER BY timeseries.at ${order}\n ) AS series_row_number\n FROM requested\n JOIN timeseries\n ON timeseries.project_id = ?\n AND timeseries.object_type_id = requested.object_type_id\n AND timeseries.object_id = requested.object_id\n AND timeseries.property_id = requested.property_id\n WHERE 1 = 1\n `\n args.push(input.projectId)\n\n if (input.from) {\n query += \" AND timeseries.at >= ?\"\n args.push(input.from.toISOString())\n }\n\n if (input.to) {\n query += \" AND timeseries.at <= ?\"\n args.push(input.to.toISOString())\n }\n\n query += \"\\n )\\n SELECT * FROM ranked\"\n\n if (input.limitPerSeries !== undefined) {\n query += \" WHERE series_row_number <= ?\"\n args.push(Math.max(0, input.limitPerSeries))\n }\n\n query += ` ORDER BY series_index ASC, at ${order}`\n\n const rows = this.db.query(query).all(...args) as (DatabaseRow & {\n series_index: number\n series_row_number: number\n })[]\n const results = input.series.map((series) => ({\n ...series,\n points: [] as TimeseriesPoint[],\n }))\n\n for (const row of rows) {\n const result = results[row.series_index]\n if (result) {\n result.points.push(this.rowToPoint(row))\n }\n }\n\n return results\n }\n\n async getLatest(params: {\n projectId: string\n objectTypeId: string\n objectId: string\n propertyId: string\n }): Promise<TimeseriesPoint | null> {\n const row = this.db\n .query(\n `\n SELECT * FROM timeseries\n WHERE project_id = ? AND object_type_id = ? AND object_id = ? AND property_id = ?\n ORDER BY at DESC\n LIMIT 1\n `\n )\n .get(\n params.projectId,\n params.objectTypeId,\n params.objectId,\n params.propertyId\n ) as DatabaseRow | null\n\n return row ? this.rowToPoint(row) : null\n }\n private rowToPoint(row: DatabaseRow): TimeseriesPoint {\n return {\n projectId: row.project_id,\n objectTypeId: row.object_type_id,\n objectId: row.object_id,\n propertyId: row.property_id,\n value: JSON.parse(row.value),\n unit: row.unit ?? undefined,\n at: new Date(row.at),\n lastCommitId: row.last_commit_id,\n }\n }\n\n /**\n * Close the database connection.\n */\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\ninterface DatabaseRow {\n project_id: string\n object_type_id: string\n object_id: string\n property_id: string\n value: string\n unit: string | null\n at: string\n last_commit_id: string\n}\n",
|
|
46
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n WebhookDeliveryClaimRecord,\n WebhookDeliveryClaimResult,\n WebhookDeliveryKey,\n WebhookDeliveryRecord,\n WebhookDeliveryStorage,\n} from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteWebhookDeliveryStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteWebhookDeliveryStorage implements WebhookDeliveryStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteWebhookDeliveryStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async claim(\n input: WebhookDeliveryKey & { receivedAt: string }\n ): Promise<WebhookDeliveryClaimRecord> {\n return this.db.transaction(() => {\n // Atomic first claim: only one request can insert this scoped delivery key.\n const inserted = this.db\n .query(\n `\n INSERT OR IGNORE INTO webhook_deliveries (\n project_id,\n connector_id,\n webhook_id,\n idempotency_key,\n status,\n received_at\n ) VALUES (?, ?, ?, ?, 'in_progress', ?)\n `\n )\n .run(\n input.projectId,\n input.connectorId,\n input.webhookId,\n input.idempotencyKey,\n input.receivedAt\n ) as { changes: number }\n\n if (inserted.changes > 0) {\n return toWebhookDeliveryClaimRecord(\n {\n projectId: input.projectId,\n connectorId: input.connectorId,\n webhookId: input.webhookId,\n idempotencyKey: input.idempotencyKey,\n status: \"in_progress\",\n receivedAt: input.receivedAt,\n },\n \"claimed\"\n )\n }\n\n const existing = this.getDeliveryRecord(input)\n\n if (existing?.status === \"completed\") {\n return toWebhookDeliveryClaimRecord(existing, \"duplicate\")\n }\n\n if (existing?.status === \"in_progress\") {\n return toWebhookDeliveryClaimRecord(existing, \"in_progress\")\n }\n\n if (existing?.status !== \"failed\") {\n throw new Error(\"[SixbSqlite] Webhook delivery row disappeared during claim.\")\n }\n\n // Failed deliveries are intentionally claimable so provider retries can run again.\n const claimed = this.db\n .query(\n `\n UPDATE webhook_deliveries\n SET status = 'in_progress',\n received_at = ?,\n completed_at = NULL,\n failed_at = NULL,\n error = NULL\n WHERE project_id = ?\n AND connector_id = ?\n AND webhook_id = ?\n AND idempotency_key = ?\n AND status = 'failed'\n `\n )\n .run(\n input.receivedAt,\n input.projectId,\n input.connectorId,\n input.webhookId,\n input.idempotencyKey\n ) as { changes: number }\n\n if (claimed.changes > 0) {\n return toWebhookDeliveryClaimRecord(this.requireDeliveryRecord(input, \"claim\"), \"claimed\")\n }\n\n const current = this.requireDeliveryRecord(input, \"claim\")\n return toWebhookDeliveryClaimRecord(\n current,\n current.status === \"completed\" ? \"duplicate\" : \"in_progress\"\n )\n })()\n }\n\n async complete(\n input: WebhookDeliveryKey & { completedAt: string }\n ): Promise<WebhookDeliveryRecord> {\n this.db\n .query(\n `\n UPDATE webhook_deliveries\n SET status = 'completed',\n completed_at = ?,\n failed_at = NULL,\n error = NULL\n WHERE project_id = ?\n AND connector_id = ?\n AND webhook_id = ?\n AND idempotency_key = ?\n `\n )\n .run(\n input.completedAt,\n input.projectId,\n input.connectorId,\n input.webhookId,\n input.idempotencyKey\n )\n\n return this.requireDeliveryRecord(input, \"complete\")\n }\n\n async fail(\n input: WebhookDeliveryKey & { failedAt: string; error: string }\n ): Promise<WebhookDeliveryRecord> {\n this.db\n .query(\n `\n UPDATE webhook_deliveries\n SET status = 'failed',\n failed_at = ?,\n error = ?\n WHERE project_id = ?\n AND connector_id = ?\n AND webhook_id = ?\n AND idempotency_key = ?\n `\n )\n .run(\n input.failedAt,\n input.error,\n input.projectId,\n input.connectorId,\n input.webhookId,\n input.idempotencyKey\n )\n\n return this.requireDeliveryRecord(input, \"fail\")\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private getDeliveryRecord(key: WebhookDeliveryKey): WebhookDeliveryRecord | null {\n const row = this.db\n .query(\n `\n SELECT\n project_id,\n connector_id,\n webhook_id,\n idempotency_key,\n status,\n received_at,\n completed_at,\n failed_at,\n error\n FROM webhook_deliveries\n WHERE project_id = ?\n AND connector_id = ?\n AND webhook_id = ?\n AND idempotency_key = ?\n `\n )\n .get(\n key.projectId,\n key.connectorId,\n key.webhookId,\n key.idempotencyKey\n ) as SqliteWebhookDeliveryRow | null\n\n return row ? toWebhookDeliveryRecord(row) : null\n }\n\n private requireDeliveryRecord(\n key: WebhookDeliveryKey,\n action: \"claim\" | \"complete\" | \"fail\"\n ): WebhookDeliveryRecord {\n const record = this.getDeliveryRecord(key)\n\n if (!record) {\n throw new Error(\n `[SixbSqlite] Missing webhook delivery row after ${action} for ${serializeKey(key)}.`\n )\n }\n\n return record\n }\n}\n\ninterface SqliteWebhookDeliveryRow {\n readonly project_id: string\n readonly connector_id: string\n readonly webhook_id: string\n readonly idempotency_key: string\n readonly status: WebhookDeliveryRecord[\"status\"]\n readonly received_at: string\n readonly completed_at: string | null\n readonly failed_at: string | null\n readonly error: string | null\n}\n\nfunction toWebhookDeliveryRecord(row: SqliteWebhookDeliveryRow): WebhookDeliveryRecord {\n return {\n projectId: row.project_id,\n connectorId: row.connector_id,\n webhookId: row.webhook_id,\n idempotencyKey: row.idempotency_key,\n status: row.status,\n receivedAt: row.received_at,\n completedAt: row.completed_at ?? undefined,\n failedAt: row.failed_at ?? undefined,\n error: row.error ?? undefined,\n }\n}\n\nfunction toWebhookDeliveryClaimRecord(\n record: WebhookDeliveryRecord,\n claimResult: WebhookDeliveryClaimResult\n): WebhookDeliveryClaimRecord {\n return {\n ...record,\n claimResult,\n }\n}\n\nfunction serializeKey(key: WebhookDeliveryKey): string {\n return JSON.stringify([key.projectId, key.connectorId, key.webhookId, key.idempotencyKey])\n}\n",
|
|
47
|
+
"import type { Database } from \"bun:sqlite\"\nimport type {\n FinishWebhookRunInput,\n ListWebhookRunsInput,\n ListWebhookRunsResult,\n StartWebhookRunInput,\n WebhookRunRecord,\n WebhookRunStorage,\n} from \"@sixb/core/storage\"\nimport { WebhookRunError } from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n appendRunListFilters,\n hasEmptyStatuses,\n queryRunList,\n type SqliteValue,\n} from \"./run-list-query\"\nimport { isUniqueConstraintError } from \"./storage-errors\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteWebhookRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteWebhookRunStorage implements WebhookRunStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteWebhookRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async start(input: StartWebhookRunInput): Promise<WebhookRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO webhook_runs (\n project_id,\n id,\n connector_id,\n webhook_id,\n status,\n method,\n route,\n started_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.connectorId,\n input.webhookId,\n \"running\",\n input.method,\n input.route,\n startedAt.toISOString()\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WebhookRunError(\n `[SixbSqlite] Webhook run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n const record = await this.getById({ projectId: input.projectId, id: input.id })\n if (!record) {\n throw new WebhookRunError(\n `[SixbSqlite] Failed to load webhook run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return record\n }\n\n async finish(input: FinishWebhookRunInput): Promise<WebhookRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM webhook_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WebhookRunDatabaseRow | null\n\n if (!existing) {\n throw new WebhookRunError(\n `[SixbSqlite] Webhook run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new WebhookRunError(\n `[SixbSqlite] Webhook run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE webhook_runs\n SET\n status = ?,\n finished_at = ?,\n request_body_bytes = ?,\n response_status = ?,\n idempotency_key = ?,\n delivery_claim_result = ?,\n error = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.requestBodyBytes ?? null,\n input.responseStatus ?? null,\n input.idempotencyKey ?? null,\n input.deliveryClaimResult ?? null,\n input.status === \"succeeded\" ? null : (input.error ?? null),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM webhook_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WebhookRunDatabaseRow\n\n return rowToWebhookRunRecord(updated)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WebhookRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM webhook_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as WebhookRunDatabaseRow | null\n\n return row ? rowToWebhookRunRecord(row) : null\n }\n\n async list(input: ListWebhookRunsInput): Promise<ListWebhookRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.connectorId) {\n whereClauses.push(\"connector_id = ?\")\n args.push(input.connectorId)\n }\n\n if (input.webhookId) {\n whereClauses.push(\"webhook_id = ?\")\n args.push(input.webhookId)\n }\n\n if (input.idempotencyKey) {\n whereClauses.push(\"idempotency_key = ?\")\n args.push(input.idempotencyKey)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<WebhookRunDatabaseRow>({\n db: this.db,\n tableName: \"webhook_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToWebhookRunRecord),\n hasMore,\n total,\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n}\n\nfunction rowToWebhookRunRecord(row: WebhookRunDatabaseRow): WebhookRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n connectorId: row.connector_id,\n webhookId: row.webhook_id,\n status: row.status,\n method: row.method,\n route: row.route,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n requestBodyBytes: row.request_body_bytes ?? undefined,\n responseStatus: row.response_status ?? undefined,\n idempotencyKey: row.idempotency_key ?? undefined,\n deliveryClaimResult: row.delivery_claim_result ?? undefined,\n error: row.error ?? undefined,\n }\n}\n\ninterface WebhookRunDatabaseRow {\n readonly project_id: string\n readonly id: string\n readonly connector_id: string\n readonly webhook_id: string\n readonly status: WebhookRunRecord[\"status\"]\n readonly method: string\n readonly route: string\n readonly started_at: string\n readonly finished_at: string | null\n readonly request_body_bytes: number | null\n readonly response_status: number | null\n readonly idempotency_key: string | null\n readonly delivery_claim_result: WebhookRunRecord[\"deliveryClaimResult\"] | null\n readonly error: string | null\n}\n",
|
|
48
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { WorkflowIOSnapshot } from \"@sixb/core/internal/workflows\"\nimport type {\n CancelWorkflowInterventionInput,\n CreateWorkflowInterventionInput,\n ExpireWorkflowInterventionInput,\n ListWorkflowInterventionsInput,\n ListWorkflowInterventionsResult,\n SubmitWorkflowInterventionInput,\n WorkflowInterventionActor,\n WorkflowInterventionRecord,\n WorkflowInterventionStorage,\n} from \"@sixb/core/storage\"\nimport { WorkflowInterventionError } from \"@sixb/core/storage\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport { isUniqueConstraintError } from \"./storage-errors\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteWorkflowInterventionStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteWorkflowInterventionStorage implements WorkflowInterventionStorage {\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteWorkflowInterventionStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n }\n\n async create(input: CreateWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n assertNonNegativeInteger(input.nodeIndex, \"nodeIndex\")\n\n try {\n this.db\n .query(\n `\n INSERT INTO workflow_interventions (\n project_id,\n id,\n workflow_id,\n workflow_run_id,\n node_run_id,\n node_index,\n node_id,\n node_key,\n intervention_id,\n input,\n default_response,\n status,\n requested_at,\n expires_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.workflowId,\n input.workflowRunId,\n input.nodeRunId,\n input.nodeIndex,\n input.nodeId,\n input.nodeKey,\n input.interventionId,\n serializeRecord(input.input),\n serializeRecord(input.defaultResponse),\n \"pending\",\n (input.requestedAt ?? new Date()).toISOString(),\n input.expiresAt?.toISOString() ?? null\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WorkflowInterventionError(\n `[SixbSqlite] Workflow intervention '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n return this.requireIntervention(input.projectId, input.id)\n }\n\n async submit(input: SubmitWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return this.db.transaction(() => {\n const existing = this.requirePendingIntervention(input.projectId, input.id)\n\n this.db\n .query(\n `\n UPDATE workflow_interventions\n SET\n status = ?,\n submitted_at = ?,\n submitted_by = ?,\n response = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"submitted\",\n (input.submittedAt ?? new Date()).toISOString(),\n serializeActor(input.submittedBy),\n serializeRecord(input.response),\n existing.project_id,\n existing.id\n )\n\n return this.requireIntervention(input.projectId, input.id)\n })()\n }\n\n async cancel(input: CancelWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return this.db.transaction(() => {\n const existing = this.requirePendingIntervention(input.projectId, input.id)\n\n this.db\n .query(\n `\n UPDATE workflow_interventions\n SET\n status = ?,\n cancelled_at = ?,\n cancelled_by = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"cancelled\",\n (input.cancelledAt ?? new Date()).toISOString(),\n serializeActor(input.cancelledBy),\n existing.project_id,\n existing.id\n )\n\n return this.requireIntervention(input.projectId, input.id)\n })()\n }\n\n async expire(input: ExpireWorkflowInterventionInput): Promise<WorkflowInterventionRecord> {\n return this.db.transaction(() => {\n const existing = this.requirePendingIntervention(input.projectId, input.id)\n\n this.db\n .query(\n `\n UPDATE workflow_interventions\n SET\n status = ?,\n expired_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"expired\",\n (input.expiredAt ?? new Date()).toISOString(),\n existing.project_id,\n existing.id\n )\n\n return this.requireIntervention(input.projectId, input.id)\n })()\n }\n\n async getById(params: {\n projectId: string\n id: string\n }): Promise<WorkflowInterventionRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as WorkflowInterventionDatabaseRow | null\n\n return row ? rowToWorkflowInterventionRecord(row) : null\n }\n\n async list(input: ListWorkflowInterventionsInput): Promise<ListWorkflowInterventionsResult> {\n if ((input.statuses && input.statuses.length === 0) || input.workflowIds?.length === 0) {\n return {\n interventions: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.statuses) {\n whereClauses.push(`status IN (${input.statuses.map(() => \"?\").join(\", \")})`)\n args.push(...input.statuses)\n }\n\n if (input.workflowId) {\n whereClauses.push(\"workflow_id = ?\")\n args.push(input.workflowId)\n }\n\n if (input.workflowIds) {\n whereClauses.push(`workflow_id IN (${input.workflowIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.workflowIds)\n }\n\n if (input.workflowRunId) {\n whereClauses.push(\"workflow_run_id = ?\")\n args.push(input.workflowRunId)\n }\n\n if (input.nodeRunId) {\n whereClauses.push(\"node_run_id = ?\")\n args.push(input.nodeRunId)\n }\n\n if (input.nodeId) {\n whereClauses.push(\"node_id = ?\")\n args.push(input.nodeId)\n }\n\n if (input.nodeKey) {\n whereClauses.push(\"node_key = ?\")\n args.push(input.nodeKey)\n }\n\n if (input.interventionId) {\n whereClauses.push(\"intervention_id = ?\")\n args.push(input.interventionId)\n }\n\n if (input.requestedAfter) {\n whereClauses.push(\"requested_at >= ?\")\n args.push(input.requestedAfter.toISOString())\n }\n\n if (input.requestedBefore) {\n whereClauses.push(\"requested_at <= ?\")\n args.push(input.requestedBefore.toISOString())\n }\n\n const where = `WHERE ${whereClauses.join(\" AND \")}`\n const order = input.order === \"asc\" ? \"ASC\" : \"DESC\"\n const offset = input.offset ?? 0\n const totalRow = this.db\n .query(`SELECT COUNT(*) AS count FROM workflow_interventions ${where}`)\n .get(...args) as { count: number }\n\n let query = `\n SELECT * FROM workflow_interventions\n ${where}\n ORDER BY requested_at ${order}, id ${order}\n `\n const queryArgs = [...args]\n\n if (input.limit !== undefined) {\n query += \" LIMIT ? OFFSET ?\"\n queryArgs.push(input.limit, offset)\n } else if (offset > 0) {\n query += \" LIMIT -1 OFFSET ?\"\n queryArgs.push(offset)\n }\n\n const rows = this.db.query(query).all(...queryArgs) as WorkflowInterventionDatabaseRow[]\n\n return {\n interventions: rows.map(rowToWorkflowInterventionRecord),\n hasMore: offset + rows.length < totalRow.count,\n total: totalRow.count,\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private requirePendingIntervention(\n projectId: string,\n id: string\n ): WorkflowInterventionDatabaseRow {\n const row = this.db\n .query(\"SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as WorkflowInterventionDatabaseRow | null\n\n if (!row) {\n throw new WorkflowInterventionError(\n `[SixbSqlite] Workflow intervention '${id}' not found for project '${projectId}'.`\n )\n }\n\n if (row.status !== \"pending\") {\n throw new WorkflowInterventionError(\n `[SixbSqlite] Workflow intervention '${id}' for project '${projectId}' is not pending.`\n )\n }\n\n return row\n }\n\n private requireIntervention(projectId: string, id: string): WorkflowInterventionRecord {\n const row = this.db\n .query(\"SELECT * FROM workflow_interventions WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as WorkflowInterventionDatabaseRow | null\n\n if (!row) {\n throw new WorkflowInterventionError(\n `[SixbSqlite] Failed to load workflow intervention '${id}' for project '${projectId}'.`\n )\n }\n\n return rowToWorkflowInterventionRecord(row)\n }\n}\n\ntype SqliteValue = string | number | null\n\nfunction serializeRecord(value: WorkflowIOSnapshot): string {\n return JSON.stringify(value)\n}\n\nfunction parseRecord(value: string): WorkflowIOSnapshot {\n return JSON.parse(value) as WorkflowIOSnapshot\n}\n\nfunction serializeActor(actor: WorkflowInterventionActor | undefined): string | null {\n return actor ? JSON.stringify(actor) : null\n}\n\nfunction parseActor(value: string | null): WorkflowInterventionActor | undefined {\n return value ? (JSON.parse(value) as WorkflowInterventionActor) : undefined\n}\n\nfunction rowToWorkflowInterventionRecord(\n row: WorkflowInterventionDatabaseRow\n): WorkflowInterventionRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowId: row.workflow_id,\n workflowRunId: row.workflow_run_id,\n nodeRunId: row.node_run_id,\n nodeIndex: row.node_index,\n nodeId: row.node_id,\n nodeKey: row.node_key,\n interventionId: row.intervention_id,\n input: parseRecord(row.input),\n defaultResponse: parseRecord(row.default_response),\n status: row.status,\n requestedAt: new Date(row.requested_at),\n expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,\n submittedAt: row.submitted_at ? new Date(row.submitted_at) : undefined,\n submittedBy: parseActor(row.submitted_by),\n response: row.response ? parseRecord(row.response) : undefined,\n cancelledAt: row.cancelled_at ? new Date(row.cancelled_at) : undefined,\n cancelledBy: parseActor(row.cancelled_by),\n expiredAt: row.expired_at ? new Date(row.expired_at) : undefined,\n }\n}\n\nfunction assertNonNegativeInteger(value: number, fieldName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new WorkflowInterventionError(\n `[SixbSqlite] Workflow intervention ${fieldName} must be a non-negative integer.`\n )\n }\n}\n\ninterface WorkflowInterventionDatabaseRow {\n project_id: string\n id: string\n workflow_id: string\n workflow_run_id: string\n node_run_id: string\n node_index: number\n node_id: string\n node_key: string\n intervention_id: string\n input: string\n default_response: string\n status: WorkflowInterventionRecord[\"status\"]\n requested_at: string\n expires_at: string | null\n submitted_at: string | null\n submitted_by: string | null\n response: string | null\n cancelled_at: string | null\n cancelled_by: string | null\n expired_at: string | null\n}\n",
|
|
49
|
+
"import type { Database } from \"bun:sqlite\"\nimport type { Principal, WorkflowRunSource } from \"@sixb/core\"\nimport type { WorkflowIOSnapshot } from \"@sixb/core/internal/workflows\"\nimport type {\n CancelWorkflowAgentNodeRunInput,\n ConfirmWorkflowAgentNodeRunExecutionOwnershipInput,\n ConfirmWorkflowRunExecutionOwnershipInput,\n CreateWorkflowAgentNodeRunInput,\n FinishWorkflowAgentNodeRunInput,\n FinishWorkflowNodeRunInput,\n FinishWorkflowRunInput,\n ListLatestWorkflowRunsInput,\n ListLatestWorkflowRunsResult,\n ListWorkflowAgentNodeRunsInput,\n ListWorkflowAgentNodeRunsResult,\n ListWorkflowNodeRunsInput,\n ListWorkflowNodeRunsResult,\n ListWorkflowRunsInput,\n ListWorkflowRunsResult,\n QueueWorkflowRunInput,\n ReclaimWorkflowAgentNodeRunInput,\n ReclaimWorkflowRunInput,\n ResumeWorkflowRunInput,\n StartWorkflowAgentNodeRunInput,\n StartWorkflowNodeRunInput,\n StartWorkflowRunInput,\n WaitWorkflowNodeRunInput,\n WaitWorkflowRunInput,\n WorkflowAgentNodeRunRecord,\n WorkflowAgentNodeRunStorage,\n WorkflowNodeRunRecord,\n WorkflowNodeRunStorage,\n WorkflowRunRecord,\n WorkflowRunStorage,\n} from \"@sixb/core/storage\"\nimport { WorkflowRunError } from \"@sixb/core/storage\"\nimport { queryLatestRunsByOwnerId } from \"./latest-run-query\"\nimport { installFreshSqliteSchema } from \"./migrations\"\nimport {\n appendRunListFilters,\n hasEmptyStatuses,\n queryRunList,\n type SqliteValue,\n} from \"./run-list-query\"\nimport { isUniqueConstraintError } from \"./storage-errors\"\nimport {\n closeSqliteStoreConnection,\n openSqliteStoreConnection,\n type SqliteStoreConnection,\n} from \"./transactions\"\n\nexport interface SqliteWorkflowRunStorageOptions {\n /** Path to SQLite database file. Defaults to ':memory:' for in-memory database. */\n path?: string\n /** Internal shared connection used by bundled SqliteStorage. */\n connection?: SqliteStoreConnection\n}\n\nexport class SqliteWorkflowRunStorage implements WorkflowRunStorage {\n readonly nodes: SqliteWorkflowNodeRunStorage\n readonly agentNodes: SqliteWorkflowAgentNodeRunStorage\n\n private readonly connection: SqliteStoreConnection\n private readonly db: Database\n\n constructor(options: SqliteWorkflowRunStorageOptions = {}) {\n this.connection = openSqliteStoreConnection(options)\n this.db = this.connection.db\n\n if (this.connection.installFreshSchema) {\n installFreshSqliteSchema(this.db)\n }\n\n this.nodes = new SqliteWorkflowNodeRunStorage(this.db)\n this.agentNodes = new SqliteWorkflowAgentNodeRunStorage(this.db)\n }\n\n async queue(input: QueueWorkflowRunInput): Promise<WorkflowRunRecord> {\n const queuedAt = input.queuedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO workflow_runs (\n project_id,\n id,\n workflow_id,\n status,\n input,\n queued_at,\n started_at,\n source,\n requested_by_principal_type,\n requested_by_principal_id,\n attempt\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.workflowId,\n \"queued\",\n serializeRecord(input.input),\n queuedAt.toISOString(),\n queuedAt.toISOString(),\n input.source ? JSON.stringify(input.source) : null,\n input.requestedByPrincipal?.type ?? \"system\",\n input.requestedByPrincipal?.id ?? \"system\",\n 0\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n return this.requireWorkflowRun(input.projectId, input.id)\n }\n\n async start(input: StartWorkflowRunInput): Promise<WorkflowRunRecord> {\n const startedAt = input.startedAt ?? new Date()\n\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowRunDatabaseRow | null\n\n if (existing) {\n if (existing.status !== \"queued\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n if (existing.workflow_id !== input.workflowId) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' workflow '${input.workflowId}' does not match existing workflow '${existing.workflow_id}'.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE workflow_runs\n SET\n status = ?,\n input = ?,\n started_at = ?,\n finished_at = NULL,\n error = NULL,\n source = COALESCE(source, ?)\n , attempt = attempt + 1,\n execution_token = ?, execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"running\",\n serializeRecord(input.input),\n startedAt.toISOString(),\n input.source ? JSON.stringify(input.source) : null,\n input.execution?.token ?? null,\n input.execution?.queueLeaseExpiresAt.toISOString() ?? null,\n input.projectId,\n input.id\n )\n\n return this.requireWorkflowRun(input.projectId, input.id)\n }\n\n try {\n this.db\n .query(\n `\n INSERT INTO workflow_runs (\n project_id,\n id,\n workflow_id,\n status,\n input,\n started_at,\n source,\n requested_by_principal_type,\n requested_by_principal_id,\n attempt,\n execution_token,\n execution_queue_lease_expires_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.workflowId,\n \"running\",\n serializeRecord(input.input),\n startedAt.toISOString(),\n input.source ? JSON.stringify(input.source) : null,\n input.requestedByPrincipal?.type ?? \"system\",\n input.requestedByPrincipal?.id ?? \"system\",\n 1,\n input.execution?.token ?? null,\n input.execution?.queueLeaseExpiresAt.toISOString() ?? null\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n return this.requireWorkflowRun(input.projectId, input.id)\n })()\n }\n\n async reclaim(input: ReclaimWorkflowRunInput): Promise<WorkflowRunRecord> {\n return this.db.transaction(() => {\n const row = this.requireStatus(input.projectId, input.id, \"running\")\n this.db\n .query(`\n UPDATE workflow_runs SET attempt = ?, execution_token = ?,\n execution_queue_lease_expires_at = ? WHERE project_id = ? AND id = ?\n `)\n .run(\n row.attempt + 1,\n input.execution.token,\n input.execution.queueLeaseExpiresAt.toISOString(),\n input.projectId,\n input.id\n )\n return this.requireWorkflowRun(input.projectId, input.id)\n })()\n }\n\n async confirmExecutionOwnership(\n input: ConfirmWorkflowRunExecutionOwnershipInput\n ): Promise<WorkflowRunRecord> {\n return this.db.transaction(() => {\n const row = this.requireStatus(input.projectId, input.id, \"running\")\n assertSqliteWorkflowRunOwnership(row, input.executionToken)\n const current = row.execution_queue_lease_expires_at\n ? new Date(row.execution_queue_lease_expires_at)\n : input.queueLeaseExpiresAt\n this.db\n .query(`\n UPDATE workflow_runs SET execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND id = ?\n `)\n .run(\n new Date(Math.max(current.getTime(), input.queueLeaseExpiresAt.getTime())).toISOString(),\n input.projectId,\n input.id\n )\n return this.requireWorkflowRun(input.projectId, input.id)\n })()\n }\n\n async finish(input: FinishWorkflowRunInput): Promise<WorkflowRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowRunDatabaseRow | null\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (!canFinishWorkflowRun(existing.status, input.status)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' for project '${input.projectId}' cannot be finished from status '${existing.status}'.`\n )\n }\n assertSqliteWorkflowRunOwnership(existing, input.executionToken)\n\n this.db\n .query(\n `\n UPDATE workflow_runs\n SET\n status = ?,\n finished_at = ?,\n error = ?\n , execution_token = NULL, execution_queue_lease_expires_at = NULL\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\" ? null : (input.error ?? null),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowRunDatabaseRow\n\n return rowToWorkflowRunRecord(updated)\n })()\n }\n\n async wait(input: WaitWorkflowRunInput): Promise<WorkflowRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowRunDatabaseRow | null\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' for project '${input.projectId}' must be running.`\n )\n }\n assertSqliteWorkflowRunOwnership(existing, input.executionToken)\n\n this.db\n .query(\n `\n UPDATE workflow_runs\n SET\n status = ?,\n finished_at = NULL,\n error = NULL\n , execution_token = NULL, execution_queue_lease_expires_at = NULL\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\"waiting\", input.projectId, input.id)\n\n return this.requireWorkflowRun(input.projectId, input.id)\n })()\n }\n\n async resume(input: ResumeWorkflowRunInput): Promise<WorkflowRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowRunDatabaseRow | null\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n\n if (existing.status !== \"waiting\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.id}' for project '${input.projectId}' must be waiting.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE workflow_runs\n SET\n status = ?,\n finished_at = NULL,\n error = NULL\n , attempt = attempt + 1, execution_token = ?, execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n \"running\",\n input.execution?.token ?? null,\n input.execution?.queueLeaseExpiresAt.toISOString() ?? null,\n input.projectId,\n input.id\n )\n\n return this.requireWorkflowRun(input.projectId, input.id)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WorkflowRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as WorkflowRunDatabaseRow | null\n\n return row ? rowToWorkflowRunRecord(row) : null\n }\n\n async list(input: ListWorkflowRunsInput): Promise<ListWorkflowRunsResult> {\n if (hasEmptyStatuses(input) || input.workflowIds?.length === 0) {\n return {\n runs: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.workflowId) {\n whereClauses.push(\"workflow_id = ?\")\n args.push(input.workflowId)\n }\n\n if (input.workflowIds) {\n whereClauses.push(`workflow_id IN (${input.workflowIds.map(() => \"?\").join(\", \")})`)\n args.push(...input.workflowIds)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<WorkflowRunDatabaseRow>({\n db: this.db,\n tableName: \"workflow_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n runs: rows.map(rowToWorkflowRunRecord),\n hasMore,\n total,\n }\n }\n\n async listLatestByWorkflowIds(\n input: ListLatestWorkflowRunsInput\n ): Promise<ListLatestWorkflowRunsResult> {\n const rows = queryLatestRunsByOwnerId<WorkflowRunDatabaseRow>({\n db: this.db,\n tableName: \"workflow_runs\",\n ownerColumn: \"workflow_id\",\n ownerIds: input.workflowIds,\n projectId: input.projectId,\n ownerIdFor: (row) => row.workflow_id,\n })\n\n return {\n runs: rows.map(rowToWorkflowRunRecord),\n }\n }\n\n close(): void {\n closeSqliteStoreConnection(this.connection)\n }\n\n private requireWorkflowRun(projectId: string, id: string): WorkflowRunRecord {\n const record = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as WorkflowRunDatabaseRow | null\n\n if (!record) {\n throw new WorkflowRunError(\n `[SixbSqlite] Failed to load workflow run '${id}' for project '${projectId}'.`\n )\n }\n\n return rowToWorkflowRunRecord(record)\n }\n\n private requireStatus(\n projectId: string,\n id: string,\n status: WorkflowRunRecord[\"status\"]\n ): WorkflowRunDatabaseRow {\n const row = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(projectId, id) as WorkflowRunDatabaseRow | null\n if (!row) throw new WorkflowRunError(`[SixbSqlite] Workflow run '${id}' not found.`)\n if (row.status !== status) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${id}' must be ${status} (status '${row.status}').`\n )\n }\n return row\n }\n}\n\nexport class SqliteWorkflowAgentNodeRunStorage implements WorkflowAgentNodeRunStorage {\n constructor(private readonly db: Database) {}\n\n async create(input: CreateWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n try {\n this.db\n .query(`\n INSERT INTO workflow_agent_node_runs (\n project_id, node_run_id, agent_id, status, prompt, attempt, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n `)\n .run(\n input.projectId,\n input.nodeRunId,\n input.agentId,\n \"queued\",\n input.prompt,\n 0,\n (input.createdAt ?? new Date()).toISOString()\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Agent execution already exists for workflow node run '${input.nodeRunId}'.`\n )\n }\n throw error\n }\n return this.require(input.projectId, input.nodeRunId)\n }\n\n async start(input: StartWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return this.db.transaction(() => {\n this.requireStatus(input.projectId, input.nodeRunId, \"queued\")\n this.db\n .query(`\n UPDATE workflow_agent_node_runs SET\n status = ?, execution_principal_type = ?, execution_principal_id = ?, model_id = ?,\n attempt = 1, execution_token = ?, execution_queue_lease_expires_at = ?, started_at = ?\n WHERE project_id = ? AND node_run_id = ?\n `)\n .run(\n \"running\",\n input.executionPrincipal?.type ?? null,\n input.executionPrincipal?.id ?? null,\n input.modelId ?? null,\n input.execution.token,\n input.execution.queueLeaseExpiresAt.toISOString(),\n (input.startedAt ?? new Date()).toISOString(),\n input.projectId,\n input.nodeRunId\n )\n return this.require(input.projectId, input.nodeRunId)\n })()\n }\n\n async reclaim(input: ReclaimWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return this.db.transaction(() => {\n const row = this.requireStatus(input.projectId, input.nodeRunId, \"running\")\n this.db\n .query(`\n UPDATE workflow_agent_node_runs SET\n attempt = ?, execution_token = ?, execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND node_run_id = ?\n `)\n .run(\n Number(row.attempt) + 1,\n input.execution.token,\n input.execution.queueLeaseExpiresAt.toISOString(),\n input.projectId,\n input.nodeRunId\n )\n return this.require(input.projectId, input.nodeRunId)\n })()\n }\n\n async confirmExecutionOwnership(\n input: ConfirmWorkflowAgentNodeRunExecutionOwnershipInput\n ): Promise<WorkflowAgentNodeRunRecord> {\n return this.db.transaction(() => {\n const row = this.requireStatus(input.projectId, input.nodeRunId, \"running\")\n assertSqliteWorkflowAgentNodeOwnership(row, input.executionToken)\n const current = row.execution_queue_lease_expires_at\n ? new Date(row.execution_queue_lease_expires_at)\n : input.queueLeaseExpiresAt\n this.db\n .query(`\n UPDATE workflow_agent_node_runs SET execution_queue_lease_expires_at = ?\n WHERE project_id = ? AND node_run_id = ?\n `)\n .run(\n new Date(Math.max(current.getTime(), input.queueLeaseExpiresAt.getTime())).toISOString(),\n input.projectId,\n input.nodeRunId\n )\n return this.require(input.projectId, input.nodeRunId)\n })()\n }\n\n async finish(input: FinishWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return this.db.transaction(() => {\n const row = this.requireStatus(input.projectId, input.nodeRunId, \"running\")\n assertSqliteWorkflowAgentNodeOwnership(row, input.executionToken)\n this.db\n .query(`\n UPDATE workflow_agent_node_runs SET\n status = ?, model_id = COALESCE(?, model_id), finish_reason = ?, usage = ?, trace = ?,\n diagnostics = ?, error = ?, execution_token = NULL,\n execution_queue_lease_expires_at = NULL, completed_at = ?\n WHERE project_id = ? AND node_run_id = ?\n `)\n .run(\n input.status,\n input.modelId ?? null,\n input.finishReason ?? null,\n input.usage ? JSON.stringify(input.usage) : null,\n input.trace ? JSON.stringify(input.trace) : null,\n input.diagnostics ? JSON.stringify(input.diagnostics) : null,\n input.status === \"succeeded\" ? null : (input.error ?? null),\n (input.completedAt ?? new Date()).toISOString(),\n input.projectId,\n input.nodeRunId\n )\n return this.require(input.projectId, input.nodeRunId)\n })()\n }\n\n async cancel(input: CancelWorkflowAgentNodeRunInput): Promise<WorkflowAgentNodeRunRecord> {\n return this.db.transaction(() => {\n const row = this.require(input.projectId, input.nodeRunId)\n if (row.status !== \"queued\" && row.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Agent workflow node run '${input.nodeRunId}' cannot be cancelled from status '${row.status}'.`\n )\n }\n this.db\n .query(\n `UPDATE workflow_agent_node_runs SET status = ?, error = ?, execution_token = NULL,\n execution_queue_lease_expires_at = NULL, completed_at = ?\n WHERE project_id = ? AND node_run_id = ?`\n )\n .run(\n \"cancelled\",\n input.error ?? null,\n (input.completedAt ?? new Date()).toISOString(),\n input.projectId,\n input.nodeRunId\n )\n return this.require(input.projectId, input.nodeRunId)\n })()\n }\n\n async getByNodeRunId(params: {\n projectId: string\n nodeRunId: string\n }): Promise<WorkflowAgentNodeRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM workflow_agent_node_runs WHERE project_id = ? AND node_run_id = ?\")\n .get(params.projectId, params.nodeRunId) as WorkflowAgentNodeRunDatabaseRow | null\n return row ? rowToWorkflowAgentNodeRunRecord(row) : null\n }\n\n async list(input: ListWorkflowAgentNodeRunsInput): Promise<ListWorkflowAgentNodeRunsResult> {\n if (hasEmptyStatuses(input)) return { runs: [], total: 0, hasMore: false }\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n if (input.agentId) {\n whereClauses.push(\"agent_id = ?\")\n args.push(input.agentId)\n }\n appendRunListFilters(whereClauses, args, input)\n const result = queryRunList<WorkflowAgentNodeRunDatabaseRow>({\n db: this.db,\n tableName: \"workflow_agent_node_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n return { ...result, runs: result.rows.map(rowToWorkflowAgentNodeRunRecord) }\n }\n\n private require(projectId: string, nodeRunId: string): WorkflowAgentNodeRunRecord {\n const row = this.db\n .query(\"SELECT * FROM workflow_agent_node_runs WHERE project_id = ? AND node_run_id = ?\")\n .get(projectId, nodeRunId) as WorkflowAgentNodeRunDatabaseRow | null\n if (!row) {\n throw new WorkflowRunError(\n `[SixbSqlite] Agent workflow node run '${nodeRunId}' not found for project '${projectId}'.`\n )\n }\n return rowToWorkflowAgentNodeRunRecord(row)\n }\n\n private requireStatus(\n projectId: string,\n nodeRunId: string,\n status: WorkflowAgentNodeRunRecord[\"status\"]\n ): WorkflowAgentNodeRunDatabaseRow {\n const row = this.db\n .query(\"SELECT * FROM workflow_agent_node_runs WHERE project_id = ? AND node_run_id = ?\")\n .get(projectId, nodeRunId) as WorkflowAgentNodeRunDatabaseRow | null\n if (!row) {\n throw new WorkflowRunError(\n `[SixbSqlite] Agent workflow node run '${nodeRunId}' not found for project '${projectId}'.`\n )\n }\n if (row.status !== status) {\n throw new WorkflowRunError(\n `[SixbSqlite] Agent workflow node run '${nodeRunId}' must be ${status} (status '${row.status}').`\n )\n }\n return row\n }\n}\n\nexport class SqliteWorkflowNodeRunStorage implements WorkflowNodeRunStorage {\n constructor(private readonly db: Database) {}\n\n async start(input: StartWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n assertNonNegativeInteger(input.nodeIndex, \"nodeIndex\")\n\n return this.db.transaction(() => {\n const workflowRun = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.workflowRunId) as WorkflowRunDatabaseRow | null\n\n if (!workflowRun) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.workflowRunId}' not found for project '${input.projectId}'.`\n )\n }\n\n if (workflowRun.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run '${input.workflowRunId}' for project '${input.projectId}' must be running.`\n )\n }\n assertSqliteWorkflowRunOwnership(workflowRun, input.executionToken)\n\n if (workflowRun.workflow_id !== input.workflowId) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' workflow '${input.workflowId}' does not match workflow run '${input.workflowRunId}' workflow '${workflowRun.workflow_id}'.`\n )\n }\n\n const startedAt = input.startedAt ?? new Date()\n\n try {\n this.db\n .query(\n `\n INSERT INTO workflow_node_runs (\n project_id,\n id,\n workflow_run_id,\n workflow_id,\n node_index,\n node_type,\n node_id,\n node_key,\n status,\n input,\n started_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `\n )\n .run(\n input.projectId,\n input.id,\n input.workflowRunId,\n input.workflowId,\n input.nodeIndex,\n input.nodeType,\n input.nodeId,\n input.nodeKey,\n \"running\",\n serializeRecord(input.input),\n startedAt.toISOString()\n )\n } catch (error) {\n if (isUniqueConstraintError(error)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' already exists for project '${input.projectId}'.`\n )\n }\n\n throw error\n }\n\n const row = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowNodeRunDatabaseRow | null\n\n if (!row) {\n throw new WorkflowRunError(\n `[SixbSqlite] Failed to load workflow node run '${input.id}' for project '${input.projectId}'.`\n )\n }\n\n return rowToWorkflowNodeRunRecord(row)\n })()\n }\n\n async finish(input: FinishWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowNodeRunDatabaseRow | null\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n this.assertNodeParentOwnership(existing, input.executionToken)\n\n if (existing.status !== \"running\" && existing.status !== \"waiting\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' for project '${input.projectId}' is already terminal.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE workflow_node_runs\n SET\n status = ?,\n finished_at = ?,\n output = ?,\n error = ?\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\n input.status,\n (input.finishedAt ?? new Date()).toISOString(),\n input.status === \"succeeded\" && input.output ? serializeRecord(input.output) : null,\n input.status === \"succeeded\" ? null : (input.error ?? null),\n input.projectId,\n input.id\n )\n\n const updated = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowNodeRunDatabaseRow\n\n return rowToWorkflowNodeRunRecord(updated)\n })()\n }\n\n async wait(input: WaitWorkflowNodeRunInput): Promise<WorkflowNodeRunRecord> {\n return this.db.transaction(() => {\n const existing = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowNodeRunDatabaseRow | null\n\n if (!existing) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' not found for project '${input.projectId}'.`\n )\n }\n this.assertNodeParentOwnership(existing, input.executionToken)\n\n if (existing.status !== \"running\") {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow node run '${input.id}' for project '${input.projectId}' must be running.`\n )\n }\n\n this.db\n .query(\n `\n UPDATE workflow_node_runs\n SET\n status = ?,\n finished_at = NULL,\n output = NULL,\n error = NULL\n WHERE project_id = ? AND id = ?\n `\n )\n .run(\"waiting\", input.projectId, input.id)\n\n const updated = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(input.projectId, input.id) as WorkflowNodeRunDatabaseRow\n\n return rowToWorkflowNodeRunRecord(updated)\n })()\n }\n\n async getById(params: { projectId: string; id: string }): Promise<WorkflowNodeRunRecord | null> {\n const row = this.db\n .query(\"SELECT * FROM workflow_node_runs WHERE project_id = ? AND id = ?\")\n .get(params.projectId, params.id) as WorkflowNodeRunDatabaseRow | null\n\n return row ? rowToWorkflowNodeRunRecord(row) : null\n }\n\n async list(input: ListWorkflowNodeRunsInput): Promise<ListWorkflowNodeRunsResult> {\n if (hasEmptyStatuses(input)) {\n return {\n nodes: [],\n hasMore: false,\n total: 0,\n }\n }\n\n const whereClauses = [\"project_id = ?\"]\n const args: SqliteValue[] = [input.projectId]\n\n if (input.workflowRunId) {\n whereClauses.push(\"workflow_run_id = ?\")\n args.push(input.workflowRunId)\n }\n\n if (input.workflowId) {\n whereClauses.push(\"workflow_id = ?\")\n args.push(input.workflowId)\n }\n\n if (input.nodeType) {\n whereClauses.push(\"node_type = ?\")\n args.push(input.nodeType)\n }\n\n if (input.nodeId) {\n whereClauses.push(\"node_id = ?\")\n args.push(input.nodeId)\n }\n\n if (input.nodeKey) {\n whereClauses.push(\"node_key = ?\")\n args.push(input.nodeKey)\n }\n\n appendRunListFilters(whereClauses, args, input)\n\n const { rows, total, hasMore } = queryRunList<WorkflowNodeRunDatabaseRow>({\n db: this.db,\n tableName: \"workflow_node_runs\",\n whereClauses,\n args,\n order: input.order,\n limit: input.limit,\n offset: input.offset,\n })\n\n return {\n nodes: rows.map(rowToWorkflowNodeRunRecord),\n hasMore,\n total,\n }\n }\n\n private assertNodeParentOwnership(node: WorkflowNodeRunDatabaseRow, token?: string): void {\n const run = this.db\n .query(\"SELECT * FROM workflow_runs WHERE project_id = ? AND id = ?\")\n .get(node.project_id, node.workflow_run_id) as WorkflowRunDatabaseRow | null\n if (!run) throw new WorkflowRunError(\"[SixbSqlite] Parent workflow run was not found.\")\n assertSqliteWorkflowRunOwnership(run, token)\n }\n}\n\nfunction serializeRecord(value: WorkflowIOSnapshot): string {\n return JSON.stringify(value)\n}\n\nfunction parseRecord(value: string): WorkflowIOSnapshot {\n return JSON.parse(value) as WorkflowIOSnapshot\n}\n\nfunction rowToWorkflowRunRecord(row: WorkflowRunDatabaseRow): WorkflowRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowId: row.workflow_id,\n status: row.status,\n input: parseRecord(row.input),\n queuedAt: row.queued_at ? new Date(row.queued_at) : undefined,\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n error: row.error ?? undefined,\n source: row.source ? (JSON.parse(row.source) as WorkflowRunSource) : undefined,\n requestedByPrincipal: {\n type: row.requested_by_principal_type,\n id: row.requested_by_principal_id,\n },\n attempt: row.attempt,\n ...(row.execution_token && row.execution_queue_lease_expires_at\n ? {\n execution: {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n },\n }\n : {}),\n }\n}\n\nfunction rowToWorkflowNodeRunRecord(row: WorkflowNodeRunDatabaseRow): WorkflowNodeRunRecord {\n return {\n id: row.id,\n projectId: row.project_id,\n workflowRunId: row.workflow_run_id,\n workflowId: row.workflow_id,\n nodeIndex: row.node_index,\n nodeType: row.node_type,\n nodeId: row.node_id,\n nodeKey: row.node_key,\n status: row.status,\n input: parseRecord(row.input),\n startedAt: new Date(row.started_at),\n finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,\n output: row.output ? parseRecord(row.output) : undefined,\n error: row.error ?? undefined,\n }\n}\n\nfunction assertNonNegativeInteger(value: number, fieldName: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new WorkflowRunError(\n `[SixbSqlite] Workflow run ${fieldName} must be a non-negative integer.`\n )\n }\n}\n\nfunction canFinishWorkflowRun(\n current: WorkflowRunRecord[\"status\"],\n next: FinishWorkflowRunInput[\"status\"]\n): boolean {\n return (\n current === \"running\" ||\n (current === \"waiting\" && next !== \"succeeded\") ||\n (current === \"queued\" && next !== \"succeeded\")\n )\n}\n\ninterface WorkflowRunDatabaseRow {\n project_id: string\n id: string\n workflow_id: string\n status: WorkflowRunRecord[\"status\"]\n input: string\n queued_at: string | null\n started_at: string\n finished_at: string | null\n error: string | null\n source: string | null\n requested_by_principal_type: Principal[\"type\"]\n requested_by_principal_id: string\n attempt: number\n execution_token: string | null\n execution_queue_lease_expires_at: string | null\n}\n\ninterface WorkflowNodeRunDatabaseRow {\n project_id: string\n id: string\n workflow_run_id: string\n workflow_id: string\n node_index: number\n node_type: WorkflowNodeRunRecord[\"nodeType\"]\n node_id: string\n node_key: string\n status: WorkflowNodeRunRecord[\"status\"]\n input: string\n started_at: string\n finished_at: string | null\n output: string | null\n error: string | null\n}\n\ninterface WorkflowAgentNodeRunDatabaseRow {\n project_id: string\n node_run_id: string\n agent_id: string\n status: WorkflowAgentNodeRunRecord[\"status\"]\n prompt: string\n execution_principal_type: \"serviceAccount\" | null\n execution_principal_id: string | null\n model_id: string | null\n finish_reason: WorkflowAgentNodeRunRecord[\"finishReason\"] | null\n usage: string | null\n trace: string | null\n diagnostics: string | null\n error: string | null\n attempt: number\n execution_token: string | null\n execution_queue_lease_expires_at: string | null\n created_at: string\n started_at: string | null\n completed_at: string | null\n}\n\nfunction assertSqliteWorkflowAgentNodeOwnership(\n row: WorkflowAgentNodeRunDatabaseRow,\n token: string\n): void {\n if (row.execution_token !== token) {\n throw new WorkflowRunError(\n `[SixbSqlite] Execution token is no longer current on agent workflow node run '${row.node_run_id}'.`\n )\n }\n}\n\nfunction rowToWorkflowAgentNodeRunRecord(\n row: WorkflowAgentNodeRunDatabaseRow\n): WorkflowAgentNodeRunRecord {\n return {\n projectId: row.project_id,\n nodeRunId: row.node_run_id,\n agentId: row.agent_id,\n status: row.status,\n prompt: row.prompt,\n ...(row.execution_principal_type && row.execution_principal_id\n ? {\n executionPrincipal: {\n type: row.execution_principal_type,\n id: row.execution_principal_id,\n },\n }\n : {}),\n ...(row.model_id ? { modelId: row.model_id } : {}),\n ...(row.finish_reason ? { finishReason: row.finish_reason } : {}),\n ...(row.usage ? { usage: JSON.parse(row.usage) } : {}),\n ...(row.trace ? { trace: JSON.parse(row.trace) } : {}),\n ...(row.diagnostics ? { diagnostics: JSON.parse(row.diagnostics) } : {}),\n ...(row.error ? { error: row.error } : {}),\n attempt: row.attempt,\n ...(row.execution_token && row.execution_queue_lease_expires_at\n ? {\n execution: {\n token: row.execution_token,\n queueLeaseExpiresAt: new Date(row.execution_queue_lease_expires_at),\n },\n }\n : {}),\n createdAt: new Date(row.created_at),\n ...(row.started_at ? { startedAt: new Date(row.started_at) } : {}),\n ...(row.completed_at ? { completedAt: new Date(row.completed_at) } : {}),\n }\n}\n\nfunction assertSqliteWorkflowRunOwnership(row: WorkflowRunDatabaseRow, token?: string): void {\n if (row.execution_token !== (token ?? null)) {\n throw new WorkflowRunError(\n `[SixbSqlite] Execution token is no longer current on workflow run '${row.id}'.`\n )\n }\n}\n"
|
|
50
|
+
],
|
|
51
|
+
"mappings": ";;AAIA;AAOA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACpBA;AACA;AACA;AACA;AASA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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",
|
|
52
|
+
"debugId": "983F7BC9E5B8E71164756E2164756E21",
|
|
53
|
+
"names": []
|
|
54
|
+
}
|