@effect-agent/storage-sqlite 0.1.0-beta.84 → 0.1.0-beta.85

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.
@@ -194,7 +194,7 @@ const makeActivityStore = Effect.fn("SqliteActivityStore.make")(function* () {
194
194
  key: decoded.key,
195
195
  leaseExpiresAt: current.leaseExpiresAt
196
196
  });
197
- const next = yield* Schema.decodeUnknownEffect(ActivityProgress)({
197
+ const next = yield* Schema.decodeEffect(ActivityProgress)({
198
198
  version: STORAGE_VERSION,
199
199
  key: decoded.key,
200
200
  throughSequence: current?.throughSequence ?? 0,
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteActivityStore.mjs","names":[],"sources":["../src/SqliteActivityStore.ts"],"sourcesContent":["import {\n ActivityBusy,\n ActivityClaim,\n ActivityClaimRequest,\n ActivityMutationFailpoint,\n type ActivityMutationFailure,\n ActivityOwnershipLost,\n ActivityProcessorKey,\n ActivityProcessorStore,\n ActivityProgress,\n ActivityStoreError,\n ActivityWorkConflict,\n PreparedActivity,\n} from \"@effect-agent/thread/ActivityStore\";\nimport { Digest } from \"@effect-agent/thread/Records\";\nimport { Clock, Effect, Layer, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst STORAGE_VERSION = 1 as const;\nconst METADATA_COMPONENT = \"activity\";\nconst STATE_TABLE = \"effect_agent_activity_processor_state_v1\";\nconst StoredJson = Schema.String.check(Schema.isMaxLength(16 * 1024 * 1024));\nconst sameKey = Schema.toEquivalence(ActivityProcessorKey);\nconst sameWork = Schema.toEquivalence(PreparedActivity);\n\nclass ActivityMetadataRow extends Schema.Class<ActivityMetadataRow>(\n \"@effect-agent/storage-sqlite/ActivityMetadataRow\",\n)({\n version: Schema.Int,\n}) {}\n\nclass ActivityTableRow extends Schema.Class<ActivityTableRow>(\n \"@effect-agent/storage-sqlite/ActivityTableRow\",\n)({\n name: Schema.NonEmptyString,\n}) {}\n\nclass ActivityStateRow extends Schema.Class<ActivityStateRow>(\n \"@effect-agent/storage-sqlite/ActivityStateRow\",\n)({\n processor_id: ActivityProcessorKey.fields.processorId,\n processor_version: ActivityProcessorKey.fields.processorVersion,\n thread_id: ActivityProcessorKey.fields.threadId,\n format_version: Schema.Int,\n through_sequence: ActivityProgress.fields.throughSequence,\n epoch: ActivityProgress.fields.epoch,\n owner: ActivityProgress.fields.owner,\n lease_expires_at: ActivityProgress.fields.leaseExpiresAt,\n progress_json: StoredJson,\n}) {}\n\nclass ActivityChangeCountRow extends Schema.Class<ActivityChangeCountRow>(\n \"@effect-agent/storage-sqlite/ActivityChangeCountRow\",\n)({\n changed: Schema.Int,\n}) {}\n\nconst StoredVersionHeader = Schema.Struct({ version: Schema.Int });\n\nexport type SqliteActivityInitializationError = ActivityStoreError | ActivityMutationFailure;\n\nconst storeError = (\n operation: string,\n reason: ActivityStoreError[\"reason\"] = \"unavailable\",\n): ActivityStoreError => ActivityStoreError.make({ operation, reason });\n\nconst query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n operation: string,\n) => effect.pipe(Effect.mapError(() => storeError(operation)));\n\nconst decodeRows = Effect.fn(\"SqliteActivityStore.decodeRows\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n rows: ReadonlyArray<unknown>,\n operation: string,\n): Effect.fn.Return<ReadonlyArray<A>, ActivityStoreError> {\n return yield* Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n});\n\nconst decodeInput = Effect.fn(\"SqliteActivityStore.decodeInput\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n value: unknown,\n operation: string,\n): Effect.fn.Return<A, ActivityStoreError> {\n return yield* Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError(() => storeError(operation, \"invalid-input\")),\n );\n});\n\nconst encodeProgress = Effect.fn(\"SqliteActivityStore.encodeProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n): Effect.fn.Return<string, ActivityStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ActivityProgress))(progress).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n Effect.flatMap((encoded) =>\n Schema.decodeEffect(StoredJson)(encoded).pipe(\n Effect.mapError(() => storeError(operation, \"invalid-input\")),\n ),\n ),\n );\n});\n\nconst decodeProgress = Effect.fn(\"SqliteActivityStore.decodeProgress\")(function* (\n value: string,\n operation: string,\n): Effect.fn.Return<ActivityProgress, ActivityStoreError> {\n const header = yield* Schema.decodeEffect(Schema.fromJsonString(StoredVersionHeader))(value).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n\n if (header.version !== STORAGE_VERSION) {\n return yield* storeError(operation, \"incompatible\");\n }\n\n const progress = yield* Schema.decodeEffect(Schema.fromJsonString(ActivityProgress))(value).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n\n const canonical = yield* encodeProgress(progress, operation);\n\n if (canonical !== value) return yield* storeError(operation, \"corrupt\");\n\n return progress;\n});\n\nconst validateProgress = Effect.fn(\"SqliteActivityStore.validateProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n): Effect.fn.Return<ActivityProgress, ActivityStoreError> {\n if (\n progress.epoch < 1 ||\n (progress.owner === null && progress.leaseExpiresAt !== 0) ||\n (progress.pending !== null &&\n (!sameKey(progress.pending.key, progress.key) ||\n progress.pending.sequence !== progress.throughSequence + 1))\n ) {\n return yield* storeError(operation, \"corrupt\");\n }\n\n return progress;\n});\n\nconst makeClaim = (progress: ActivityProgress): ActivityClaim | null =>\n progress.owner === null\n ? null\n : ActivityClaim.make({\n key: progress.key,\n owner: progress.owner,\n epoch: progress.epoch,\n throughSequence: progress.throughSequence,\n leaseExpiresAt: progress.leaseExpiresAt,\n pending: progress.pending,\n });\n\nconst ownershipLost = (claim: ActivityClaim) =>\n ActivityOwnershipLost.make({ key: claim.key, owner: claim.owner, epoch: claim.epoch });\n\n// The pinned Node SQLite client's writable withTransaction begins with BEGIN IMMEDIATE.\n// Each mutation therefore locks before reading progress, which serializes independent\n// connections without a deferred read-to-write upgrade.\nconst makeActivityStore = Effect.fn(\"SqliteActivityStore.make\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* ActivityMutationFailpoint;\n\n yield* failpoint.hit(\"activity:initialize:before\");\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`\n CREATE TABLE IF NOT EXISTS effect_agent_activity_metadata (\n component TEXT PRIMARY KEY NOT NULL,\n version INTEGER NOT NULL\n )\n `;\n\n const metadataRows = yield* sql<Record<string, unknown>>`\n SELECT version FROM effect_agent_activity_metadata\n WHERE component = ${METADATA_COMPONENT}\n `;\n\n const metadata = yield* decodeRows(\n ActivityMetadataRow,\n metadataRows,\n \"decode activity schema version\",\n );\n\n if (metadata.length > 1) {\n return yield* storeError(\"decode activity schema version\", \"corrupt\");\n }\n const currentVersion = metadata[0]?.version;\n\n if (currentVersion !== undefined && currentVersion !== STORAGE_VERSION) {\n return yield* storeError(\"initialize activity schema\", \"incompatible\");\n }\n if (currentVersion === undefined) {\n const tableRows = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master\n WHERE type = 'table' AND name = ${STATE_TABLE}\n `;\n\n const existing = yield* decodeRows(\n ActivityTableRow,\n tableRows,\n \"inspect activity schema\",\n );\n\n if (existing.length > 0) {\n return yield* storeError(\"initialize activity schema\", \"incompatible\");\n }\n yield* sql`\n CREATE TABLE effect_agent_activity_processor_state_v1 (\n processor_id TEXT NOT NULL,\n processor_version TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n format_version INTEGER NOT NULL,\n through_sequence INTEGER NOT NULL,\n epoch INTEGER NOT NULL,\n owner TEXT,\n lease_expires_at REAL NOT NULL,\n progress_json TEXT NOT NULL,\n PRIMARY KEY (processor_id, processor_version, thread_id)\n )\n `;\n yield* sql`\n INSERT INTO effect_agent_activity_metadata (component, version)\n VALUES (${METADATA_COMPONENT}, ${STORAGE_VERSION})\n `;\n }\n yield* sql`\n SELECT processor_id, processor_version, thread_id, format_version,\n through_sequence, epoch, owner, lease_expires_at, progress_json\n FROM effect_agent_activity_processor_state_v1\n LIMIT 0\n `;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(\"initialize activity schema\"))));\n yield* failpoint.hit(\"activity:initialize:after\");\n\n const readProgress = Effect.fn(\"SqliteActivityStore.readProgress\")(function* (\n key: ActivityProcessorKey,\n operation: string,\n ): Effect.fn.Return<ActivityProgress | null, ActivityStoreError> {\n const rawRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT processor_id, processor_version, thread_id, format_version,\n through_sequence, epoch, owner, lease_expires_at, progress_json\n FROM effect_agent_activity_processor_state_v1\n WHERE processor_id = ${key.processorId}\n AND processor_version = ${key.processorVersion}\n AND thread_id = ${key.threadId}\n `,\n operation,\n );\n\n const rows = yield* decodeRows(ActivityStateRow, rawRows, operation);\n\n if (rows.length === 0) return null;\n if (rows.length !== 1) return yield* storeError(operation, \"corrupt\");\n const row = rows[0];\n\n if (row.format_version !== STORAGE_VERSION) {\n return yield* storeError(operation, \"incompatible\");\n }\n const progress = yield* decodeProgress(row.progress_json, operation);\n\n yield* validateProgress(progress, operation);\n if (\n !sameKey(progress.key, key) ||\n row.processor_id !== key.processorId ||\n row.processor_version !== key.processorVersion ||\n row.thread_id !== key.threadId ||\n row.through_sequence !== progress.throughSequence ||\n row.epoch !== progress.epoch ||\n row.owner !== progress.owner ||\n row.lease_expires_at !== progress.leaseExpiresAt\n ) {\n return yield* storeError(operation, \"corrupt\");\n }\n\n return progress;\n });\n\n const checkChanged = Effect.fn(\"SqliteActivityStore.checkChanged\")(function* (\n operation: string,\n ): Effect.fn.Return<void, ActivityStoreError> {\n const rawRows = yield* query(\n sql<Record<string, unknown>>`SELECT changes() AS changed`,\n operation,\n );\n\n const rows = yield* decodeRows(ActivityChangeCountRow, rawRows, operation);\n\n if (rows.length !== 1 || rows[0].changed !== 1) {\n return yield* storeError(operation, \"corrupt\");\n }\n });\n\n const insertProgress = Effect.fn(\"SqliteActivityStore.insertProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n ) {\n const progressJson = yield* encodeProgress(progress, operation);\n\n yield* sql`\n INSERT INTO effect_agent_activity_processor_state_v1 (\n processor_id, processor_version, thread_id, format_version, through_sequence,\n epoch, owner, lease_expires_at, progress_json\n ) VALUES (\n ${progress.key.processorId}, ${progress.key.processorVersion}, ${progress.key.threadId},\n ${STORAGE_VERSION}, ${progress.throughSequence}, ${progress.epoch}, ${progress.owner},\n ${progress.leaseExpiresAt}, ${progressJson}\n )\n `;\n yield* checkChanged(operation);\n });\n\n const updateProgress = Effect.fn(\"SqliteActivityStore.updateProgress\")(function* (\n current: ActivityProgress,\n next: ActivityProgress,\n operation: string,\n ) {\n const progressJson = yield* encodeProgress(next, operation);\n\n yield* sql`\n UPDATE effect_agent_activity_processor_state_v1\n SET format_version = ${STORAGE_VERSION},\n through_sequence = ${next.throughSequence},\n epoch = ${next.epoch},\n owner = ${next.owner},\n lease_expires_at = ${next.leaseExpiresAt},\n progress_json = ${progressJson}\n WHERE processor_id = ${current.key.processorId}\n AND processor_version = ${current.key.processorVersion}\n AND thread_id = ${current.key.threadId}\n AND through_sequence = ${current.throughSequence}\n AND epoch = ${current.epoch}\n `;\n yield* checkChanged(operation);\n });\n\n const requireLive = Effect.fn(\"SqliteActivityStore.requireLive\")(function* (\n progress: ActivityProgress | null,\n claim: ActivityClaim,\n requireSequence: boolean,\n ): Effect.fn.Return<ActivityProgress, ActivityOwnershipLost> {\n const now = yield* Clock.currentTimeMillis;\n\n if (\n progress === null ||\n !sameKey(progress.key, claim.key) ||\n progress.owner !== claim.owner ||\n progress.epoch !== claim.epoch ||\n progress.leaseExpiresAt <= now ||\n (requireSequence && progress.throughSequence !== claim.throughSequence)\n ) {\n return yield* ownershipLost(claim);\n }\n\n return progress;\n });\n\n const inspect: ActivityProcessorStore[\"Service\"][\"inspect\"] = Effect.fn(\n \"SqliteActivityStore.inspect\",\n )(function* (key) {\n const decodedKey = yield* decodeInput(ActivityProcessorKey, key, \"inspect activity progress\");\n\n return yield* readProgress(decodedKey, \"inspect activity progress\");\n });\n\n const claim: ActivityProcessorStore[\"Service\"][\"claim\"] = Effect.fn(\"SqliteActivityStore.claim\")(\n function* (request) {\n const operation = \"claim activity progress\";\n const decoded = yield* decodeInput(ActivityClaimRequest, request, operation);\n\n yield* failpoint.hit(\"activity:claim:before\");\n\n const claimed = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readProgress(decoded.key, operation);\n const now = yield* Clock.currentTimeMillis;\n\n if (current !== null && current.owner !== null && current.leaseExpiresAt > now) {\n return yield* ActivityBusy.make({\n key: decoded.key,\n leaseExpiresAt: current.leaseExpiresAt,\n });\n }\n\n const next = yield* Schema.decodeUnknownEffect(ActivityProgress)({\n version: STORAGE_VERSION,\n key: decoded.key,\n throughSequence: current?.throughSequence ?? 0,\n epoch: (current?.epoch ?? 0) + 1,\n owner: decoded.owner,\n leaseExpiresAt: now + decoded.leaseMillis,\n pending: current?.pending ?? null,\n advancedAt: current?.advancedAt ?? null,\n }).pipe(Effect.mapError(() => storeError(operation, \"corrupt\")));\n\n if (current === null) yield* insertProgress(next, operation);\n else yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:claim:after-state\");\n const result = makeClaim(next);\n\n if (result === null) return yield* storeError(operation, \"corrupt\");\n\n return result;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n yield* failpoint.hit(\"activity:claim:after\");\n\n return claimed;\n },\n );\n\n const prepare: ActivityProcessorStore[\"Service\"][\"prepare\"] = Effect.fn(\n \"SqliteActivityStore.prepare\",\n )(function* (request) {\n const operation = \"prepare activity output\";\n const claim = yield* decodeInput(ActivityClaim, request.claim, operation);\n const work = yield* decodeInput(PreparedActivity, request.work, operation);\n\n yield* failpoint.hit(\"activity:prepare:before\");\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* requireLive(\n yield* readProgress(claim.key, operation),\n claim,\n true,\n );\n\n if (current.pending !== null) {\n if (sameWork(current.pending, work)) {\n return { work: current.pending, changed: false } as const;\n }\n\n return yield* ActivityWorkConflict.make({ key: claim.key, workId: work.workId });\n }\n if (!sameKey(work.key, claim.key) || work.sequence !== current.throughSequence + 1) {\n return yield* ActivityWorkConflict.make({ key: claim.key, workId: work.workId });\n }\n const next = ActivityProgress.make({ ...current, pending: work });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:prepare:after-state\");\n\n return { work, changed: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n if (result.changed) yield* failpoint.hit(\"activity:prepare:after\");\n\n return result.work;\n });\n\n const advance: ActivityProcessorStore[\"Service\"][\"advance\"] = Effect.fn(\n \"SqliteActivityStore.advance\",\n )(function* (request) {\n const operation = \"advance activity progress\";\n const claim = yield* decodeInput(ActivityClaim, request.claim, operation);\n const workId = yield* decodeInput(Digest, request.workId, operation);\n\n yield* failpoint.hit(\"activity:advance:before\");\n\n const nextClaim = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* requireLive(\n yield* readProgress(claim.key, operation),\n claim,\n true,\n );\n\n if (current.pending === null || current.pending.workId !== workId) {\n return yield* ActivityWorkConflict.make({ key: claim.key, workId });\n }\n\n const next = ActivityProgress.make({\n ...current,\n throughSequence: current.pending.sequence,\n pending: null,\n advancedAt: yield* Clock.currentTimeMillis,\n });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:advance:after-state\");\n const result = makeClaim(next);\n\n if (result === null) return yield* storeError(operation, \"corrupt\");\n\n return result;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n yield* failpoint.hit(\"activity:advance:after\");\n\n return nextClaim;\n });\n\n const release: ActivityProcessorStore[\"Service\"][\"release\"] = Effect.fn(\n \"SqliteActivityStore.release\",\n )(function* (claim) {\n const operation = \"release activity claim\";\n const decoded = yield* decodeInput(ActivityClaim, claim, operation);\n\n yield* failpoint.hit(\"activity:release:before\");\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readProgress(decoded.key, operation);\n\n if (\n current === null ||\n current.owner !== decoded.owner ||\n current.epoch !== decoded.epoch\n ) {\n return yield* ownershipLost(decoded);\n }\n const next = ActivityProgress.make({ ...current, owner: null, leaseExpiresAt: 0 });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:release:after-state\");\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n yield* failpoint.hit(\"activity:release:after\");\n });\n\n return ActivityProcessorStore.of({ inspect, claim, prepare, advance, release });\n});\n\n/** SQLite activity progress with mutation failpoints kept injectable for recovery tests. */\nexport const activityProcessorStoreLayerWithFailpoints: Layer.Layer<\n ActivityProcessorStore,\n SqliteActivityInitializationError,\n SqlClientService.SqlClient | ActivityMutationFailpoint\n> = Layer.effect(ActivityProcessorStore, makeActivityStore());\n\n/** SQLite activity progress with the production no-op mutation failpoint. */\nexport const activityProcessorStoreLayer: Layer.Layer<\n ActivityProcessorStore,\n SqliteActivityInitializationError,\n SqlClientService.SqlClient\n> = activityProcessorStoreLayerWithFailpoints.pipe(Layer.provide(ActivityMutationFailpoint.layer));\n"],"mappings":"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"}
1
+ {"version":3,"file":"SqliteActivityStore.mjs","names":[],"sources":["../src/SqliteActivityStore.ts"],"sourcesContent":["import {\n ActivityBusy,\n ActivityClaim,\n ActivityClaimRequest,\n ActivityMutationFailpoint,\n type ActivityMutationFailure,\n ActivityOwnershipLost,\n ActivityProcessorKey,\n ActivityProcessorStore,\n ActivityProgress,\n ActivityStoreError,\n ActivityWorkConflict,\n PreparedActivity,\n} from \"@effect-agent/thread/ActivityStore\";\nimport { Digest } from \"@effect-agent/thread/Records\";\nimport { Clock, Effect, Layer, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst STORAGE_VERSION = 1 as const;\nconst METADATA_COMPONENT = \"activity\";\nconst STATE_TABLE = \"effect_agent_activity_processor_state_v1\";\nconst StoredJson = Schema.String.check(Schema.isMaxLength(16 * 1024 * 1024));\nconst sameKey = Schema.toEquivalence(ActivityProcessorKey);\nconst sameWork = Schema.toEquivalence(PreparedActivity);\n\nclass ActivityMetadataRow extends Schema.Class<ActivityMetadataRow>(\n \"@effect-agent/storage-sqlite/ActivityMetadataRow\",\n)({\n version: Schema.Int,\n}) {}\n\nclass ActivityTableRow extends Schema.Class<ActivityTableRow>(\n \"@effect-agent/storage-sqlite/ActivityTableRow\",\n)({\n name: Schema.NonEmptyString,\n}) {}\n\nclass ActivityStateRow extends Schema.Class<ActivityStateRow>(\n \"@effect-agent/storage-sqlite/ActivityStateRow\",\n)({\n processor_id: ActivityProcessorKey.fields.processorId,\n processor_version: ActivityProcessorKey.fields.processorVersion,\n thread_id: ActivityProcessorKey.fields.threadId,\n format_version: Schema.Int,\n through_sequence: ActivityProgress.fields.throughSequence,\n epoch: ActivityProgress.fields.epoch,\n owner: ActivityProgress.fields.owner,\n lease_expires_at: ActivityProgress.fields.leaseExpiresAt,\n progress_json: StoredJson,\n}) {}\n\nclass ActivityChangeCountRow extends Schema.Class<ActivityChangeCountRow>(\n \"@effect-agent/storage-sqlite/ActivityChangeCountRow\",\n)({\n changed: Schema.Int,\n}) {}\n\nconst StoredVersionHeader = Schema.Struct({ version: Schema.Int });\n\nexport type SqliteActivityInitializationError = ActivityStoreError | ActivityMutationFailure;\n\nconst storeError = (\n operation: string,\n reason: ActivityStoreError[\"reason\"] = \"unavailable\",\n): ActivityStoreError => ActivityStoreError.make({ operation, reason });\n\nconst query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n operation: string,\n) => effect.pipe(Effect.mapError(() => storeError(operation)));\n\nconst decodeRows = Effect.fn(\"SqliteActivityStore.decodeRows\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n rows: ReadonlyArray<unknown>,\n operation: string,\n): Effect.fn.Return<ReadonlyArray<A>, ActivityStoreError> {\n return yield* Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n});\n\nconst decodeInput = Effect.fn(\"SqliteActivityStore.decodeInput\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n value: unknown,\n operation: string,\n): Effect.fn.Return<A, ActivityStoreError> {\n return yield* Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError(() => storeError(operation, \"invalid-input\")),\n );\n});\n\nconst encodeProgress = Effect.fn(\"SqliteActivityStore.encodeProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n): Effect.fn.Return<string, ActivityStoreError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ActivityProgress))(progress).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n Effect.flatMap((encoded) =>\n Schema.decodeEffect(StoredJson)(encoded).pipe(\n Effect.mapError(() => storeError(operation, \"invalid-input\")),\n ),\n ),\n );\n});\n\nconst decodeProgress = Effect.fn(\"SqliteActivityStore.decodeProgress\")(function* (\n value: string,\n operation: string,\n): Effect.fn.Return<ActivityProgress, ActivityStoreError> {\n const header = yield* Schema.decodeEffect(Schema.fromJsonString(StoredVersionHeader))(value).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n\n if (header.version !== STORAGE_VERSION) {\n return yield* storeError(operation, \"incompatible\");\n }\n\n const progress = yield* Schema.decodeEffect(Schema.fromJsonString(ActivityProgress))(value).pipe(\n Effect.mapError(() => storeError(operation, \"corrupt\")),\n );\n\n const canonical = yield* encodeProgress(progress, operation);\n\n if (canonical !== value) return yield* storeError(operation, \"corrupt\");\n\n return progress;\n});\n\nconst validateProgress = Effect.fn(\"SqliteActivityStore.validateProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n): Effect.fn.Return<ActivityProgress, ActivityStoreError> {\n if (\n progress.epoch < 1 ||\n (progress.owner === null && progress.leaseExpiresAt !== 0) ||\n (progress.pending !== null &&\n (!sameKey(progress.pending.key, progress.key) ||\n progress.pending.sequence !== progress.throughSequence + 1))\n ) {\n return yield* storeError(operation, \"corrupt\");\n }\n\n return progress;\n});\n\nconst makeClaim = (progress: ActivityProgress): ActivityClaim | null =>\n progress.owner === null\n ? null\n : ActivityClaim.make({\n key: progress.key,\n owner: progress.owner,\n epoch: progress.epoch,\n throughSequence: progress.throughSequence,\n leaseExpiresAt: progress.leaseExpiresAt,\n pending: progress.pending,\n });\n\nconst ownershipLost = (claim: ActivityClaim) =>\n ActivityOwnershipLost.make({ key: claim.key, owner: claim.owner, epoch: claim.epoch });\n\n// The pinned Node SQLite client's writable withTransaction begins with BEGIN IMMEDIATE.\n// Each mutation therefore locks before reading progress, which serializes independent\n// connections without a deferred read-to-write upgrade.\nconst makeActivityStore = Effect.fn(\"SqliteActivityStore.make\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* ActivityMutationFailpoint;\n\n yield* failpoint.hit(\"activity:initialize:before\");\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`\n CREATE TABLE IF NOT EXISTS effect_agent_activity_metadata (\n component TEXT PRIMARY KEY NOT NULL,\n version INTEGER NOT NULL\n )\n `;\n\n const metadataRows = yield* sql<Record<string, unknown>>`\n SELECT version FROM effect_agent_activity_metadata\n WHERE component = ${METADATA_COMPONENT}\n `;\n\n const metadata = yield* decodeRows(\n ActivityMetadataRow,\n metadataRows,\n \"decode activity schema version\",\n );\n\n if (metadata.length > 1) {\n return yield* storeError(\"decode activity schema version\", \"corrupt\");\n }\n const currentVersion = metadata[0]?.version;\n\n if (currentVersion !== undefined && currentVersion !== STORAGE_VERSION) {\n return yield* storeError(\"initialize activity schema\", \"incompatible\");\n }\n if (currentVersion === undefined) {\n const tableRows = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master\n WHERE type = 'table' AND name = ${STATE_TABLE}\n `;\n\n const existing = yield* decodeRows(\n ActivityTableRow,\n tableRows,\n \"inspect activity schema\",\n );\n\n if (existing.length > 0) {\n return yield* storeError(\"initialize activity schema\", \"incompatible\");\n }\n yield* sql`\n CREATE TABLE effect_agent_activity_processor_state_v1 (\n processor_id TEXT NOT NULL,\n processor_version TEXT NOT NULL,\n thread_id TEXT NOT NULL,\n format_version INTEGER NOT NULL,\n through_sequence INTEGER NOT NULL,\n epoch INTEGER NOT NULL,\n owner TEXT,\n lease_expires_at REAL NOT NULL,\n progress_json TEXT NOT NULL,\n PRIMARY KEY (processor_id, processor_version, thread_id)\n )\n `;\n yield* sql`\n INSERT INTO effect_agent_activity_metadata (component, version)\n VALUES (${METADATA_COMPONENT}, ${STORAGE_VERSION})\n `;\n }\n yield* sql`\n SELECT processor_id, processor_version, thread_id, format_version,\n through_sequence, epoch, owner, lease_expires_at, progress_json\n FROM effect_agent_activity_processor_state_v1\n LIMIT 0\n `;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(\"initialize activity schema\"))));\n yield* failpoint.hit(\"activity:initialize:after\");\n\n const readProgress = Effect.fn(\"SqliteActivityStore.readProgress\")(function* (\n key: ActivityProcessorKey,\n operation: string,\n ): Effect.fn.Return<ActivityProgress | null, ActivityStoreError> {\n const rawRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT processor_id, processor_version, thread_id, format_version,\n through_sequence, epoch, owner, lease_expires_at, progress_json\n FROM effect_agent_activity_processor_state_v1\n WHERE processor_id = ${key.processorId}\n AND processor_version = ${key.processorVersion}\n AND thread_id = ${key.threadId}\n `,\n operation,\n );\n\n const rows = yield* decodeRows(ActivityStateRow, rawRows, operation);\n\n if (rows.length === 0) return null;\n if (rows.length !== 1) return yield* storeError(operation, \"corrupt\");\n const row = rows[0];\n\n if (row.format_version !== STORAGE_VERSION) {\n return yield* storeError(operation, \"incompatible\");\n }\n const progress = yield* decodeProgress(row.progress_json, operation);\n\n yield* validateProgress(progress, operation);\n if (\n !sameKey(progress.key, key) ||\n row.processor_id !== key.processorId ||\n row.processor_version !== key.processorVersion ||\n row.thread_id !== key.threadId ||\n row.through_sequence !== progress.throughSequence ||\n row.epoch !== progress.epoch ||\n row.owner !== progress.owner ||\n row.lease_expires_at !== progress.leaseExpiresAt\n ) {\n return yield* storeError(operation, \"corrupt\");\n }\n\n return progress;\n });\n\n const checkChanged = Effect.fn(\"SqliteActivityStore.checkChanged\")(function* (\n operation: string,\n ): Effect.fn.Return<void, ActivityStoreError> {\n const rawRows = yield* query(\n sql<Record<string, unknown>>`SELECT changes() AS changed`,\n operation,\n );\n\n const rows = yield* decodeRows(ActivityChangeCountRow, rawRows, operation);\n\n if (rows.length !== 1 || rows[0].changed !== 1) {\n return yield* storeError(operation, \"corrupt\");\n }\n });\n\n const insertProgress = Effect.fn(\"SqliteActivityStore.insertProgress\")(function* (\n progress: ActivityProgress,\n operation: string,\n ) {\n const progressJson = yield* encodeProgress(progress, operation);\n\n yield* sql`\n INSERT INTO effect_agent_activity_processor_state_v1 (\n processor_id, processor_version, thread_id, format_version, through_sequence,\n epoch, owner, lease_expires_at, progress_json\n ) VALUES (\n ${progress.key.processorId}, ${progress.key.processorVersion}, ${progress.key.threadId},\n ${STORAGE_VERSION}, ${progress.throughSequence}, ${progress.epoch}, ${progress.owner},\n ${progress.leaseExpiresAt}, ${progressJson}\n )\n `;\n yield* checkChanged(operation);\n });\n\n const updateProgress = Effect.fn(\"SqliteActivityStore.updateProgress\")(function* (\n current: ActivityProgress,\n next: ActivityProgress,\n operation: string,\n ) {\n const progressJson = yield* encodeProgress(next, operation);\n\n yield* sql`\n UPDATE effect_agent_activity_processor_state_v1\n SET format_version = ${STORAGE_VERSION},\n through_sequence = ${next.throughSequence},\n epoch = ${next.epoch},\n owner = ${next.owner},\n lease_expires_at = ${next.leaseExpiresAt},\n progress_json = ${progressJson}\n WHERE processor_id = ${current.key.processorId}\n AND processor_version = ${current.key.processorVersion}\n AND thread_id = ${current.key.threadId}\n AND through_sequence = ${current.throughSequence}\n AND epoch = ${current.epoch}\n `;\n yield* checkChanged(operation);\n });\n\n const requireLive = Effect.fn(\"SqliteActivityStore.requireLive\")(function* (\n progress: ActivityProgress | null,\n claim: ActivityClaim,\n requireSequence: boolean,\n ): Effect.fn.Return<ActivityProgress, ActivityOwnershipLost> {\n const now = yield* Clock.currentTimeMillis;\n\n if (\n progress === null ||\n !sameKey(progress.key, claim.key) ||\n progress.owner !== claim.owner ||\n progress.epoch !== claim.epoch ||\n progress.leaseExpiresAt <= now ||\n (requireSequence && progress.throughSequence !== claim.throughSequence)\n ) {\n return yield* ownershipLost(claim);\n }\n\n return progress;\n });\n\n const inspect: ActivityProcessorStore[\"Service\"][\"inspect\"] = Effect.fn(\n \"SqliteActivityStore.inspect\",\n )(function* (key) {\n const decodedKey = yield* decodeInput(ActivityProcessorKey, key, \"inspect activity progress\");\n\n return yield* readProgress(decodedKey, \"inspect activity progress\");\n });\n\n const claim: ActivityProcessorStore[\"Service\"][\"claim\"] = Effect.fn(\"SqliteActivityStore.claim\")(\n function* (request) {\n const operation = \"claim activity progress\";\n const decoded = yield* decodeInput(ActivityClaimRequest, request, operation);\n\n yield* failpoint.hit(\"activity:claim:before\");\n\n const claimed = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readProgress(decoded.key, operation);\n const now = yield* Clock.currentTimeMillis;\n\n if (current !== null && current.owner !== null && current.leaseExpiresAt > now) {\n return yield* ActivityBusy.make({\n key: decoded.key,\n leaseExpiresAt: current.leaseExpiresAt,\n });\n }\n\n const next = yield* Schema.decodeEffect(ActivityProgress)({\n version: STORAGE_VERSION,\n key: decoded.key,\n throughSequence: current?.throughSequence ?? 0,\n epoch: (current?.epoch ?? 0) + 1,\n owner: decoded.owner,\n leaseExpiresAt: now + decoded.leaseMillis,\n pending: current?.pending ?? null,\n advancedAt: current?.advancedAt ?? null,\n }).pipe(Effect.mapError(() => storeError(operation, \"corrupt\")));\n\n if (current === null) yield* insertProgress(next, operation);\n else yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:claim:after-state\");\n const result = makeClaim(next);\n\n if (result === null) return yield* storeError(operation, \"corrupt\");\n\n return result;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n yield* failpoint.hit(\"activity:claim:after\");\n\n return claimed;\n },\n );\n\n const prepare: ActivityProcessorStore[\"Service\"][\"prepare\"] = Effect.fn(\n \"SqliteActivityStore.prepare\",\n )(function* (request) {\n const operation = \"prepare activity output\";\n const claim = yield* decodeInput(ActivityClaim, request.claim, operation);\n const work = yield* decodeInput(PreparedActivity, request.work, operation);\n\n yield* failpoint.hit(\"activity:prepare:before\");\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* requireLive(\n yield* readProgress(claim.key, operation),\n claim,\n true,\n );\n\n if (current.pending !== null) {\n if (sameWork(current.pending, work)) {\n return { work: current.pending, changed: false } as const;\n }\n\n return yield* ActivityWorkConflict.make({ key: claim.key, workId: work.workId });\n }\n if (!sameKey(work.key, claim.key) || work.sequence !== current.throughSequence + 1) {\n return yield* ActivityWorkConflict.make({ key: claim.key, workId: work.workId });\n }\n const next = ActivityProgress.make({ ...current, pending: work });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:prepare:after-state\");\n\n return { work, changed: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n if (result.changed) yield* failpoint.hit(\"activity:prepare:after\");\n\n return result.work;\n });\n\n const advance: ActivityProcessorStore[\"Service\"][\"advance\"] = Effect.fn(\n \"SqliteActivityStore.advance\",\n )(function* (request) {\n const operation = \"advance activity progress\";\n const claim = yield* decodeInput(ActivityClaim, request.claim, operation);\n const workId = yield* decodeInput(Digest, request.workId, operation);\n\n yield* failpoint.hit(\"activity:advance:before\");\n\n const nextClaim = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* requireLive(\n yield* readProgress(claim.key, operation),\n claim,\n true,\n );\n\n if (current.pending === null || current.pending.workId !== workId) {\n return yield* ActivityWorkConflict.make({ key: claim.key, workId });\n }\n\n const next = ActivityProgress.make({\n ...current,\n throughSequence: current.pending.sequence,\n pending: null,\n advancedAt: yield* Clock.currentTimeMillis,\n });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:advance:after-state\");\n const result = makeClaim(next);\n\n if (result === null) return yield* storeError(operation, \"corrupt\");\n\n return result;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n\n yield* failpoint.hit(\"activity:advance:after\");\n\n return nextClaim;\n });\n\n const release: ActivityProcessorStore[\"Service\"][\"release\"] = Effect.fn(\n \"SqliteActivityStore.release\",\n )(function* (claim) {\n const operation = \"release activity claim\";\n const decoded = yield* decodeInput(ActivityClaim, claim, operation);\n\n yield* failpoint.hit(\"activity:release:before\");\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readProgress(decoded.key, operation);\n\n if (\n current === null ||\n current.owner !== decoded.owner ||\n current.epoch !== decoded.epoch\n ) {\n return yield* ownershipLost(decoded);\n }\n const next = ActivityProgress.make({ ...current, owner: null, leaseExpiresAt: 0 });\n\n yield* updateProgress(current, next, operation);\n yield* failpoint.hit(\"activity:release:after-state\");\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(storeError(operation))));\n yield* failpoint.hit(\"activity:release:after\");\n });\n\n return ActivityProcessorStore.of({ inspect, claim, prepare, advance, release });\n});\n\n/** SQLite activity progress with mutation failpoints kept injectable for recovery tests. */\nexport const activityProcessorStoreLayerWithFailpoints: Layer.Layer<\n ActivityProcessorStore,\n SqliteActivityInitializationError,\n SqlClientService.SqlClient | ActivityMutationFailpoint\n> = Layer.effect(ActivityProcessorStore, makeActivityStore());\n\n/** SQLite activity progress with the production no-op mutation failpoint. */\nexport const activityProcessorStoreLayer: Layer.Layer<\n ActivityProcessorStore,\n SqliteActivityInitializationError,\n SqlClientService.SqlClient\n> = activityProcessorStoreLayerWithFailpoints.pipe(Layer.provide(ActivityMutationFailpoint.layer));\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as initializeSqliteJournal } from "./sqlite-journal-D9xFxCw-.mjs";
2
+ import { a as initializeSqliteJournal } from "./sqlite-journal-B1dejOUb.mjs";
3
3
  import { MessageDeliveryError, MessageDeliveryStore } from "@effect-agent/thread/MessageDelivery";
4
4
  import { SqlMessageDeliveryTransaction, makeSqlMessageDeliveryStore } from "@effect-agent/thread/SqlMessageDeliveryStore";
5
5
  import { Effect, Layer } from "effect";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as initializeSqliteJournal } from "./sqlite-journal-D9xFxCw-.mjs";
2
+ import { a as initializeSqliteJournal } from "./sqlite-journal-B1dejOUb.mjs";
3
3
  import { Effect, Layer, Result, Schema } from "effect";
4
4
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
5
5
  import { ScheduleCapacityError, ScheduleChange, ScheduleConflict, ScheduleDueCursor, ScheduleFailpoint, ScheduleId, ScheduleInstant, ScheduleKey, ScheduleNotFound, ScheduleOwner, SchedulePageRequest, ScheduleRecord, ScheduleStorageError, ScheduleStore, defaultSchedulingLimits } from "@effect-agent/thread/Schedule";
@@ -192,7 +192,7 @@ const makeScheduleStore = Effect.gen(function* () {
192
192
  const due = Effect.fn("SqliteScheduleStore.due")(function* (nowMillis, limit, owner, after) {
193
193
  const operation = "query due schedules";
194
194
  const decodedOwner = owner === void 0 ? void 0 : yield* decodeInput(operation, ScheduleOwner, owner);
195
- const cursor = after === void 0 ? void 0 : yield* Schema.decodeUnknownEffect(ScheduleDueCursor)(after).pipe(Effect.mapError(() => corrupt(operation)));
195
+ const cursor = after === void 0 ? void 0 : yield* Schema.decodeEffect(ScheduleDueCursor)(after).pipe(Effect.mapError(() => corrupt(operation)));
196
196
  const continuation = cursor === void 0 ? sql`1 = 1` : sql`
197
197
  (deadline_at_millis, tenant_id, owner_id, schedule_id) >
198
198
  (${cursor.deadlineAtMillis}, ${cursor.owner.tenantId}, ${cursor.owner.ownerId}, ${cursor.scheduleId})`;
@@ -1 +1 @@
1
- {"version":3,"file":"SqliteScheduleStore.mjs","names":[],"sources":["../src/SqliteScheduleStore.ts"],"sourcesContent":["import {\n ScheduleCapacityError,\n ScheduleDueCursor,\n defaultSchedulingLimits,\n ScheduleChange,\n ScheduleConflict,\n ScheduleFailpoint,\n ScheduleKey,\n ScheduleId,\n ScheduleInstant,\n ScheduleNotFound,\n ScheduleOwner,\n type SchedulePage,\n SchedulePageRequest,\n ScheduleRecord,\n ScheduleStorageError,\n ScheduleStore,\n} from \"@effect-agent/thread/Schedule\";\nimport {\n scheduleUsesCapacity,\n applyScheduleChange,\n scheduleDeadline,\n} from \"@effect-agent/thread/ScheduleTransition\";\nimport { Effect, Layer, Result, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport { initializeSqliteJournal } from \"./internal/sqlite-journal.ts\";\nimport type { SqliteStorageConfig } from \"./SqliteStorageConfig.ts\";\nimport type { SqliteStorageFailpoint } from \"./SqliteStorageFailpoint.ts\";\nimport type { SqliteStorageInitializationError } from \"./SqliteThreadStore.ts\";\n\n// Configuration and the immutable pending envelope may each carry the canonical input. Leave\n// room for JSON escaping and bounded status while rejecting an unreadable oversized row.\nconst StoredScheduleJson = Schema.String.check(Schema.isMaxLength(16 * 1024 * 1024));\nconst StoredDeadline = Schema.NullOr(ScheduleInstant);\n\nclass ScheduleRow extends Schema.Class<ScheduleRow>(\"@effect-agent/storage-sqlite/ScheduleRow\")({\n tenant_id: ScheduleOwner.fields.tenantId,\n owner_id: ScheduleOwner.fields.ownerId,\n schedule_id: ScheduleId,\n deadline_at_millis: StoredDeadline,\n record_json: StoredScheduleJson,\n}) {}\n\nconst ScheduleDueRow = Schema.Struct({\n tenant_id: ScheduleOwner.fields.tenantId,\n owner_id: ScheduleOwner.fields.ownerId,\n schedule_id: ScheduleId,\n deadline_at_millis: ScheduleInstant,\n});\n\nclass ScheduleCountRow extends Schema.Class<ScheduleCountRow>(\n \"@effect-agent/storage-sqlite/ScheduleCountRow\",\n)({\n schedule_count: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\nclass ScheduleDeadlineRow extends Schema.Class<ScheduleDeadlineRow>(\n \"@effect-agent/storage-sqlite/ScheduleDeadlineRow\",\n)({\n deadline_at_millis: StoredDeadline,\n}) {}\n\nconst unavailable = (operation: string): ScheduleStorageError =>\n ScheduleStorageError.make({ operation, reason: \"unavailable\" });\n\nconst corrupt = (operation: string): ScheduleStorageError =>\n ScheduleStorageError.make({ operation, reason: \"corrupt\" });\n\nconst decodeRows = Effect.fn(\"SqliteScheduleStore.decodeRows\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n rows: ReadonlyArray<unknown>,\n operation: string,\n): Effect.fn.Return<A, ScheduleStorageError> {\n return yield* Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n});\n\nconst decodeRecord = Effect.fn(\"SqliteScheduleStore.decodeRecord\")(function* (\n row: ScheduleRow,\n): Effect.fn.Return<ScheduleRecord, ScheduleStorageError> {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(ScheduleRecord))(\n row.record_json,\n ).pipe(Effect.mapError(() => corrupt(\"decode schedule\")));\n\n if (\n record.owner.tenantId !== row.tenant_id ||\n record.owner.ownerId !== row.owner_id ||\n record.scheduleId !== row.schedule_id ||\n scheduleDeadline(record) !== row.deadline_at_millis\n ) {\n return yield* corrupt(\"decode schedule identity\");\n }\n\n return record;\n});\n\nconst encodeRecord = Effect.fn(\"SqliteScheduleStore.encodeRecord\")(function* (\n record: ScheduleRecord,\n): Effect.fn.Return<string, ScheduleStorageError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ScheduleRecord))(record).pipe(\n Effect.mapError(() => corrupt(\"encode schedule\")),\n );\n});\n\nconst decodeInput = Effect.fn(\"SqliteScheduleStore.decodeInput\")(function* <A, I>(\n operation: string,\n schema: Schema.Codec<A, I, never>,\n value: unknown,\n): Effect.fn.Return<A, ScheduleStorageError> {\n return yield* Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n});\n\nconst makeScheduleStore = Effect.gen(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const scheduleFailpoint = yield* ScheduleFailpoint;\n\n yield* initializeSqliteJournal();\n\n const readRows = Effect.fn(\"SqliteScheduleStore.readRows\")(function* (\n key: ScheduleKey,\n operation: string,\n ): Effect.fn.Return<ReadonlyArray<ScheduleRow>, ScheduleStorageError> {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${key.owner.tenantId}\n AND owner_id = ${key.owner.ownerId}\n AND schedule_id = ${key.scheduleId}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return yield* decodeRows(Schema.Array(ScheduleRow), rows, operation);\n });\n\n const readOne = Effect.fn(\"SqliteScheduleStore.readOne\")(function* (\n key: ScheduleKey,\n operation: string,\n ): Effect.fn.Return<ScheduleRecord | null, ScheduleStorageError> {\n const rows = yield* readRows(key, operation);\n\n if (rows.length === 0) return null;\n if (rows.length !== 1) return yield* corrupt(operation);\n\n return yield* decodeRecord(rows[0]);\n });\n\n const insert: ScheduleStore[\"Service\"][\"insert\"] = Effect.fn(\"SqliteScheduleStore.insert\")(\n function* (record, ownerLimit) {\n const operation = \"insert schedule\";\n const canonical = yield* decodeInput(operation, ScheduleRecord, record);\n const recordJson = yield* encodeRecord(canonical);\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const existing = yield* readOne(canonical, operation);\n\n if (existing !== null) {\n if (existing.creationFingerprint === canonical.creationFingerprint) {\n return { record: existing, inserted: false } as const;\n }\n\n return yield* ScheduleConflict.make({\n reason: \"creation\",\n key: { owner: canonical.owner, scheduleId: canonical.scheduleId },\n });\n }\n\n const rawCounts = yield* sql<Record<string, unknown>>`\n SELECT COUNT(*) AS schedule_count\n FROM effect_agent_schedules\n WHERE tenant_id = ${canonical.owner.tenantId}\n AND owner_id = ${canonical.owner.ownerId}\n AND (json_extract(record_json, '$.pending') IS NOT NULL OR\n (json_extract(record_json, '$.state') != 'cancelled' AND json_extract(record_json, '$.nextAtMillis') IS NOT NULL))\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const counts = yield* decodeRows(Schema.Array(ScheduleCountRow), rawCounts, operation);\n\n if (counts.length !== 1) return yield* corrupt(operation);\n if (counts[0].schedule_count >= ownerLimit) {\n return yield* ScheduleCapacityError.make({ limit: ownerLimit });\n }\n yield* scheduleFailpoint.hit(\"schedule:insert:before\");\n yield* sql`\n INSERT INTO effect_agent_schedules (\n tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n ) VALUES (\n ${canonical.owner.tenantId},\n ${canonical.owner.ownerId},\n ${canonical.scheduleId},\n ${scheduleDeadline(canonical)},\n ${recordJson}\n )\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return { record: canonical, inserted: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(unavailable(operation))));\n\n if (result.inserted) yield* scheduleFailpoint.hit(\"schedule:insert:after\");\n\n return result.record;\n },\n );\n\n const get: ScheduleStore[\"Service\"][\"get\"] = Effect.fn(\"SqliteScheduleStore.get\")(\n function* (key) {\n const decodedKey = yield* decodeInput(\"get schedule\", ScheduleKey, key);\n\n return yield* readOne(decodedKey, \"get schedule\");\n },\n );\n\n const list: ScheduleStore[\"Service\"][\"list\"] = Effect.fn(\"SqliteScheduleStore.list\")(function* (\n request: SchedulePageRequest,\n ): Effect.fn.Return<SchedulePage, ScheduleStorageError> {\n const operation = \"list schedules\";\n const decodedRequest = yield* decodeInput(operation, SchedulePageRequest, request);\n\n const rows =\n decodedRequest.after === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedRequest.owner.tenantId}\n AND owner_id = ${decodedRequest.owner.ownerId}\n ORDER BY schedule_id\n LIMIT ${decodedRequest.limit + 1}\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedRequest.owner.tenantId}\n AND owner_id = ${decodedRequest.owner.ownerId}\n AND schedule_id > ${decodedRequest.after}\n ORDER BY schedule_id\n LIMIT ${decodedRequest.limit + 1}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleRow), rows, operation);\n const records = yield* Effect.forEach(decoded, decodeRecord);\n const hasNext = records.length > decodedRequest.limit;\n const items = hasNext ? records.slice(0, decodedRequest.limit) : records;\n\n return { items, next: hasNext ? (items.at(-1)?.scheduleId ?? null) : null };\n });\n\n const change: ScheduleStore[\"Service\"][\"change\"] = Effect.fn(\"SqliteScheduleStore.change\")(\n function* (key, change, ownerLimit = defaultSchedulingLimits.maxSchedulesPerOwner) {\n const operation = \"change schedule\";\n const decodedKey = yield* decodeInput(operation, ScheduleKey, key);\n const decodedChange = yield* decodeInput(operation, ScheduleChange, change);\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readOne(decodedKey, operation);\n\n if (current === null) return yield* ScheduleNotFound.make({ key: decodedKey });\n const transition = applyScheduleChange(current, decodedChange);\n\n if (Result.isFailure(transition)) return yield* transition.failure;\n const next = transition.success;\n\n if (!scheduleUsesCapacity(current) && scheduleUsesCapacity(next)) {\n const rawCounts = yield* sql<Record<string, unknown>>`\n SELECT COUNT(*) AS schedule_count FROM effect_agent_schedules\n WHERE tenant_id = ${key.owner.tenantId} AND owner_id = ${key.owner.ownerId}\n AND (json_extract(record_json, '$.pending') IS NOT NULL OR\n (json_extract(record_json, '$.state') != 'cancelled' AND json_extract(record_json, '$.nextAtMillis') IS NOT NULL))\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const counts = yield* decodeRows(\n Schema.Array(ScheduleCountRow),\n rawCounts,\n operation,\n );\n\n if (counts.length !== 1) return yield* corrupt(operation);\n if (counts[0].schedule_count >= ownerLimit)\n return yield* ScheduleCapacityError.make({ limit: ownerLimit });\n }\n if (next === current) return { record: current, changed: false } as const;\n const recordJson = yield* encodeRecord(next);\n\n yield* scheduleFailpoint.hit(`schedule:${decodedChange._tag.toLowerCase()}:before`);\n yield* sql`\n UPDATE effect_agent_schedules\n SET deadline_at_millis = ${scheduleDeadline(next)}, record_json = ${recordJson}\n WHERE tenant_id = ${decodedKey.owner.tenantId}\n AND owner_id = ${decodedKey.owner.ownerId}\n AND schedule_id = ${decodedKey.scheduleId}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return { record: next, changed: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(unavailable(operation))));\n\n if (result.changed) {\n yield* scheduleFailpoint.hit(`schedule:${decodedChange._tag.toLowerCase()}:after`);\n }\n\n return result.record;\n },\n );\n\n const due: ScheduleStore[\"Service\"][\"due\"] = Effect.fn(\"SqliteScheduleStore.due\")(function* (\n nowMillis,\n limit,\n owner?: ScheduleOwner,\n after?: ScheduleDueCursor,\n ) {\n const operation = \"query due schedules\";\n\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(operation, ScheduleOwner, owner);\n\n const cursor =\n after === undefined\n ? undefined\n : yield* Schema.decodeUnknownEffect(ScheduleDueCursor)(after).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n\n const continuation =\n cursor === undefined\n ? sql`1 = 1`\n : sql`\n (deadline_at_millis, tenant_id, owner_id, schedule_id) >\n (${cursor.deadlineAtMillis}, ${cursor.owner.tenantId}, ${cursor.owner.ownerId}, ${cursor.scheduleId})`;\n\n const rows =\n decodedOwner === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis\n FROM effect_agent_schedules\n WHERE deadline_at_millis <= ${nowMillis} AND ${continuation}\n ORDER BY deadline_at_millis, tenant_id, owner_id, schedule_id\n LIMIT ${limit}\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedOwner.tenantId}\n AND owner_id = ${decodedOwner.ownerId}\n AND deadline_at_millis <= ${nowMillis} AND ${continuation}\n ORDER BY deadline_at_millis, schedule_id\n LIMIT ${limit}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleDueRow), rows, operation);\n\n return decoded.map((row) => ({\n owner: { tenantId: row.tenant_id, ownerId: row.owner_id },\n scheduleId: row.schedule_id,\n deadlineAtMillis: row.deadline_at_millis,\n }));\n });\n\n const nextDeadline: ScheduleStore[\"Service\"][\"nextDeadline\"] = Effect.fn(\n \"SqliteScheduleStore.nextDeadline\",\n )(function* (owner?: ScheduleOwner) {\n const operation = \"query next schedule deadline\";\n\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(operation, ScheduleOwner, owner);\n\n const rows =\n decodedOwner === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT MIN(deadline_at_millis) AS deadline_at_millis\n FROM effect_agent_schedules\n WHERE deadline_at_millis IS NOT NULL\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT MIN(deadline_at_millis) AS deadline_at_millis\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedOwner.tenantId}\n AND owner_id = ${decodedOwner.ownerId}\n AND deadline_at_millis IS NOT NULL\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleDeadlineRow), rows, operation);\n\n if (decoded.length !== 1) return yield* corrupt(operation);\n\n return decoded[0].deadline_at_millis;\n });\n\n return ScheduleStore.of({ insert, get, list, change, due, nextDeadline });\n});\n\n/** SQLite implementation of the atomic ScheduleStore port. */\nexport const scheduleStoreLayer: Layer.Layer<\n ScheduleStore,\n SqliteStorageInitializationError,\n SqliteStorageConfig | SqliteStorageFailpoint | SqlClientService.SqlClient\n> = Layer.effect(ScheduleStore)(makeScheduleStore);\n"],"mappings":"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"}
1
+ {"version":3,"file":"SqliteScheduleStore.mjs","names":[],"sources":["../src/SqliteScheduleStore.ts"],"sourcesContent":["import {\n ScheduleCapacityError,\n ScheduleDueCursor,\n defaultSchedulingLimits,\n ScheduleChange,\n ScheduleConflict,\n ScheduleFailpoint,\n ScheduleKey,\n ScheduleId,\n ScheduleInstant,\n ScheduleNotFound,\n ScheduleOwner,\n type SchedulePage,\n SchedulePageRequest,\n ScheduleRecord,\n ScheduleStorageError,\n ScheduleStore,\n} from \"@effect-agent/thread/Schedule\";\nimport {\n scheduleUsesCapacity,\n applyScheduleChange,\n scheduleDeadline,\n} from \"@effect-agent/thread/ScheduleTransition\";\nimport { Effect, Layer, Result, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\n\nimport { initializeSqliteJournal } from \"./internal/sqlite-journal.ts\";\nimport type { SqliteStorageConfig } from \"./SqliteStorageConfig.ts\";\nimport type { SqliteStorageFailpoint } from \"./SqliteStorageFailpoint.ts\";\nimport type { SqliteStorageInitializationError } from \"./SqliteThreadStore.ts\";\n\n// Configuration and the immutable pending envelope may each carry the canonical input. Leave\n// room for JSON escaping and bounded status while rejecting an unreadable oversized row.\nconst StoredScheduleJson = Schema.String.check(Schema.isMaxLength(16 * 1024 * 1024));\nconst StoredDeadline = Schema.NullOr(ScheduleInstant);\n\nclass ScheduleRow extends Schema.Class<ScheduleRow>(\"@effect-agent/storage-sqlite/ScheduleRow\")({\n tenant_id: ScheduleOwner.fields.tenantId,\n owner_id: ScheduleOwner.fields.ownerId,\n schedule_id: ScheduleId,\n deadline_at_millis: StoredDeadline,\n record_json: StoredScheduleJson,\n}) {}\n\nconst ScheduleDueRow = Schema.Struct({\n tenant_id: ScheduleOwner.fields.tenantId,\n owner_id: ScheduleOwner.fields.ownerId,\n schedule_id: ScheduleId,\n deadline_at_millis: ScheduleInstant,\n});\n\nclass ScheduleCountRow extends Schema.Class<ScheduleCountRow>(\n \"@effect-agent/storage-sqlite/ScheduleCountRow\",\n)({\n schedule_count: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),\n}) {}\n\nclass ScheduleDeadlineRow extends Schema.Class<ScheduleDeadlineRow>(\n \"@effect-agent/storage-sqlite/ScheduleDeadlineRow\",\n)({\n deadline_at_millis: StoredDeadline,\n}) {}\n\nconst unavailable = (operation: string): ScheduleStorageError =>\n ScheduleStorageError.make({ operation, reason: \"unavailable\" });\n\nconst corrupt = (operation: string): ScheduleStorageError =>\n ScheduleStorageError.make({ operation, reason: \"corrupt\" });\n\nconst decodeRows = Effect.fn(\"SqliteScheduleStore.decodeRows\")(function* <A, I>(\n schema: Schema.Codec<A, I, never>,\n rows: ReadonlyArray<unknown>,\n operation: string,\n): Effect.fn.Return<A, ScheduleStorageError> {\n return yield* Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n});\n\nconst decodeRecord = Effect.fn(\"SqliteScheduleStore.decodeRecord\")(function* (\n row: ScheduleRow,\n): Effect.fn.Return<ScheduleRecord, ScheduleStorageError> {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(ScheduleRecord))(\n row.record_json,\n ).pipe(Effect.mapError(() => corrupt(\"decode schedule\")));\n\n if (\n record.owner.tenantId !== row.tenant_id ||\n record.owner.ownerId !== row.owner_id ||\n record.scheduleId !== row.schedule_id ||\n scheduleDeadline(record) !== row.deadline_at_millis\n ) {\n return yield* corrupt(\"decode schedule identity\");\n }\n\n return record;\n});\n\nconst encodeRecord = Effect.fn(\"SqliteScheduleStore.encodeRecord\")(function* (\n record: ScheduleRecord,\n): Effect.fn.Return<string, ScheduleStorageError> {\n return yield* Schema.encodeEffect(Schema.fromJsonString(ScheduleRecord))(record).pipe(\n Effect.mapError(() => corrupt(\"encode schedule\")),\n );\n});\n\nconst decodeInput = Effect.fn(\"SqliteScheduleStore.decodeInput\")(function* <A, I>(\n operation: string,\n schema: Schema.Codec<A, I, never>,\n value: unknown,\n): Effect.fn.Return<A, ScheduleStorageError> {\n return yield* Schema.decodeUnknownEffect(schema)(value).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n});\n\nconst makeScheduleStore = Effect.gen(function* () {\n const sql = yield* SqlClientService.SqlClient;\n const scheduleFailpoint = yield* ScheduleFailpoint;\n\n yield* initializeSqliteJournal();\n\n const readRows = Effect.fn(\"SqliteScheduleStore.readRows\")(function* (\n key: ScheduleKey,\n operation: string,\n ): Effect.fn.Return<ReadonlyArray<ScheduleRow>, ScheduleStorageError> {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${key.owner.tenantId}\n AND owner_id = ${key.owner.ownerId}\n AND schedule_id = ${key.scheduleId}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return yield* decodeRows(Schema.Array(ScheduleRow), rows, operation);\n });\n\n const readOne = Effect.fn(\"SqliteScheduleStore.readOne\")(function* (\n key: ScheduleKey,\n operation: string,\n ): Effect.fn.Return<ScheduleRecord | null, ScheduleStorageError> {\n const rows = yield* readRows(key, operation);\n\n if (rows.length === 0) return null;\n if (rows.length !== 1) return yield* corrupt(operation);\n\n return yield* decodeRecord(rows[0]);\n });\n\n const insert: ScheduleStore[\"Service\"][\"insert\"] = Effect.fn(\"SqliteScheduleStore.insert\")(\n function* (record, ownerLimit) {\n const operation = \"insert schedule\";\n const canonical = yield* decodeInput(operation, ScheduleRecord, record);\n const recordJson = yield* encodeRecord(canonical);\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const existing = yield* readOne(canonical, operation);\n\n if (existing !== null) {\n if (existing.creationFingerprint === canonical.creationFingerprint) {\n return { record: existing, inserted: false } as const;\n }\n\n return yield* ScheduleConflict.make({\n reason: \"creation\",\n key: { owner: canonical.owner, scheduleId: canonical.scheduleId },\n });\n }\n\n const rawCounts = yield* sql<Record<string, unknown>>`\n SELECT COUNT(*) AS schedule_count\n FROM effect_agent_schedules\n WHERE tenant_id = ${canonical.owner.tenantId}\n AND owner_id = ${canonical.owner.ownerId}\n AND (json_extract(record_json, '$.pending') IS NOT NULL OR\n (json_extract(record_json, '$.state') != 'cancelled' AND json_extract(record_json, '$.nextAtMillis') IS NOT NULL))\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const counts = yield* decodeRows(Schema.Array(ScheduleCountRow), rawCounts, operation);\n\n if (counts.length !== 1) return yield* corrupt(operation);\n if (counts[0].schedule_count >= ownerLimit) {\n return yield* ScheduleCapacityError.make({ limit: ownerLimit });\n }\n yield* scheduleFailpoint.hit(\"schedule:insert:before\");\n yield* sql`\n INSERT INTO effect_agent_schedules (\n tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n ) VALUES (\n ${canonical.owner.tenantId},\n ${canonical.owner.ownerId},\n ${canonical.scheduleId},\n ${scheduleDeadline(canonical)},\n ${recordJson}\n )\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return { record: canonical, inserted: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(unavailable(operation))));\n\n if (result.inserted) yield* scheduleFailpoint.hit(\"schedule:insert:after\");\n\n return result.record;\n },\n );\n\n const get: ScheduleStore[\"Service\"][\"get\"] = Effect.fn(\"SqliteScheduleStore.get\")(\n function* (key) {\n const decodedKey = yield* decodeInput(\"get schedule\", ScheduleKey, key);\n\n return yield* readOne(decodedKey, \"get schedule\");\n },\n );\n\n const list: ScheduleStore[\"Service\"][\"list\"] = Effect.fn(\"SqliteScheduleStore.list\")(function* (\n request: SchedulePageRequest,\n ): Effect.fn.Return<SchedulePage, ScheduleStorageError> {\n const operation = \"list schedules\";\n const decodedRequest = yield* decodeInput(operation, SchedulePageRequest, request);\n\n const rows =\n decodedRequest.after === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedRequest.owner.tenantId}\n AND owner_id = ${decodedRequest.owner.ownerId}\n ORDER BY schedule_id\n LIMIT ${decodedRequest.limit + 1}\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis, record_json\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedRequest.owner.tenantId}\n AND owner_id = ${decodedRequest.owner.ownerId}\n AND schedule_id > ${decodedRequest.after}\n ORDER BY schedule_id\n LIMIT ${decodedRequest.limit + 1}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleRow), rows, operation);\n const records = yield* Effect.forEach(decoded, decodeRecord);\n const hasNext = records.length > decodedRequest.limit;\n const items = hasNext ? records.slice(0, decodedRequest.limit) : records;\n\n return { items, next: hasNext ? (items.at(-1)?.scheduleId ?? null) : null };\n });\n\n const change: ScheduleStore[\"Service\"][\"change\"] = Effect.fn(\"SqliteScheduleStore.change\")(\n function* (key, change, ownerLimit = defaultSchedulingLimits.maxSchedulesPerOwner) {\n const operation = \"change schedule\";\n const decodedKey = yield* decodeInput(operation, ScheduleKey, key);\n const decodedChange = yield* decodeInput(operation, ScheduleChange, change);\n\n const result = yield* sql\n .withTransaction(\n Effect.gen(function* () {\n const current = yield* readOne(decodedKey, operation);\n\n if (current === null) return yield* ScheduleNotFound.make({ key: decodedKey });\n const transition = applyScheduleChange(current, decodedChange);\n\n if (Result.isFailure(transition)) return yield* transition.failure;\n const next = transition.success;\n\n if (!scheduleUsesCapacity(current) && scheduleUsesCapacity(next)) {\n const rawCounts = yield* sql<Record<string, unknown>>`\n SELECT COUNT(*) AS schedule_count FROM effect_agent_schedules\n WHERE tenant_id = ${key.owner.tenantId} AND owner_id = ${key.owner.ownerId}\n AND (json_extract(record_json, '$.pending') IS NOT NULL OR\n (json_extract(record_json, '$.state') != 'cancelled' AND json_extract(record_json, '$.nextAtMillis') IS NOT NULL))\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const counts = yield* decodeRows(\n Schema.Array(ScheduleCountRow),\n rawCounts,\n operation,\n );\n\n if (counts.length !== 1) return yield* corrupt(operation);\n if (counts[0].schedule_count >= ownerLimit)\n return yield* ScheduleCapacityError.make({ limit: ownerLimit });\n }\n if (next === current) return { record: current, changed: false } as const;\n const recordJson = yield* encodeRecord(next);\n\n yield* scheduleFailpoint.hit(`schedule:${decodedChange._tag.toLowerCase()}:before`);\n yield* sql`\n UPDATE effect_agent_schedules\n SET deadline_at_millis = ${scheduleDeadline(next)}, record_json = ${recordJson}\n WHERE tenant_id = ${decodedKey.owner.tenantId}\n AND owner_id = ${decodedKey.owner.ownerId}\n AND schedule_id = ${decodedKey.scheduleId}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n return { record: next, changed: true } as const;\n }),\n )\n .pipe(Effect.catchTag(\"SqlError\", () => Effect.fail(unavailable(operation))));\n\n if (result.changed) {\n yield* scheduleFailpoint.hit(`schedule:${decodedChange._tag.toLowerCase()}:after`);\n }\n\n return result.record;\n },\n );\n\n const due: ScheduleStore[\"Service\"][\"due\"] = Effect.fn(\"SqliteScheduleStore.due\")(function* (\n nowMillis,\n limit,\n owner?: ScheduleOwner,\n after?: ScheduleDueCursor,\n ) {\n const operation = \"query due schedules\";\n\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(operation, ScheduleOwner, owner);\n\n const cursor =\n after === undefined\n ? undefined\n : yield* Schema.decodeEffect(ScheduleDueCursor)(after).pipe(\n Effect.mapError(() => corrupt(operation)),\n );\n\n const continuation =\n cursor === undefined\n ? sql`1 = 1`\n : sql`\n (deadline_at_millis, tenant_id, owner_id, schedule_id) >\n (${cursor.deadlineAtMillis}, ${cursor.owner.tenantId}, ${cursor.owner.ownerId}, ${cursor.scheduleId})`;\n\n const rows =\n decodedOwner === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis\n FROM effect_agent_schedules\n WHERE deadline_at_millis <= ${nowMillis} AND ${continuation}\n ORDER BY deadline_at_millis, tenant_id, owner_id, schedule_id\n LIMIT ${limit}\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT tenant_id, owner_id, schedule_id, deadline_at_millis\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedOwner.tenantId}\n AND owner_id = ${decodedOwner.ownerId}\n AND deadline_at_millis <= ${nowMillis} AND ${continuation}\n ORDER BY deadline_at_millis, schedule_id\n LIMIT ${limit}\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleDueRow), rows, operation);\n\n return decoded.map((row) => ({\n owner: { tenantId: row.tenant_id, ownerId: row.owner_id },\n scheduleId: row.schedule_id,\n deadlineAtMillis: row.deadline_at_millis,\n }));\n });\n\n const nextDeadline: ScheduleStore[\"Service\"][\"nextDeadline\"] = Effect.fn(\n \"SqliteScheduleStore.nextDeadline\",\n )(function* (owner?: ScheduleOwner) {\n const operation = \"query next schedule deadline\";\n\n const decodedOwner =\n owner === undefined ? undefined : yield* decodeInput(operation, ScheduleOwner, owner);\n\n const rows =\n decodedOwner === undefined\n ? yield* sql<Record<string, unknown>>`\n SELECT MIN(deadline_at_millis) AS deadline_at_millis\n FROM effect_agent_schedules\n WHERE deadline_at_millis IS NOT NULL\n `.pipe(Effect.mapError(() => unavailable(operation)))\n : yield* sql<Record<string, unknown>>`\n SELECT MIN(deadline_at_millis) AS deadline_at_millis\n FROM effect_agent_schedules\n WHERE tenant_id = ${decodedOwner.tenantId}\n AND owner_id = ${decodedOwner.ownerId}\n AND deadline_at_millis IS NOT NULL\n `.pipe(Effect.mapError(() => unavailable(operation)));\n\n const decoded = yield* decodeRows(Schema.Array(ScheduleDeadlineRow), rows, operation);\n\n if (decoded.length !== 1) return yield* corrupt(operation);\n\n return decoded[0].deadline_at_millis;\n });\n\n return ScheduleStore.of({ insert, get, list, change, due, nextDeadline });\n});\n\n/** SQLite implementation of the atomic ScheduleStore port. */\nexport const scheduleStoreLayer: Layer.Layer<\n ScheduleStore,\n SqliteStorageInitializationError,\n SqliteStorageConfig | SqliteStorageFailpoint | SqlClientService.SqlClient\n> = Layer.effect(ScheduleStore)(makeScheduleStore);\n"],"mappings":";;;;;;;;AAiCA,MAAM,qBAAqB,OAAO,OAAO,MAAM,OAAO,YAAY,QAAgB,CAAC;AACnF,MAAM,iBAAiB,OAAO,OAAO,eAAe;AAEpD,IAAM,cAAN,cAA0B,OAAO,MAAmB,0CAA0C,CAAC,CAAC;CAC9F,WAAW,cAAc,OAAO;CAChC,UAAU,cAAc,OAAO;CAC/B,aAAa;CACb,oBAAoB;CACpB,aAAa;AACf,CAAC,CAAC,CAAC,CAAC;AAEJ,MAAM,iBAAiB,OAAO,OAAO;CACnC,WAAW,cAAc,OAAO;CAChC,UAAU,cAAc,OAAO;CAC/B,aAAa;CACb,oBAAoB;AACtB,CAAC;AAED,IAAM,mBAAN,cAA+B,OAAO,MACpC,+CACF,CAAC,CAAC,EACA,gBAAgB,OAAO,IAAI,MAAM,OAAO,uBAAuB,CAAC,CAAC,EACnE,CAAC,CAAC,CAAC,CAAC;AAEJ,IAAM,sBAAN,cAAkC,OAAO,MACvC,kDACF,CAAC,CAAC,EACA,oBAAoB,eACtB,CAAC,CAAC,CAAC,CAAC;AAEJ,MAAM,eAAe,cACnB,qBAAqB,KAAK;CAAE;CAAW,QAAQ;AAAc,CAAC;AAEhE,MAAM,WAAW,cACf,qBAAqB,KAAK;CAAE;CAAW,QAAQ;AAAU,CAAC;AAE5D,MAAM,aAAa,OAAO,GAAG,gCAAgC,CAAC,CAAC,WAC7D,QACA,MACA,WAC2C;CAC3C,OAAO,OAAO,OAAO,oBAAoB,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,KACrD,OAAO,eAAe,QAAQ,SAAS,CAAC,CAC1C;AACF,CAAC;AAED,MAAM,eAAe,OAAO,GAAG,kCAAkC,CAAC,CAAC,WACjE,KACwD;CACxD,MAAM,SAAS,OAAO,OAAO,aAAa,OAAO,eAAe,cAAc,CAAC,CAAC,CAC9E,IAAI,WACN,CAAC,CAAC,KAAK,OAAO,eAAe,QAAQ,iBAAiB,CAAC,CAAC;CAExD,IACE,OAAO,MAAM,aAAa,IAAI,aAC9B,OAAO,MAAM,YAAY,IAAI,YAC7B,OAAO,eAAe,IAAI,eAC1B,iBAAiB,MAAM,MAAM,IAAI,oBAEjC,OAAO,OAAO,QAAQ,0BAA0B;CAGlD,OAAO;AACT,CAAC;AAED,MAAM,eAAe,OAAO,GAAG,kCAAkC,CAAC,CAAC,WACjE,QACgD;CAChD,OAAO,OAAO,OAAO,aAAa,OAAO,eAAe,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAC/E,OAAO,eAAe,QAAQ,iBAAiB,CAAC,CAClD;AACF,CAAC;AAED,MAAM,cAAc,OAAO,GAAG,iCAAiC,CAAC,CAAC,WAC/D,WACA,QACA,OAC2C;CAC3C,OAAO,OAAO,OAAO,oBAAoB,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACtD,OAAO,eAAe,QAAQ,SAAS,CAAC,CAC1C;AACF,CAAC;AAED,MAAM,oBAAoB,OAAO,IAAI,aAAa;CAChD,MAAM,MAAM,OAAO,iBAAiB;CACpC,MAAM,oBAAoB,OAAO;CAEjC,OAAO,wBAAwB;CAE/B,MAAM,WAAW,OAAO,GAAG,8BAA8B,CAAC,CAAC,WACzD,KACA,WACoE;EACpE,MAAM,OAAO,OAAO,GAA4B;;;0BAG1B,IAAI,MAAM,SAAS;yBACpB,IAAI,MAAM,QAAQ;4BACf,IAAI,WAAW;MACrC,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;EAEpD,OAAO,OAAO,WAAW,OAAO,MAAM,WAAW,GAAG,MAAM,SAAS;CACrE,CAAC;CAED,MAAM,UAAU,OAAO,GAAG,6BAA6B,CAAC,CAAC,WACvD,KACA,WAC+D;EAC/D,MAAM,OAAO,OAAO,SAAS,KAAK,SAAS;EAE3C,IAAI,KAAK,WAAW,GAAG,OAAO;EAC9B,IAAI,KAAK,WAAW,GAAG,OAAO,OAAO,QAAQ,SAAS;EAEtD,OAAO,OAAO,aAAa,KAAK,EAAE;CACpC,CAAC;CAED,MAAM,SAA6C,OAAO,GAAG,4BAA4B,CAAC,CACxF,WAAW,QAAQ,YAAY;EAC7B,MAAM,YAAY;EAClB,MAAM,YAAY,OAAO,YAAY,WAAW,gBAAgB,MAAM;EACtE,MAAM,aAAa,OAAO,aAAa,SAAS;EAEhD,MAAM,SAAS,OAAO,IACnB,gBACC,OAAO,IAAI,aAAa;GACtB,MAAM,WAAW,OAAO,QAAQ,WAAW,SAAS;GAEpD,IAAI,aAAa,MAAM;IACrB,IAAI,SAAS,wBAAwB,UAAU,qBAC7C,OAAO;KAAE,QAAQ;KAAU,UAAU;IAAM;IAG7C,OAAO,OAAO,iBAAiB,KAAK;KAClC,QAAQ;KACR,KAAK;MAAE,OAAO,UAAU;MAAO,YAAY,UAAU;KAAW;IAClE,CAAC;GACH;GAEA,MAAM,YAAY,OAAO,GAA4B;;;gCAGjC,UAAU,MAAM,SAAS;+BAC1B,UAAU,MAAM,QAAQ;;;YAG3C,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;GAElD,MAAM,SAAS,OAAO,WAAW,OAAO,MAAM,gBAAgB,GAAG,WAAW,SAAS;GAErF,IAAI,OAAO,WAAW,GAAG,OAAO,OAAO,QAAQ,SAAS;GACxD,IAAI,OAAO,EAAE,CAAC,kBAAkB,YAC9B,OAAO,OAAO,sBAAsB,KAAK,EAAE,OAAO,WAAW,CAAC;GAEhE,OAAO,kBAAkB,IAAI,wBAAwB;GACrD,OAAO,GAAG;;;;gBAIN,UAAU,MAAM,SAAS;gBACzB,UAAU,MAAM,QAAQ;gBACxB,UAAU,WAAW;gBACrB,iBAAiB,SAAS,EAAE;gBAC5B,WAAW;;YAEf,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;GAElD,OAAO;IAAE,QAAQ;IAAW,UAAU;GAAK;EAC7C,CAAC,CACH,CAAC,CACA,KAAK,OAAO,SAAS,kBAAkB,OAAO,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC;EAE9E,IAAI,OAAO,UAAU,OAAO,kBAAkB,IAAI,uBAAuB;EAEzE,OAAO,OAAO;CAChB,CACF;CAEA,MAAM,MAAuC,OAAO,GAAG,yBAAyB,CAAC,CAC/E,WAAW,KAAK;EACd,MAAM,aAAa,OAAO,YAAY,gBAAgB,aAAa,GAAG;EAEtE,OAAO,OAAO,QAAQ,YAAY,cAAc;CAClD,CACF;CAEA,MAAM,OAAyC,OAAO,GAAG,0BAA0B,CAAC,CAAC,WACnF,SACsD;EACtD,MAAM,YAAY;EAClB,MAAM,iBAAiB,OAAO,YAAY,WAAW,qBAAqB,OAAO;EAEjF,MAAM,OACJ,eAAe,UAAU,KAAA,IACrB,OAAO,GAA4B;;;gCAGb,eAAe,MAAM,SAAS;+BAC/B,eAAe,MAAM,QAAQ;;oBAExC,eAAe,QAAQ,EAAE;YACjC,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC,IACpD,OAAO,GAA4B;;;gCAGb,eAAe,MAAM,SAAS;+BAC/B,eAAe,MAAM,QAAQ;kCAC1B,eAAe,MAAM;;oBAEnC,eAAe,QAAQ,EAAE;YACjC,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;EAE1D,MAAM,UAAU,OAAO,WAAW,OAAO,MAAM,WAAW,GAAG,MAAM,SAAS;EAC5E,MAAM,UAAU,OAAO,OAAO,QAAQ,SAAS,YAAY;EAC3D,MAAM,UAAU,QAAQ,SAAS,eAAe;EAChD,MAAM,QAAQ,UAAU,QAAQ,MAAM,GAAG,eAAe,KAAK,IAAI;EAEjE,OAAO;GAAE;GAAO,MAAM,UAAW,MAAM,GAAG,EAAE,CAAC,EAAE,cAAc,OAAQ;EAAK;CAC5E,CAAC;CAED,MAAM,SAA6C,OAAO,GAAG,4BAA4B,CAAC,CACxF,WAAW,KAAK,QAAQ,aAAa,wBAAwB,sBAAsB;EACjF,MAAM,YAAY;EAClB,MAAM,aAAa,OAAO,YAAY,WAAW,aAAa,GAAG;EACjE,MAAM,gBAAgB,OAAO,YAAY,WAAW,gBAAgB,MAAM;EAE1E,MAAM,SAAS,OAAO,IACnB,gBACC,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,QAAQ,YAAY,SAAS;GAEpD,IAAI,YAAY,MAAM,OAAO,OAAO,iBAAiB,KAAK,EAAE,KAAK,WAAW,CAAC;GAC7E,MAAM,aAAa,oBAAoB,SAAS,aAAa;GAE7D,IAAI,OAAO,UAAU,UAAU,GAAG,OAAO,OAAO,WAAW;GAC3D,MAAM,OAAO,WAAW;GAExB,IAAI,CAAC,qBAAqB,OAAO,KAAK,qBAAqB,IAAI,GAAG;IAChE,MAAM,YAAY,OAAO,GAA4B;;kCAEjC,IAAI,MAAM,SAAS,kBAAkB,IAAI,MAAM,QAAQ;;;cAG3E,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;IAElD,MAAM,SAAS,OAAO,WACpB,OAAO,MAAM,gBAAgB,GAC7B,WACA,SACF;IAEA,IAAI,OAAO,WAAW,GAAG,OAAO,OAAO,QAAQ,SAAS;IACxD,IAAI,OAAO,EAAE,CAAC,kBAAkB,YAC9B,OAAO,OAAO,sBAAsB,KAAK,EAAE,OAAO,WAAW,CAAC;GAClE;GACA,IAAI,SAAS,SAAS,OAAO;IAAE,QAAQ;IAAS,SAAS;GAAM;GAC/D,MAAM,aAAa,OAAO,aAAa,IAAI;GAE3C,OAAO,kBAAkB,IAAI,YAAY,cAAc,KAAK,YAAY,EAAE,QAAQ;GAClF,OAAO,GAAG;;uCAEiB,iBAAiB,IAAI,EAAE,kBAAkB,WAAW;gCAC3D,WAAW,MAAM,SAAS;+BAC3B,WAAW,MAAM,QAAQ;kCACtB,WAAW,WAAW;YAC5C,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;GAElD,OAAO;IAAE,QAAQ;IAAM,SAAS;GAAK;EACvC,CAAC,CACH,CAAC,CACA,KAAK,OAAO,SAAS,kBAAkB,OAAO,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC;EAE9E,IAAI,OAAO,SACT,OAAO,kBAAkB,IAAI,YAAY,cAAc,KAAK,YAAY,EAAE,OAAO;EAGnF,OAAO,OAAO;CAChB,CACF;CAEA,MAAM,MAAuC,OAAO,GAAG,yBAAyB,CAAC,CAAC,WAChF,WACA,OACA,OACA,OACA;EACA,MAAM,YAAY;EAElB,MAAM,eACJ,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO,YAAY,WAAW,eAAe,KAAK;EAEtF,MAAM,SACJ,UAAU,KAAA,IACN,KAAA,IACA,OAAO,OAAO,aAAa,iBAAiB,CAAC,CAAC,KAAK,CAAC,CAAC,KACnD,OAAO,eAAe,QAAQ,SAAS,CAAC,CAC1C;EAEN,MAAM,eACJ,WAAW,KAAA,IACP,GAAG,UACH,GAAG;;SAEJ,OAAO,iBAAiB,IAAI,OAAO,MAAM,SAAS,IAAI,OAAO,MAAM,QAAQ,IAAI,OAAO,WAAW;EAEtG,MAAM,OACJ,iBAAiB,KAAA,IACb,OAAO,GAA4B;;;0CAGH,UAAU,OAAO,aAAa;;oBAEpD,MAAM;YACd,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC,IACpD,OAAO,GAA4B;;;gCAGb,aAAa,SAAS;+BACvB,aAAa,QAAQ;0CACV,UAAU,OAAO,aAAa;;oBAEpD,MAAM;YACd,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;EAI1D,QAAO,OAFgB,WAAW,OAAO,MAAM,cAAc,GAAG,MAAM,SAAS,EAAA,CAEhE,KAAK,SAAS;GAC3B,OAAO;IAAE,UAAU,IAAI;IAAW,SAAS,IAAI;GAAS;GACxD,YAAY,IAAI;GAChB,kBAAkB,IAAI;EACxB,EAAE;CACJ,CAAC;CAED,MAAM,eAAyD,OAAO,GACpE,kCACF,CAAC,CAAC,WAAW,OAAuB;EAClC,MAAM,YAAY;EAElB,MAAM,eACJ,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO,YAAY,WAAW,eAAe,KAAK;EAEtF,MAAM,OACJ,iBAAiB,KAAA,IACb,OAAO,GAA4B;;;;UAInC,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC,IAClD,OAAO,GAA4B;;;8BAGf,aAAa,SAAS;6BACvB,aAAa,QAAQ;;UAExC,KAAK,OAAO,eAAe,YAAY,SAAS,CAAC,CAAC;EAExD,MAAM,UAAU,OAAO,WAAW,OAAO,MAAM,mBAAmB,GAAG,MAAM,SAAS;EAEpF,IAAI,QAAQ,WAAW,GAAG,OAAO,OAAO,QAAQ,SAAS;EAEzD,OAAO,QAAQ,EAAE,CAAC;CACpB,CAAC;CAED,OAAO,cAAc,GAAG;EAAE;EAAQ;EAAK;EAAM;EAAQ;EAAK;CAAa,CAAC;AAC1E,CAAC;;AAGD,MAAa,qBAIT,MAAM,OAAO,aAAa,CAAC,CAAC,iBAAiB"}
@@ -2,7 +2,7 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { SqliteStorageConfig } from "./SqliteStorageConfig.mjs";
3
3
  import { SqliteLedgerError, SqliteStorageCorruptionError, SqliteStorageError, SqliteWriteContention } from "./SqliteStorageError.mjs";
4
4
  import { SqliteStorageFailpoint } from "./SqliteStorageFailpoint.mjs";
5
- import { a as initializeSqliteJournal, i as decodeRows } from "./sqlite-journal-D9xFxCw-.mjs";
5
+ import { a as initializeSqliteJournal, i as decodeRows } from "./sqlite-journal-B1dejOUb.mjs";
6
6
  import { storageConfigLayer, storageFailpointLayer } from "./SqliteThreadStore.mjs";
7
7
  import { Clock, Context, Crypto, DateTime, Effect, Layer, Option, Schema, Stream } from "effect";
8
8
  import * as SqlClientService from "effect/unstable/sql/SqlClient";
@@ -10,7 +10,7 @@ import { EMPTY_TAIL_DIGEST } from "@effect-agent/thread/Digest";
10
10
  import { ApprovalDecision, CanonicalSequence, DefinitionDigests, Digest, PersistedJson, ProducerEpoch, RecordEnvelope, SettlementOutcome, WorkerAdmission } from "@effect-agent/thread/Records";
11
11
  import { NodeCrypto } from "@effect/platform-node";
12
12
  import { SqliteClient } from "@effect/sql-sqlite-node";
13
- import { MessageAdmission } from "@effect-agent/core/Messaging";
13
+ import { InputMessage } from "@effect-agent/core/Messaging";
14
14
  import { AbortCommand, AbortIntent, AbortIntentRequest, AdmissionAdmitted, AdmissionConflict, AdmissionFence, AdmissionGroup, AdmissionNotAdmitted, AdmissionPolicyError, AdmissionRequest, AdmissionResult, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, AttachChildToReservationRequest, BeginChildBudgetReleaseRequest, ChildAttachmentSnapshot, ChildBudgetReservationRequest, ChildBudgetReservationSnapshot, ChildReservationConflict, ChildReservationStatus, ChildSettledNotification, Claim, ClaimJoiningRequest, ClaimRequest, InputAppliedMarker, JoinSnapshot, JoinedToHost, JoiningClaim, LedgerCapabilities, LedgerError, MarkInputAppliedRequest, MarkJoinedRequest, MarkReadyRequest, MarkUnknownRequest, OwnershipLost, OwnershipRenewal, OwnershipSnapshot, ParentLinkage, QueueSequence, RecoverySnapshot, RecoverySnapshotRequest, ReleaseChildBudgetRequest, ReleaseOwnershipRequest, RenewOwnershipRequest, ReservedChildBudget, ReservedSettlement, RevertJoiningRequest, Settlement, SettlementConflict, SettlementFinalization, SettlementReservation, SettlementReservationSnapshot, SubmissionAdmissionFence, SubmissionLedger, SubmissionLookup, SubmissionLookupByKey, SubmissionSnapshot, SubmissionState, SuspendRequest, SuspensionReason, SuspensionSnapshot, UnknownResolution, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, settlementFailureFromRecord, submissionAbortRecordId } from "@effect-agent/thread/SubmissionLedger";
15
15
  //#region src/SqliteSubmissionLedger.ts
16
16
  var SqliteSubmissionLedger_exports = /* @__PURE__ */ __exportAll({
@@ -291,7 +291,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
291
291
  const ownership = yield* readOwnership(operation, submission.submission_id);
292
292
  if (Option.isNone(ownership) || ownership.value.ownership_token !== ownershipToken) {
293
293
  const actualEpoch = yield* threadEpoch(operation, submission.thread_id);
294
- const submissionId = yield* Schema.decodeUnknownEffect(SubmissionSnapshot.fields.submissionId)(submission.submission_id).pipe(Effect.mapError(internalFailure(operation)));
294
+ const submissionId = yield* Schema.decodeEffect(SubmissionSnapshot.fields.submissionId)(submission.submission_id).pipe(Effect.mapError(internalFailure(operation)));
295
295
  return yield* OwnershipLost.make({
296
296
  submissionId,
297
297
  actualEpoch
@@ -486,14 +486,14 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
486
486
  const capabilities = Effect.succeed(LedgerCapabilities.make({ durability: "durable-node" }));
487
487
  const admit = Effect.fn("SqliteSubmissionLedger.admit")(function* (request) {
488
488
  const operation = "ledger admit";
489
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(AdmissionRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
489
+ const validated = yield* Schema.decodeEffect(Schema.toType(AdmissionRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
490
490
  const inputJson = yield* encodePersistedJsonText(validated.inputPayload).pipe(Effect.mapError(internalFailure(operation)));
491
491
  const workerAdmissionJson = validated.workerAdmission === void 0 ? null : yield* Schema.encodeEffect(Schema.fromJsonString(WorkerAdmission))(validated.workerAdmission).pipe(Effect.mapError(internalFailure(operation)));
492
492
  if (workerAdmissionJson !== null && new TextEncoder().encode(workerAdmissionJson).byteLength > 16777216) return yield* LedgerError.make({
493
493
  operation,
494
494
  message: "Worker admission metadata exceeds the stored value bound"
495
495
  });
496
- const messageAdmissionJson = validated.messageAdmission === void 0 ? null : yield* Schema.encodeEffect(Schema.fromJsonString(MessageAdmission))(validated.messageAdmission).pipe(Effect.mapError(internalFailure(operation)));
496
+ const messageAdmissionJson = validated.messageAdmission === void 0 ? null : yield* Schema.encodeEffect(Schema.fromJsonString(InputMessage))(validated.messageAdmission).pipe(Effect.mapError(internalFailure(operation)));
497
497
  if (messageAdmissionJson !== null && new TextEncoder().encode(messageAdmissionJson).byteLength > 16777216) return yield* LedgerError.make({
498
498
  operation,
499
499
  message: "Message admission metadata exceeds the stored value bound"
@@ -523,9 +523,9 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
523
523
  attemptedInputDigest: validated.inputDigest
524
524
  });
525
525
  const retainedWorkerAdmission = existing[0].worker_admission_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(WorkerAdmission))(existing[0].worker_admission_json).pipe(Effect.mapError(internalFailure(operation)));
526
- const retainedMessageAdmission = existing[0].message_admission_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(MessageAdmission))(existing[0].message_admission_json).pipe(Effect.mapError(internalFailure(operation)));
526
+ const retainedInputMessage = existing[0].message_admission_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(InputMessage))(existing[0].message_admission_json).pipe(Effect.mapError(internalFailure(operation)));
527
527
  const retainedFence = existing[0].admission_fence_json === null ? void 0 : yield* Schema.decodeEffect(Schema.fromJsonString(AdmissionFence))(existing[0].admission_fence_json).pipe(Effect.mapError(internalFailure(operation)));
528
- if ((existing[0].admission_group ?? void 0) !== validated.admissionGroup || !Schema.toEquivalence(Schema.optional(WorkerAdmission))(retainedWorkerAdmission, validated.workerAdmission) || !Schema.toEquivalence(Schema.optional(MessageAdmission))(retainedMessageAdmission, validated.messageAdmission) || !Schema.toEquivalence(Schema.optional(AdmissionFence))(retainedFence, validated.admissionFence)) return yield* AdmissionConflict.make({
528
+ if ((existing[0].admission_group ?? void 0) !== validated.admissionGroup || !Schema.toEquivalence(Schema.optional(WorkerAdmission))(retainedWorkerAdmission, validated.workerAdmission) || !Schema.toEquivalence(Schema.optional(InputMessage))(retainedInputMessage, validated.messageAdmission) || !Schema.toEquivalence(Schema.optional(AdmissionFence))(retainedFence, validated.admissionFence)) return yield* AdmissionConflict.make({
529
529
  threadId: validated.threadId,
530
530
  principal: validated.principal,
531
531
  idempotencyKey: validated.idempotencyKey,
@@ -626,7 +626,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
626
626
  });
627
627
  const markReady = Effect.fn("SqliteSubmissionLedger.markReady")(function* (request) {
628
628
  const operation = "ledger mark ready";
629
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(MarkReadyRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
629
+ const validated = yield* Schema.decodeEffect(Schema.toType(MarkReadyRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
630
630
  yield* hitFailpoint("ledger:mark-ready:before", operation);
631
631
  yield* inWriteTransaction(operation, Effect.gen(function* () {
632
632
  if ((yield* requireSubmission(operation, validated.submissionId)).state !== "admitted") return;
@@ -641,7 +641,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
641
641
  });
642
642
  const lookup = Effect.fn("SqliteSubmissionLedger.lookup")(function* (request) {
643
643
  const operation = "ledger lookup";
644
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SubmissionLookup))(request).pipe(Effect.mapError(internalFailure(operation)));
644
+ const validated = yield* Schema.decodeEffect(Schema.toType(SubmissionLookup))(request).pipe(Effect.mapError(internalFailure(operation)));
645
645
  if (validated._tag === "SubmissionLookupById") {
646
646
  const row = yield* readSubmission(operation, validated.submissionId);
647
647
  if (Option.isNone(row)) return Option.none();
@@ -661,7 +661,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
661
661
  });
662
662
  const resolveAdmission = Effect.fn("SqliteSubmissionLedger.resolveAdmission")(function* (request) {
663
663
  const operation = "ledger resolve admission";
664
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SubmissionLookupByKey))(request).pipe(Effect.mapError(internalFailure(operation)));
664
+ const validated = yield* Schema.decodeEffect(Schema.toType(SubmissionLookupByKey))(request).pipe(Effect.mapError(internalFailure(operation)));
665
665
  const rows = yield* sql`
666
666
  SELECT ${sql.literal(SUBMISSION_COLUMNS)}
667
667
  FROM effect_agent_submissions
@@ -676,7 +676,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
676
676
  });
677
677
  const claim = Effect.fn("SqliteSubmissionLedger.claim")(function* (request) {
678
678
  const operation = "ledger claim";
679
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ClaimRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
679
+ const validated = yield* Schema.decodeEffect(Schema.toType(ClaimRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
680
680
  const attemptId = yield* mintIdentifier("attempt", operation);
681
681
  const ownershipToken = yield* mintIdentifier("owner", operation);
682
682
  yield* hitFailpoint("ledger:claim:before", operation);
@@ -786,7 +786,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
786
786
  });
787
787
  const renewOwnership = Effect.fn("SqliteSubmissionLedger.renewOwnership")(function* (request) {
788
788
  const operation = "ledger renew ownership";
789
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(RenewOwnershipRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
789
+ const validated = yield* Schema.decodeEffect(Schema.toType(RenewOwnershipRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
790
790
  yield* hitFailpoint("ledger:renew:before", operation);
791
791
  const renewal = yield* inWriteTransaction(operation, Effect.gen(function* () {
792
792
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -808,7 +808,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
808
808
  });
809
809
  const releaseOwnership = Effect.fn("SqliteSubmissionLedger.releaseOwnership")(function* (request) {
810
810
  const operation = "ledger release ownership";
811
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ReleaseOwnershipRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
811
+ const validated = yield* Schema.decodeEffect(Schema.toType(ReleaseOwnershipRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
812
812
  yield* hitFailpoint("ledger:release:before", operation);
813
813
  yield* inWriteTransaction(operation, Effect.gen(function* () {
814
814
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -827,7 +827,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
827
827
  });
828
828
  const markInputApplied = Effect.fn("SqliteSubmissionLedger.markInputApplied")(function* (request) {
829
829
  const operation = "ledger mark input applied";
830
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(MarkInputAppliedRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
830
+ const validated = yield* Schema.decodeEffect(Schema.toType(MarkInputAppliedRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
831
831
  yield* hitFailpoint("ledger:mark-input-applied:before", operation);
832
832
  yield* inWriteTransaction(operation, Effect.gen(function* () {
833
833
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -852,7 +852,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
852
852
  });
853
853
  const reserveSettlement = Effect.fn("SqliteSubmissionLedger.reserveSettlement")(function* (request) {
854
854
  const operation = "ledger reserve settlement";
855
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SettlementReservation))(request).pipe(Effect.mapError(internalFailure(operation)));
855
+ const validated = yield* Schema.decodeEffect(Schema.toType(SettlementReservation))(request).pipe(Effect.mapError(internalFailure(operation)));
856
856
  const recordJson = yield* encodeRecordEnvelopeText(validated.record).pipe(Effect.mapError(internalFailure(operation)));
857
857
  yield* hitFailpoint("ledger:reserve-settlement:before", operation);
858
858
  const reserved = yield* inWriteTransaction(operation, Effect.gen(function* () {
@@ -960,7 +960,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
960
960
  });
961
961
  const finalizeSettlement = Effect.fn("SqliteSubmissionLedger.finalizeSettlement")(function* (request) {
962
962
  const operation = "ledger finalize settlement";
963
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SettlementFinalization))(request).pipe(Effect.mapError(internalFailure(operation)));
963
+ const validated = yield* Schema.decodeEffect(Schema.toType(SettlementFinalization))(request).pipe(Effect.mapError(internalFailure(operation)));
964
964
  yield* hitFailpoint("ledger:finalize-settlement:before", operation);
965
965
  const replayRows = yield* sql`
966
966
  SELECT submission.*, reservation.settlement_id, reservation.outcome,
@@ -1015,7 +1015,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1015
1015
  });
1016
1016
  const requestAbort = Effect.fn("SqliteSubmissionLedger.requestAbort")(function* (request) {
1017
1017
  const operation = "ledger request abort";
1018
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(AbortCommand))(request).pipe(Effect.mapError(internalFailure(operation)));
1018
+ const validated = yield* Schema.decodeEffect(Schema.toType(AbortCommand))(request).pipe(Effect.mapError(internalFailure(operation)));
1019
1019
  yield* hitFailpoint("ledger:request-abort:before", operation);
1020
1020
  const intent = yield* inWriteTransaction(operation, Effect.gen(function* () {
1021
1021
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -1064,7 +1064,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1064
1064
  });
1065
1065
  const claimJoining = Effect.fn("SqliteSubmissionLedger.claimJoining")(function* (request) {
1066
1066
  const operation = "ledger claim joining";
1067
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ClaimJoiningRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1067
+ const validated = yield* Schema.decodeEffect(Schema.toType(ClaimJoiningRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1068
1068
  yield* hitFailpoint("ledger:claim-joining:before", operation);
1069
1069
  const claims = yield* inWriteTransaction(operation, Effect.gen(function* () {
1070
1070
  const host = yield* requireSubmission(operation, validated.hostSubmissionId);
@@ -1106,7 +1106,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1106
1106
  });
1107
1107
  const markJoined = Effect.fn("SqliteSubmissionLedger.markJoined")(function* (request) {
1108
1108
  const operation = "ledger mark joined";
1109
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(MarkJoinedRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1109
+ const validated = yield* Schema.decodeEffect(Schema.toType(MarkJoinedRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1110
1110
  yield* hitFailpoint("ledger:mark-joined:before", operation);
1111
1111
  yield* inWriteTransaction(operation, Effect.gen(function* () {
1112
1112
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -1137,7 +1137,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1137
1137
  });
1138
1138
  const revertJoining = Effect.fn("SqliteSubmissionLedger.revertJoining")(function* (request) {
1139
1139
  const operation = "ledger revert joining";
1140
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(RevertJoiningRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1140
+ const validated = yield* Schema.decodeEffect(Schema.toType(RevertJoiningRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1141
1141
  yield* hitFailpoint("ledger:revert-joining:before", operation);
1142
1142
  yield* inWriteTransaction(operation, Effect.gen(function* () {
1143
1143
  if ((yield* requireSubmission(operation, validated.submissionId)).state !== "joining") return;
@@ -1151,7 +1151,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1151
1151
  });
1152
1152
  const suspend = Effect.fn("SqliteSubmissionLedger.suspend")(function* (request) {
1153
1153
  const operation = "ledger suspend";
1154
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(SuspendRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1154
+ const validated = yield* Schema.decodeEffect(Schema.toType(SuspendRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1155
1155
  const reasonJson = yield* encodeSuspensionReasonText(validated.reason).pipe(Effect.mapError(internalFailure(operation)));
1156
1156
  yield* hitFailpoint("ledger:suspend:before", operation);
1157
1157
  const outcome = yield* inWriteTransaction(operation, Effect.gen(function* () {
@@ -1226,7 +1226,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1226
1226
  });
1227
1227
  const recordApprovalDecision = Effect.fn("SqliteSubmissionLedger.recordApprovalDecision")(function* (command) {
1228
1228
  const operation = "ledger record approval decision";
1229
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ApprovalDecisionCommand))(command).pipe(Effect.mapError(internalFailure(operation)));
1229
+ const validated = yield* Schema.decodeEffect(Schema.toType(ApprovalDecisionCommand))(command).pipe(Effect.mapError(internalFailure(operation)));
1230
1230
  yield* hitFailpoint("ledger:approval-decision:before", operation);
1231
1231
  const intent = yield* inWriteTransaction(operation, Effect.gen(function* () {
1232
1232
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -1279,7 +1279,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1279
1279
  });
1280
1280
  const markUnknown = Effect.fn("SqliteSubmissionLedger.markUnknown")(function* (request) {
1281
1281
  const operation = "ledger mark unknown";
1282
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(MarkUnknownRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1282
+ const validated = yield* Schema.decodeEffect(Schema.toType(MarkUnknownRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1283
1283
  yield* hitFailpoint("ledger:mark-unknown:before", operation);
1284
1284
  yield* inWriteTransaction(operation, Effect.gen(function* () {
1285
1285
  const submission = yield* requireSubmission(operation, validated.submissionId);
@@ -1312,7 +1312,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1312
1312
  });
1313
1313
  const recordUnknownResolution = Effect.fn("SqliteSubmissionLedger.recordUnknownResolution")(function* (command) {
1314
1314
  const operation = "ledger record unknown resolution";
1315
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(UnknownResolutionCommand))(command).pipe(Effect.mapError(internalFailure(operation)));
1315
+ const validated = yield* Schema.decodeEffect(Schema.toType(UnknownResolutionCommand))(command).pipe(Effect.mapError(internalFailure(operation)));
1316
1316
  const resolutionJson = yield* encodeUnknownResolutionText(validated.resolution).pipe(Effect.mapError(internalFailure(operation)));
1317
1317
  yield* hitFailpoint("ledger:unknown-resolution:before", operation);
1318
1318
  const intent = yield* inWriteTransaction(operation, Effect.gen(function* () {
@@ -1381,7 +1381,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1381
1381
  });
1382
1382
  const recordChildSettled = Effect.fn("SqliteSubmissionLedger.recordChildSettled")(function* (request) {
1383
1383
  const operation = "ledger record child settled";
1384
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ChildSettledNotification))(request).pipe(Effect.mapError(internalFailure(operation)));
1384
+ const validated = yield* Schema.decodeEffect(Schema.toType(ChildSettledNotification))(request).pipe(Effect.mapError(internalFailure(operation)));
1385
1385
  yield* hitFailpoint("ledger:child-settled:before", operation);
1386
1386
  const outcome = yield* inWriteTransaction(operation, Effect.gen(function* () {
1387
1387
  const parent = yield* requireSubmission(operation, validated.parentSubmissionId);
@@ -1415,7 +1415,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1415
1415
  });
1416
1416
  const reserveChildBudget = Effect.fn("SqliteSubmissionLedger.reserveChildBudget")(function* (request) {
1417
1417
  const operation = "ledger reserve child budget";
1418
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ChildBudgetReservationRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1418
+ const validated = yield* Schema.decodeEffect(Schema.toType(ChildBudgetReservationRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1419
1419
  const allocationJson = yield* encodePersistedJsonText(validated.allocation).pipe(Effect.mapError(internalFailure(operation)));
1420
1420
  yield* hitFailpoint("ledger:child-reservation:before", operation);
1421
1421
  const reserved = yield* inWriteTransaction(operation, Effect.gen(function* () {
@@ -1472,7 +1472,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1472
1472
  });
1473
1473
  const attachChildToReservation = Effect.fn("SqliteSubmissionLedger.attachChildToReservation")(function* (request) {
1474
1474
  const operation = "ledger attach child to reservation";
1475
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(AttachChildToReservationRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1475
+ const validated = yield* Schema.decodeEffect(Schema.toType(AttachChildToReservationRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1476
1476
  yield* hitFailpoint("ledger:child-attach:before", operation);
1477
1477
  const attached = yield* inWriteTransaction(operation, Effect.gen(function* () {
1478
1478
  const existing = yield* readChildReservation(operation, validated.reservationId);
@@ -1514,7 +1514,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1514
1514
  });
1515
1515
  const beginChildBudgetRelease = Effect.fn("SqliteSubmissionLedger.beginChildBudgetRelease")(function* (request) {
1516
1516
  const operation = "ledger begin child budget release";
1517
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(BeginChildBudgetReleaseRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1517
+ const validated = yield* Schema.decodeEffect(Schema.toType(BeginChildBudgetReleaseRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1518
1518
  const accountingJson = yield* encodePersistedJsonText(validated.accounting).pipe(Effect.mapError(internalFailure(operation)));
1519
1519
  yield* hitFailpoint("ledger:child-release-pending:before", operation);
1520
1520
  const frozen = yield* inWriteTransaction(operation, Effect.gen(function* () {
@@ -1550,7 +1550,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1550
1550
  });
1551
1551
  const releaseChildBudget = Effect.fn("SqliteSubmissionLedger.releaseChildBudget")(function* (request) {
1552
1552
  const operation = "ledger release child budget";
1553
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(ReleaseChildBudgetRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1553
+ const validated = yield* Schema.decodeEffect(Schema.toType(ReleaseChildBudgetRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1554
1554
  yield* hitFailpoint("ledger:child-release:before", operation);
1555
1555
  const released = yield* inWriteTransaction(operation, Effect.gen(function* () {
1556
1556
  const existing = yield* readChildReservation(operation, validated.reservationId);
@@ -1604,7 +1604,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1604
1604
  const scanNonterminal = Stream.paginate(void 0, scanPage);
1605
1605
  const readAbortIntentForSubmission = Effect.fn("SqliteSubmissionLedger.readAbortIntentForSubmission")(function* (request) {
1606
1606
  const operation = "ledger read abort intent";
1607
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(AbortIntentRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1607
+ const validated = yield* Schema.decodeEffect(Schema.toType(AbortIntentRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1608
1608
  const recordId = submissionAbortRecordId(validated.submissionId);
1609
1609
  const rows = yield* sql`
1610
1610
  SELECT
@@ -1640,7 +1640,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1640
1640
  });
1641
1641
  const loadRecoverySnapshot = Effect.fn("SqliteSubmissionLedger.loadRecoverySnapshot")(function* (request) {
1642
1642
  const operation = "ledger load recovery snapshot";
1643
- const validated = yield* Schema.decodeUnknownEffect(Schema.toType(RecoverySnapshotRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1643
+ const validated = yield* Schema.decodeEffect(Schema.toType(RecoverySnapshotRequest))(request).pipe(Effect.mapError(internalFailure(operation)));
1644
1644
  return yield* journal.withReadTransaction(operation)(Effect.gen(function* () {
1645
1645
  const submissionRow = yield* requireSubmission(operation, validated.submissionId);
1646
1646
  const submission = yield* decodeSubmissionSnapshot(operation, submissionRow);
@@ -1661,7 +1661,7 @@ const makeServices = Effect.fn("SqliteSubmissionLedger.makeServices")(function*
1661
1661
  const reservationRow = yield* readReservation(operation, validated.submissionId);
1662
1662
  if (Option.isSome(reservationRow)) {
1663
1663
  const record = yield* decodeRecordEnvelopeText(reservationRow.value.record_json).pipe(Effect.mapError((error) => corruptionFailure(operation, "effect_agent_settlement_reservations", validated.submissionId, error.message)));
1664
- const settlementId = yield* Schema.decodeUnknownEffect(SettlementReservationSnapshot.fields.settlementId)(reservationRow.value.settlement_id).pipe(Effect.mapError(internalFailure(operation)));
1664
+ const settlementId = yield* Schema.decodeEffect(SettlementReservationSnapshot.fields.settlementId)(reservationRow.value.settlement_id).pipe(Effect.mapError(internalFailure(operation)));
1665
1665
  reservation = SettlementReservationSnapshot.make({
1666
1666
  settlementId,
1667
1667
  outcome: reservationRow.value.outcome,