@yielded/agent-storage-cloudflare 0.1.0-beta.177 → 0.1.0-beta.179

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"do-journal-BH10YJoi.mjs","names":["isSqlError","SqlClient"],"sources":["../src/internal/storage-span.ts","../src/internal/do-journal.ts"],"sourcesContent":["import { Effect, Predicate, References, Result, Tracer } from \"effect\";\n\ntype Tagged = { readonly _tag: string; readonly reason?: unknown };\n\nexport const isAppendContention = (error: Tagged): boolean =>\n (error._tag === \"DoAppendConflict\" || error._tag === \"AppendConflict\") && error.reason === \"tail\";\n\n/** Expected refusals remain typed at the port, but are outcomes of the storage operation. */\nexport const storageResult = <A, E extends Tagged, R>(\n effect: Effect.Effect<A, E, R>,\n expected: (error: E) => boolean,\n) =>\n effect.pipe(\n Effect.map(Result.succeed),\n Effect.catchIf(expected, (error) => Effect.succeed(Result.fail(error))),\n );\n\n/** Only error discriminants enter telemetry; messages, SQL, identities and payloads do not. */\nexport const annotateStorageError = (error: Tagged) =>\n Effect.annotateCurrentSpan({\n \"error.type\": error._tag,\n ...(Predicate.hasProperty(error, \"cause\") &&\n Predicate.hasProperty(error.cause, \"_tag\") &&\n typeof error.cause._tag === \"string\"\n ? { \"error.cause.type\": error.cause._tag }\n : {}),\n });\n\nexport const withStorageSpan = (\n name: string,\n expected: (error: Tagged) => boolean = () => false,\n) => {\n const span = Effect.withSpan(name);\n\n return <A, E extends Tagged, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.withFiber((fiber) =>\n !fiber.getRef(References.TracerEnabled) || fiber.getRef(Tracer.Tracer) === Tracer.nativeTracer\n ? effect\n : storageResult(effect, expected).pipe(\n Effect.tap((result) =>\n Result.isFailure(result)\n ? Effect.annotateCurrentSpan({ \"storage.outcome\": result.failure._tag })\n : Effect.void,\n ),\n Effect.tapError(annotateStorageError),\n span,\n Effect.flatMap(Effect.fromResult),\n ),\n );\n};\n","import { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport {\n makeCanonicalStorage,\n recordBatchId,\n} from \"@yielded/agent-storage-sql/sql-canonical-storage\";\nimport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\nimport { makeSqlExecutions } from \"@yielded/agent-storage-sql/sql-journal\";\nimport {\n makeSqlLifecyclePublication,\n type SqlLifecycleRetainMany,\n SqlLifecycleSource,\n SqlLifecycleRetainer,\n} from \"@yielded/agent-storage-sql/sql-lifecycle-publication\";\nimport { SqlStorageProgress } from \"@yielded/agent-storage-sql/sql-storage-progress\";\nimport {\n canonicalRecordJson,\n makeSqlThreadArchiveRange,\n} from \"@yielded/agent-storage-sql/sql-thread-archive-range\";\nimport { makeSqlThreadWork } from \"@yielded/agent-storage-sql/sql-thread-work\";\nimport { ThreadId } from \"@yielded/agent/identifiers\";\nimport {\n LifecyclePublicationFact,\n LifecyclePublicationError,\n} from \"@yielded/agent/lifecycle-publication\";\nimport { BatchId, CanonicalRecord, CanonicalSequence } from \"@yielded/agent/records\";\nimport { SqlStorageOwner } from \"@yielded/agent/sql-memory-store\";\nimport {\n type AppendConflict,\n AppendResult,\n ThreadStoreDiagnostic,\n ThreadStoreError,\n} from \"@yielded/agent/thread-store\";\nimport {\n Cause,\n Clock,\n Context,\n Effect,\n Layer,\n Option,\n Predicate,\n References,\n Result,\n Schema,\n Stream,\n Tracer,\n} from \"effect\";\nimport * as SqlClient from \"effect/sql/SqlClient\";\nimport { classifySqliteError, SqlError } from \"effect/sql/SqlError\";\nimport { CurrentTransformer, type Statement } from \"effect/sql/Statement\";\n\nimport { DoStorageConfig } from \"../DoStorageConfig.ts\";\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { DoStorageFailpoint, isDefaultDoStorageFailpoint } from \"../DoStorageFailpoint.ts\";\nimport { ensureDoStorageLayout } from \"./migrations.ts\";\nimport { ownedState, ownedRows, type OwnedState } from \"./owned-state.ts\";\nimport {\n isAppendContention,\n annotateStorageError,\n storageResult,\n withStorageSpan,\n} from \"./storage-span.ts\";\n\n/**\n * Static schema ceiling for stored text columns. Writes are bounded in BYTES by the\n * configured `maxStoredValueBytes` (always ≤ 2,000,000); UTF-8 byte length is never smaller\n * than UTF-16 string length, so any value that passed the byte bound also passes this\n * decode-side character ceiling.\n */\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(2_000_000));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst MAX_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n// A shared isolate budget permits multi-page hydration without multiplying its\n// retained payload by the number of resident Durable Object instances.\nconst MAX_RECORD_CACHE_JSON_BYTES = 8 * 1024 * 1024;\nconst MAX_RECORD_CACHE_ENTRIES = 4_096;\n/** Durable Object SQL storage allows at most 100 bound parameters per statement. */\nconst MAX_BOUND_PARAMETERS = 100;\nconst isSqlError = Schema.is(SqlError);\n\nconst isNativeClient = Schema.is(\n Schema.declare<SqliteClient.SqliteClient>((value): value is SqliteClient.SqliteClient =>\n Predicate.hasProperty(value, SqliteClient.TypeId),\n ),\n);\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nconst chunked = <A>(values: ReadonlyArray<A>, size: number): Array<ReadonlyArray<A>> => {\n const chunks: Array<ReadonlyArray<A>> = [];\n\n for (let index = 0; index < values.length; index += size) {\n chunks.push(values.slice(index, index + size));\n }\n\n return chunks;\n};\n\nclass ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(128))),\n tail_sequence: CanonicalSequence,\n}) {}\n\nconst threadRows = ownedRows(\n ThreadRow,\n \"effect_agent_threads\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: Schema.fromJsonString(BatchId.check(Schema.isMaxLength(MAX_IDENTIFIER_LENGTH))),\n thread_id: ThreadId.check(Schema.isMaxLength(MAX_IDENTIFIER_LENGTH)),\n record_id: Schema.fromJsonString(BoundedIdentifier),\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\ninterface RecordCacheEntry {\n readonly row: RecordRow;\n readonly bytes: number;\n readonly evict: () => void;\n}\n\n// Entries retain only their local row map, never a storage owner or incarnation.\nconst isolateRecords = new Map<RecordCacheEntry, true>();\nlet isolateRecordBytes = 0;\n\nconst releaseRecord = (entry: RecordCacheEntry) => {\n if (!isolateRecords.delete(entry)) return;\n isolateRecordBytes -= entry.bytes;\n entry.evict();\n};\n\nconst recordCaches = new WeakMap<OwnedState, ReturnType<typeof makeRecordCache>>();\n\nconst makeRecordCache = () => {\n const records = new Map<string, RecordCacheEntry>();\n const key = (thread: string, sequence: number) => JSON.stringify([thread, sequence]);\n\n return {\n clear: () => {\n for (const entry of records.values()) releaseRecord(entry);\n },\n get: (thread: string, sequence: number) => records.get(key(thread, sequence))?.row,\n prefix: (thread: string, through: number): ReadonlyArray<RecordRow> | undefined => {\n const prefix: Array<RecordRow> = [];\n\n for (let sequence = 1; sequence <= through; sequence++) {\n const row = records.get(key(thread, sequence));\n\n if (row === undefined) return undefined;\n prefix.push(row.row);\n }\n\n return prefix;\n },\n put: (row: RecordRow, capturedBytes?: number) => {\n const id = key(row.thread_id, row.sequence);\n const prior = records.get(id);\n\n if (prior?.row === row) return;\n const size = capturedBytes ?? storedTextBytes(row.record_json);\n\n if (prior !== undefined) releaseRecord(prior);\n\n const entry: RecordCacheEntry = {\n row,\n bytes: size,\n evict: () => records.delete(id),\n };\n\n records.set(id, entry);\n isolateRecords.set(entry, true);\n isolateRecordBytes += size;\n while (\n isolateRecordBytes > MAX_RECORD_CACHE_JSON_BYTES ||\n isolateRecords.size > MAX_RECORD_CACHE_ENTRIES\n ) {\n const oldest = isolateRecords.keys().next().value;\n\n if (oldest === undefined) break;\n releaseRecord(oldest);\n }\n },\n };\n};\n\nconst ReadPlanRow = Schema.Struct({\n sequence: CanonicalSequence,\n record_json_bytes: Schema.Natural.check(Schema.isLessThanOrEqualTo(MAX_READ_PAGE_JSON_BYTES)),\n});\n\ntype ReadPage = [typeof ReadPlanRow.Type, ...Array<typeof ReadPlanRow.Type>];\n\nclass CheckpointRow extends Schema.Class<CheckpointRow>(\"CheckpointRow\")({\n checkpoint_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n through_sequence: CanonicalSequence,\n}) {}\n\nconst LifecycleCursorRow = Schema.Struct({\n thread_id: BoundedIdentifier,\n through_sequence: CanonicalSequence,\n});\n\nconst lifecycleCursorRows = ownedRows(\n LifecycleCursorRow,\n \"effect_agent_lifecycle_cursors\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nconst initializedLifecycleSources = new WeakSet<OwnedState>();\n\nexport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\n\nexport class RawReadRequest extends Schema.Class<RawReadRequest>(\n \"@effect-agent/storage-cloudflare/RawReadRequest\",\n)({\n threadId: BoundedIdentifier,\n fromSequenceExclusive: CanonicalSequence,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1_024)),\n}) {}\n\nexport class RawCheckpoint extends Schema.Class<RawCheckpoint>(\n \"@effect-agent/storage-cloudflare/RawCheckpoint\",\n)({\n checkpointJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n throughSequence: CanonicalSequence,\n}) {}\n\ntype AppendError =\n | ThreadStoreError\n | DoAppendConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoStorageFailpointError\n | DoValueBoundExceeded;\n\ntype CheckpointError =\n | DoCheckpointConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoValueBoundExceeded;\n\ntype DoJournalFailpoint = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoJournalFailpoint = () => Effect.void;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): DoStorageError =>\n DoStorageError.make({\n cause: error,\n operation,\n message: error.message,\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.reason._tag,\n }),\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n decoder: string = table,\n): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: \"Stored rows do not satisfy the storage schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode storage rows\",\n decoder,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": decoder,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n): Effect.Effect<A, DoStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: `Expected exactly one row but found ${decoded.length}.`,\n }),\n ),\n ),\n );\n\n/** Open a validated layout and bind this Object's storage owner. */\nconst ensureCurrentStorage = Effect.fnUntraced(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n const state = yield* ownedState(sql);\n const owner = (yield* SqlStorageOwner) ?? state;\n\n yield* ensureDoStorageLayout().pipe(\n Effect.provideService(SqlStorageOwner, owner),\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n let journal: DoJournal | undefined;\n\n const lifecycle = yield* makeSqlLifecyclePublication(undefined, maxStoredValueBytes).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n Effect.provideService(SqlLifecycleSource, {\n beforeRetain: (threadId) =>\n Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushCanonical(threadId),\n ),\n beforePending: Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushPublications(),\n ),\n }),\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle publication\",\n message: \"Native publication storage unavailable\",\n cause,\n }),\n ),\n );\n\n journal = yield* makeJournal(sql, failpoint, maxStoredValueBytes, lifecycle, state).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n );\n if (lifecycle !== undefined) yield* journal.initializeLifecycleSource();\n\n return journal;\n});\n\nconst makeJournal = Effect.fnUntraced(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n lifecycle: Effect.Success<ReturnType<typeof makeSqlLifecyclePublication>>,\n state: OwnedState,\n) {\n const owner = (yield* SqlStorageOwner) ?? state;\n const progress = yield* SqlStorageProgress;\n\n const nativeDb =\n isNativeClient(sql) &&\n sql.config.transformQueryNames === undefined &&\n sql.config.transformResultNames === undefined &&\n isDefaultDoStorageFailpoint(failpoint)\n ? sql.config.storage?.sql\n : undefined;\n\n const work = yield* makeSqlThreadWork({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"rebuild Thread work\",\n message: \"Thread work transaction failed\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n yield* Effect.acquireRelease(\n Effect.sync(() => state.invalidators.add(work.invalidate)),\n () => Effect.sync(() => state.invalidators.delete(work.invalidate)),\n );\n\n const workFailure = (cause: unknown) =>\n DoStorageError.make({\n operation: \"publish Thread work\",\n message: \"Canonical work metadata could not be published\",\n cause,\n });\n\n const executions = yield* makeSqlExecutions().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n const executionConflict = <A>(effect: Effect.Effect<A, AppendConflict | ThreadStoreError>) =>\n effect.pipe(\n Effect.catchTag(\"AppendConflict\", (error) =>\n Effect.fail(\n DoAppendConflict.make({\n reason: error.reason,\n message: \"Active execution conflicts with the captured commit\",\n ...(error.actualTailSequence === undefined\n ? {}\n : { actualTailSequence: error.actualTailSequence }),\n }),\n ),\n ),\n );\n\n const threads = threadRows(state, sql);\n const cursors = lifecycleCursorRows(state, sql);\n let records = recordCaches.get(state);\n\n if (records === undefined) {\n records = makeRecordCache();\n recordCaches.set(state, records);\n state.invalidators.add(records.clear);\n }\n const recordCache = records;\n\n const archives = yield* makeSqlThreadArchiveRange({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"archive write\",\n message: \"Archive transaction failed.\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n const recordJson = canonicalRecordJson(sql);\n\n const physical = yield* makeCanonicalStorage().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n /** Typed pre-write refusal for any single value over the configured byte bound. */\n const checkValueBound = (\n operation: string,\n value: string,\n actualBytes = storedTextBytes(value),\n ): Effect.Effect<void, DoValueBoundExceeded> => {\n return actualBytes > maxStoredValueBytes\n ? Effect.fail(\n DoValueBoundExceeded.make({\n actualBytes,\n maxBytes: maxStoredValueBytes,\n operation,\n }),\n )\n : Effect.void;\n };\n\n /**\n * Runs one journal write transaction on the Durable Object storage-backed\n * `withTransaction` (`ctx.storage.transaction()` under the hood). Within one Durable\n * Object there is exactly ONE writer, so the Node `BEGIN IMMEDIATE` + busy-retry +\n * `SqliteWriteContention` machinery has no analogue here and is deliberately absent.\n * The shared local owner gate covers the transaction and acknowledgement.\n *\n * Journal write transactions are always top level: the Durable Object client rejects\n * nested transactions, so new journal operations must not wrap this helper inside another\n * transaction. Expected outcomes may be captured only when every such refusal precedes\n * mutation; real faults still roll back. Successful preflight reads never authorize a write.\n */\n const withWriteTransaction = (\n operation: string,\n expected?: (error: { readonly _tag: string }) => boolean,\n ) => {\n const transaction = <A, E extends { readonly _tag: string }>(\n effect: Effect.Effect<A, E>,\n ): Effect.Effect<A, E | DoStorageError> =>\n Effect.withFiber((fiber) => {\n const body = state.owner.withMutation(owner.transaction(effect)).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n );\n\n const traced =\n fiber.getRef(References.TracerEnabled) &&\n fiber.getRef(Tracer.Tracer) !== Tracer.nativeTracer;\n\n return traced\n ? body.pipe(\n Effect.tapError(annotateStorageError),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n )\n : body;\n });\n\n return <A, E extends { readonly _tag: string }>(effect: Effect.Effect<A, E>) =>\n expected === undefined\n ? transaction(effect)\n : transaction(storageResult(effect, expected)).pipe(Effect.flatMap(Effect.fromResult));\n };\n\n const materialize = Effect.fnUntraced(function* (\n threadId: string,\n createdAt: string,\n ): Effect.fn.Return<void, DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded> {\n if (threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity exceeds the Durable Object storage bounds.\",\n });\n }\n // Refusals and idempotent materialization need no transaction. Recheck before writes.\n const current = yield* getThread(threadId);\n\n if (current.length === 1) {\n return;\n }\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* getThread(threadId);\n\n const existing = yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n existingRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: threadId,\n message: \"A thread primary key returned more than one row.\",\n });\n }\n if (existing.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_threads (\n thread_id,\n created_at,\n tail_sequence\n ) VALUES (\n ${threadId},\n ${createdAt},\n 0\n ) ON CONFLICT(thread_id) DO UPDATE SET created_at=excluded.created_at\n WHERE effect_agent_threads.created_at IS NULL\n RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"materialize thread\")(error) : error,\n ),\n );\n\n if (lifecycle !== undefined)\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors (thread_id, through_sequence)\n VALUES (${threadId}, 0) RETURNING *`.pipe(\n cursors.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\"\n ? storageError(\"initialize lifecycle source\")(error)\n : error,\n ),\n );\n\n return;\n }\n }),\n );\n }, withStorageSpan(\"DoJournal.materialize\"));\n\n const getThread = Effect.fnUntraced(function* (threadId: string) {\n return (yield* threads\n .by(\"thread_id\", threadId)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"read thread\")(error) : error,\n ),\n )).filter((row) => row.thread_id === threadId && row.created_at !== null);\n });\n\n const hasRecord = Effect.fnUntraced(function* (threadId: string, recordId: string) {\n const thread = (yield* getThread(threadId))[0];\n const prefix = recordCache.prefix(threadId, thread?.tail_sequence ?? 0);\n\n if (prefix !== undefined) return prefix.some((row) => row.record_id === recordId);\n\n const rows = yield* sql`SELECT record_id FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND record_id = ${JSON.stringify(recordId)}`.pipe(\n Effect.mapError(storageError(\"read canonical record identity\")),\n );\n\n return rows.length > 0;\n });\n\n const prepareAppend = Effect.fnUntraced(function* (request: RawAppendRequest) {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n request.executionWrites.some(\n ({ update }) => update.checkpoint.progress.runId.length > MAX_IDENTIFIER_LENGTH,\n ) ||\n request.records.some((record) => record.recordId.length > MAX_IDENTIFIER_LENGTH)\n ) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers exceed the Durable Object storage bounds.\",\n });\n }\n // Archives store the full batch as one value, so their ceiling also bounds hot appends.\n // The trusted append SPI pairs captured JSON with its exact UTF-8 width.\n yield* checkValueBound(\"append canonical batch\", request.batchJson, request.batchBytes);\n for (const record of request.records) {\n if (record.recordBytes > maxStoredValueBytes)\n return yield* DoValueBoundExceeded.make({\n actualBytes: record.recordBytes,\n maxBytes: maxStoredValueBytes,\n operation: \"append canonical record\",\n });\n }\n for (const write of request.executionWrites)\n yield* checkValueBound(\"commit active execution\", write.json, write.bytes);\n\n const recordIds: Array<string> = request.records.map((record) => record.recordId);\n\n if (new Set(recordIds).size !== recordIds.length) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} contains duplicate canonical record IDs.`,\n reason: \"record-identity\",\n });\n }\n\n return request;\n });\n\n // Replay and progress validation precede this body in the same owner transaction.\n // A miss makes no native change; the ordinary path reuses any tentative batch.\n // After advancing the frontier, failures must roll back rather than fall back.\n const appendNativeBody = Effect.fnUntraced(function* (\n request: RawAppendRequest,\n first: CanonicalSequence,\n last: CanonicalSequence,\n batchInserted: boolean,\n ) {\n const db = nativeDb;\n\n // Effectful statement transformers and exported SQL spans retain the ordinary path.\n const ordinaryStatement = yield* Effect.withFiber((fiber) =>\n Effect.succeed(\n fiber.getRef(CurrentTransformer) !== undefined ||\n (fiber.getRef(References.TracerEnabled) &&\n fiber.getRef(Tracer.Tracer) !== Tracer.nativeTracer),\n ),\n );\n\n if (ordinaryStatement) return false;\n if (\n db === undefined ||\n request.executionWrites.length !== 1 ||\n request.executionWrites[0]?.update.retire ||\n request.executionWrites[0]?.update.facts.length !== 0\n )\n return false;\n\n const workPlan = yield* work.prepareClosedPair(\n request.threadId,\n first,\n last,\n request.records.map((record) => record.canonical),\n );\n\n if (workPlan === undefined) return false;\n\n const native = yield* Effect.suspend(() => {\n const query = (statement: Statement<object>, operation: string) =>\n Result.try({\n try: () => {\n const [text, parameters] = statement.compile();\n\n return db.exec(text, ...parameters).toArray();\n },\n catch: (cause) =>\n storageError(operation)(\n SqlError.make({\n reason: classifySqliteError(cause, {\n operation,\n message: \"Native canonical statement failed\",\n }),\n }),\n ),\n });\n\n return Effect.fromResult(\n Result.gen(function* () {\n const captured = physical.cachedRecords(request.threadId, first, request.records);\n\n if (captured === undefined) return undefined;\n const physicalRecords = yield* captured;\n const rows = yield* query(workPlan.advance, \"advance native work frontier\");\n\n // A zero-row predicate miss has made no change. A successful update\n // must never fall back: every later refusal rolls back this transaction.\n if (rows.length === 0) return undefined;\n const executionPlans = executions.prepareCommit(request);\n\n if (!batchInserted)\n yield* query(\n sql`INSERT INTO effect_agent_canonical_batches\n (thread_id, batch_id, first_sequence, last_sequence, producer_id_json)\n VALUES (${request.threadId}, ${JSON.stringify(request.batchId)}, ${first}, ${last}, ${request.producerIdJson})`,\n \"insert canonical batch\",\n );\n\n const inserted = yield* query(\n sql`INSERT INTO effect_agent_canonical_records ${sql.insert(physicalRecords.map((row) => row.columns))}\n ON CONFLICT(thread_id, record_id) DO NOTHING RETURNING 1`,\n \"insert canonical records\",\n );\n\n if (inserted.length !== request.records.length)\n return yield* Result.fail(\n DoAppendConflict.make({\n message: \"A canonical record ID already exists.\",\n reason: \"record-identity\",\n }),\n );\n const memberships = physicalRecords.flatMap((row) => row.memberships);\n\n for (const group of chunked(memberships, Math.floor(MAX_BOUND_PARAMETERS / 3)))\n yield* query(\n sql`INSERT INTO effect_agent_record_runs ${sql.insert(group)}`,\n \"index canonical Run membership\",\n );\n for (const pointer of workPlan.pointers)\n yield* query(pointer, \"index canonical pointers\");\n\n for (const plan of executionPlans) {\n const changed = yield* query(plan.statement, \"commit active execution\");\n const accepted = plan.accept(changed);\n\n if (Result.isFailure(accepted))\n return yield* Result.fail(\n DoAppendConflict.make({\n reason: accepted.failure.reason,\n message: \"Active execution conflicts with the captured commit\",\n ...(accepted.failure.actualTailSequence === undefined\n ? {}\n : { actualTailSequence: accepted.failure.actualTailSequence }),\n }),\n );\n }\n for (let index = 0; index < request.records.length; index++) {\n const record = request.records[index]!;\n\n recordCache.put(\n RecordRow.make({\n ...physicalRecords[index]!.columns,\n thread_id: request.threadId,\n record_id: record.recordId,\n batch_id: request.batchId,\n record_json: record.recordJson,\n sequence: CanonicalSequence.make(first + index),\n }),\n record.recordBytes,\n );\n }\n\n return rows;\n }),\n );\n });\n\n if (native === undefined) return false;\n yield* threads.write(Effect.succeed(native));\n\n return true;\n });\n\n const appendPrepared = Effect.fnUntraced(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<AppendResult, AppendError> {\n const threadRows = yield* getThread(request.threadId);\n\n const thread = threadRows.length === 1 ? threadRows[0] : undefined;\n\n if (thread === undefined)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: request.threadId,\n message: `Expected exactly one row but found ${threadRows.length}.`,\n });\n\n // A fresh canonical batch key and absence of an active receipt prove the two\n // negative replay lookups in the same statement that retains the batch header.\n // Keep the read-first path for stale/overflowed coordinates so exact retries\n // still precede sequence and tail refusals.\n const canInsert =\n request.records.length > 0 &&\n request.expectedTailSequence === thread.tail_sequence &&\n Number.isSafeInteger(thread.tail_sequence + request.records.length);\n\n const inserted = canInsert\n ? yield* sql`INSERT INTO effect_agent_canonical_batches\n (thread_id, batch_id, first_sequence, last_sequence, producer_id_json)\n SELECT ${request.threadId}, ${JSON.stringify(request.batchId)},\n ${thread.tail_sequence + 1}, ${thread.tail_sequence + request.records.length},\n ${request.producerIdJson}\n WHERE NOT EXISTS (\n SELECT 1 FROM effect_agent_executions\n WHERE thread_id=${request.threadId} AND last_commit_id=${request.batchId}\n )\n ON CONFLICT(thread_id, batch_id) DO NOTHING RETURNING 1`.pipe(\n Effect.mapError(storageError(\"insert canonical batch\")),\n )\n : [];\n\n if (inserted.length === 0) {\n const replay = yield* executionConflict(executions.replay(request));\n\n if (replay !== undefined) return AppendResult.make(replay);\n\n const prefix = recordCache.prefix(request.threadId, thread.tail_sequence);\n\n const existing =\n prefix !== undefined && !prefix.some((row) => row.batch_id === request.batchId)\n ? undefined\n : yield* archives.replay(request.threadId, request.batchId);\n\n if (existing !== undefined) {\n if (existing.batch_json !== request.batchJson) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-content\",\n });\n }\n\n return AppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n });\n }\n if (canInsert)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: request.threadId,\n message: \"Batch insertion conflicted without a durable replay receipt.\",\n });\n }\n\n yield* executionConflict(executions.rejectSuperseded(request));\n\n if (request.expectedTailSequence !== thread.tail_sequence) {\n return yield* DoAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence} ` + `but found ${thread.tail_sequence}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\n });\n }\n\n const result = yield* Schema.decodeEffect(AppendResult)({\n firstSequence: thread.tail_sequence + (request.records.length === 0 ? 0 : 1),\n lastSequence: thread.tail_sequence + request.records.length,\n replayed: false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n const { firstSequence, lastSequence } = result;\n\n yield* executionConflict(executions.validate(request));\n\n if (yield* appendNativeBody(request, firstSequence, lastSequence, inserted.length > 0)) {\n yield* progress.committed(\"canonical\").pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) =>\n DoStorageError.make({\n operation: \"enroll canonical progress\",\n message: error.message,\n cause: error,\n }),\n ),\n ),\n ),\n );\n\n return result;\n }\n\n if (request.records.length > 0 && inserted.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n producer_id_json\n ) VALUES (\n ${request.threadId},\n ${JSON.stringify(request.batchId)},\n ${firstSequence},\n ${lastSequence},\n ${request.producerIdJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n }\n yield* failpoint(\"append:after-batch-insert\");\n\n const physicalRecords = yield* physical.records(\n request.threadId,\n firstSequence,\n request.records,\n );\n\n const records = physicalRecords.map(({ columns, memberships }, index) => ({\n record: request.records[index]!,\n canonical: request.records[index]!.canonical,\n row: columns,\n memberships,\n }));\n\n // Captured scalar locators avoid parsing canonical JSON under the writer.\n // Eighteen bound columns per row stay within workerd's statement limit.\n for (const group of chunked(records, Math.floor(MAX_BOUND_PARAMETERS / 18))) {\n const inserted =\n yield* sql`INSERT INTO effect_agent_canonical_records ${sql.insert(group.map(({ row }) => row))}\n ON CONFLICT(thread_id, record_id) DO NOTHING RETURNING 1`.pipe(\n Effect.mapError(storageError(\"insert canonical records\")),\n );\n\n if (inserted.length !== group.length)\n return yield* DoAppendConflict.make({\n message: \"A canonical record ID already exists.\",\n reason: \"record-identity\",\n });\n\n const memberships = group.flatMap(({ memberships }) => memberships);\n\n for (const members of chunked(memberships, Math.floor(MAX_BOUND_PARAMETERS / 3)))\n yield* sql`INSERT INTO effect_agent_record_runs ${sql.insert(members)}`.pipe(\n Effect.mapError(storageError(\"index canonical Run membership\")),\n );\n for (const { row, record } of group) {\n recordCache.put(\n RecordRow.make({\n ...row,\n thread_id: request.threadId,\n record_id: record.recordId,\n batch_id: request.batchId,\n record_json: record.recordJson,\n sequence: Schema.decodeSync(CanonicalSequence)(row.sequence),\n }),\n record.recordBytes,\n );\n yield* failpoint(\"append:after-record-insert\");\n }\n }\n\n if (request.records.length > 0) {\n const workFields = yield* work\n .apply(\n request.threadId,\n firstSequence,\n request.records.map((record) => record.canonical),\n )\n .pipe(Effect.mapError(workFailure));\n\n yield* sql`UPDATE effect_agent_threads SET ${sql.update({ tail_sequence: lastSequence, ...workFields })}\n WHERE thread_id=${request.threadId} RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"advance thread tail\")(error) : error,\n ),\n );\n }\n yield* executionConflict(executions.commit(request, result));\n if (request.executionWrites.length > 0) yield* failpoint(\"append:after-record-insert\");\n if (\n lifecycle !== undefined &&\n request.executionWrites.some(({ update }) =>\n update.facts.some(({ payload }) => payload._tag === \"RunStarted\"),\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n for (const { update } of request.executionWrites) {\n for (const fact of update.facts) {\n if (\n lifecycle !== undefined &&\n Schema.is(Schema.toType(LifecyclePublicationFact))(fact.payload)\n )\n yield* lifecycle\n .retain({\n id: JSON.stringify([request.threadId, \"record\", fact.recordId]),\n ownerThreadId: request.threadId,\n canonicalSequence: lastSequence,\n createdAt: fact.createdAt,\n fact: fact.payload,\n })\n .pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain operational lifecycle\",\n message: cause.message,\n cause,\n }),\n ),\n );\n }\n }\n yield* failpoint(\"append:after-tail-update\");\n\n // Retain one start prefix atomically with its canonical proof, before model/tool\n // execution. Later facts stay journal-backed until the settlement publication wave.\n if (\n lifecycle !== undefined &&\n records.some(\n ({ canonical: { payload } }) =>\n payload._tag === \"RunStarted\" || payload._tag === \"SubagentStarted\",\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n\n yield* progress.committed(\"canonical\").pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) =>\n DoStorageError.make({\n operation: \"enroll canonical progress\",\n message: error.message,\n cause: error,\n }),\n ),\n ),\n ),\n );\n\n return result;\n });\n\n const append = Effect.fnUntraced(\n function* (\n request: RawAppendRequest,\n observed: ThreadRow,\n ): Effect.fn.Return<AppendResult, AppendError> {\n yield* prepareAppend(request);\n // The facade already read this tail. Reject a known stale writer without opening a\n // transaction; a matching tail is still checked atomically below. Replays precede tail\n // conflicts, preserving retry identity even after the log has advanced.\n if (request.records.length > 0 && request.expectedTailSequence !== observed.tail_sequence) {\n const batches = yield* sql`\n SELECT batch_id FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId} AND batch_id = ${JSON.stringify(request.batchId)}\n UNION ALL SELECT last_commit_id FROM effect_agent_executions\n WHERE thread_id = ${request.threadId} AND last_commit_id = ${request.batchId}\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"preflight append replay\")));\n\n // A possible replay still checks exact content in the transaction.\n if (batches.length === 0) {\n return yield* DoAppendConflict.make({\n reason: \"tail\",\n message: \"The canonical tail has advanced.\",\n actualTailSequence: observed.tail_sequence,\n });\n }\n }\n\n // Receipt arbitration may have tentatively inserted a batch. Even typed\n // contention must roll back before leaving the owner mutation gate.\n return yield* withWriteTransaction(\"append transaction\")(appendPrepared(request));\n },\n withStorageSpan(\"DoJournal.append\", isAppendContention),\n );\n\n const read = Effect.fnUntraced(function* (request: RawReadRequest) {\n const thread = (yield* getThread(request.threadId))[0];\n\n const through = Math.min(\n thread?.tail_sequence ?? 0,\n request.fromSequenceExclusive + request.limit,\n );\n\n const cached: Array<RecordRow> = [];\n\n for (let sequence = request.fromSequenceExclusive + 1; sequence <= through; sequence++) {\n const record = recordCache.get(request.threadId, sequence);\n\n if (record === undefined) break;\n cached.push(record);\n }\n if (cached.length === Math.max(0, through - request.fromSequenceExclusive)) {\n return { count: cached.length, records: Stream.fromIterable(cached) };\n }\n\n // Capture membership without retaining payloads. Append-only sequences keep each later\n // payload query inside this snapshot, even when new records arrive during consumption.\n const planRows = yield* sql<Record<string, unknown>>`\n SELECT\n sequence,\n length(CAST(${recordJson} AS BLOB)) AS record_json_bytes\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence > ${request.fromSequenceExclusive}\n ORDER BY sequence\n LIMIT ${request.limit}\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const plan = yield* decodeRows(\n Schema.Array(ReadPlanRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n planRows,\n \"ReadPlanRow\",\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message: \"Canonical read membership, sequence, or payload size changed from its read plan.\",\n });\n\n if (plan.length > request.limit) return yield* mismatch();\n\n const pages: Array<ReadPage> = [];\n let page: ReadPage | undefined;\n let pageBytes = 0;\n let previousSequence = request.fromSequenceExclusive;\n\n for (const row of plan) {\n if (row.sequence !== previousSequence + 1) return yield* mismatch();\n previousSequence = row.sequence;\n if (page === undefined || pageBytes + row.record_json_bytes > MAX_READ_PAGE_JSON_BYTES) {\n page = [row];\n pages.push(page);\n pageBytes = row.record_json_bytes;\n } else {\n page.push(row);\n pageBytes += row.record_json_bytes;\n }\n }\n\n const readPage = Effect.fnUntraced(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, ${recordBatchId(sql)} AS batch_id, ${recordJson} AS record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence >= ${page[0].sequence}\n AND sequence <= ${page[page.length - 1].sequence}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const decoded = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/${page[0].sequence}`,\n rows,\n \"RecordRow\",\n );\n\n if (\n decoded.length !== page.length ||\n decoded.some(\n (row, index) =>\n row.thread_id !== request.threadId ||\n row.sequence !== page[index].sequence ||\n storedTextBytes(row.record_json) !== page[index].record_json_bytes,\n )\n ) {\n return yield* mismatch();\n }\n\n for (const row of decoded) recordCache.put(row);\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(state.read(readPage(page)))),\n ),\n };\n });\n\n const saveCheckpoint = Effect.fnUntraced(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save checkpoint\", checkpoint.checkpointJson);\n yield* withWriteTransaction(\"checkpoint transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* getThread(checkpoint.threadId);\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n checkpoint.threadId,\n threadRows,\n );\n\n if (checkpoint.throughSequence > thread.tail_sequence) {\n return yield* DoCheckpointConflict.make({\n reason: \"ahead-of-tail\",\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n if (!(yield* isBatchBoundary(checkpoint.threadId, checkpoint.throughSequence))) {\n return yield* DoCheckpointConflict.make({\n reason: \"not-batch-boundary\",\n message: \"Checkpoint sequence is not the end of a complete canonical batch.\",\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${checkpoint.threadId}\n AND through_sequence = ${checkpoint.throughSequence}\n `.pipe(Effect.mapError(storageError(\"read idempotent checkpoint\")));\n\n const existing = yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n checkpointRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n message: \"A checkpoint primary key returned more than one row.\",\n });\n }\n if (existing.length === 1) {\n if (existing[0].checkpoint_json !== checkpoint.checkpointJson) {\n return yield* DoCheckpointConflict.make({\n reason: \"corrupt\",\n message: \"A different checkpoint already exists at this canonical sequence.\",\n });\n }\n\n return;\n }\n\n yield* sql`\n INSERT INTO effect_agent_checkpoints (\n thread_id,\n through_sequence,\n checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const loadCheckpoint = Effect.fnUntraced(function* (\n threadId: string,\n atOrBeforeSequence: CanonicalSequence,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${threadId}\n AND through_sequence <= ${atOrBeforeSequence}\n ORDER BY through_sequence DESC\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"load checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${threadId}<=${atOrBeforeSequence}`,\n rows,\n );\n });\n\n const isBatchBoundary = Effect.fnUntraced(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) return true;\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT last_sequence FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND batch_id = (\n SELECT ${recordBatchId(sql)} FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND sequence = ${sequence}\n )\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical batch boundary\")));\n\n const batches = yield* decodeRows(\n Schema.Array(Schema.Struct({ last_sequence: CanonicalSequence })),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.length === 1;\n });\n\n const sourceFailure = (cause: unknown) =>\n LifecyclePublicationError.make({ reason: \"unavailable\", cause });\n\n const sourceThreads = Effect.fnUntraced(function* () {\n const all = yield* threads.matching(\n \"lifecycle-owners\",\n (row) => row.created_at !== null,\n sql`SELECT * FROM effect_agent_threads WHERE created_at IS NOT NULL LIMIT 129`,\n 128,\n );\n\n if (all.length <= 128) return all;\n\n // Large custom hosts hydrate only owners whose journal has an unmaterialized suffix.\n return yield* Schema.decodeUnknownEffect(Schema.Array(ThreadRow))(\n yield* sql`SELECT t.* FROM effect_agent_threads t LEFT JOIN effect_agent_lifecycle_cursors c ON c.thread_id=t.thread_id\n WHERE t.created_at IS NOT NULL AND (c.thread_id IS NULL OR t.tail_sequence > c.through_sequence) ORDER BY t.thread_id LIMIT 128`,\n );\n });\n\n const initializeLifecycleSource = Effect.fnUntraced(function* () {\n if (initializedLifecycleSources.has(state)) return;\n yield* state\n .transaction(\n Effect.gen(function* () {\n const existing =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_lifecycle_cursors'`;\n\n if (existing.length === 0) {\n yield* sql`CREATE TABLE effect_agent_lifecycle_cursors (\n thread_id TEXT PRIMARY KEY, through_sequence INTEGER NOT NULL\n )`;\n // Existing inline writers already retained their facts. Enabling publication on an\n // old store starts here too; it does not publish historical facts retroactively.\n }\n // New Threads created with publication disabled have no cursor. Never advance\n // existing cursors: they can owe intent from an interrupted Attempt.\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence)\n SELECT thread_id, tail_sequence FROM effect_agent_threads WHERE created_at IS NOT NULL\n ON CONFLICT(thread_id) DO NOTHING`;\n yield* sourceThreads();\n }),\n )\n .pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle source\",\n message: \"Lifecycle source cursor unavailable\",\n cause,\n }),\n ),\n );\n initializedLifecycleSources.add(state);\n });\n\n /** The journal is durable intent; only the bounded publication wave materializes a write set. */\n const flushCanonical = Effect.fnUntraced(function* (threadId: string, maxRecords = Infinity) {\n const { retainMany } = yield* SqlLifecycleRetainer;\n const thread = (yield* getThread(threadId))[0];\n\n if (thread === undefined) return;\n const cursor = (yield* cursors.by(\"thread_id\", threadId))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n let through = cursor.through_sequence;\n const bound = Math.min(thread.tail_sequence, through + maxRecords);\n\n while (through < bound) {\n const page = yield* read(\n RawReadRequest.make({\n threadId,\n fromSequenceExclusive: through,\n limit: Math.min(128, bound - through),\n }),\n );\n\n const facts: Array<Parameters<SqlLifecycleRetainMany>[0][number]> = [];\n let bytes = 0;\n\n yield* Stream.runForEach(page.records, (row) =>\n Effect.gen(function* () {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n row.record_json,\n );\n\n if (record.recordId !== row.record_id || row.sequence !== through + 1)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (Schema.is(Schema.toType(LifecyclePublicationFact))(record.payload)) {\n if (\n bytes + storedTextBytes(row.record_json) > MAX_READ_PAGE_JSON_BYTES &&\n facts.length > 0\n ) {\n yield* retainMany(facts);\n facts.length = 0;\n bytes = 0;\n }\n facts.push({\n id: JSON.stringify([threadId, \"record\", record.recordId]),\n ownerThreadId: yield* Schema.decodeEffect(ThreadId)(threadId),\n canonicalSequence: row.sequence,\n createdAt: record.createdAt,\n fact: record.payload,\n });\n bytes += storedTextBytes(row.record_json);\n }\n through = row.sequence;\n }),\n );\n if (page.count === 0) return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n yield* retainMany(facts);\n yield* sql`UPDATE effect_agent_lifecycle_cursors SET through_sequence=${through} WHERE thread_id=${threadId} RETURNING *`.pipe(\n cursors.write,\n );\n }\n }, Effect.mapError(sourceFailure));\n\n const flushPublications = Effect.fnUntraced(function* () {\n let owners = 0;\n\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor !== undefined && cursor.through_sequence === thread.tail_sequence) continue;\n yield* flushCanonical(thread.thread_id, 1024);\n if (++owners === 4) break;\n }\n }, Effect.mapError(sourceFailure));\n\n const sourcePending = Effect.gen(function* () {\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (cursor.through_sequence < thread.tail_sequence) return true;\n }\n\n return false;\n }).pipe(Effect.mapError(sourceFailure));\n\n const ownedLifecycle =\n lifecycle === undefined\n ? undefined\n : {\n ...lifecycle,\n storage: {\n ...lifecycle.storage,\n retainedPendingDeadline: lifecycle.storage.pendingDeadline,\n pendingDeadline: state.read(\n Effect.gen(function* () {\n const deadline = yield* lifecycle.storage.pendingDeadline;\n\n if (!(yield* sourcePending)) return deadline;\n const now = yield* Clock.currentTimeMillis;\n\n return Option.some(Option.isSome(deadline) ? Math.min(now, deadline.value) : now);\n }),\n ),\n },\n };\n\n return {\n archives: archives.storage,\n archiveRanges: archives,\n work,\n state,\n owner,\n threads,\n lifecycle: ownedLifecycle,\n initializeLifecycleSource,\n flushCanonical,\n flushPublications,\n append,\n prepareAppend,\n appendPrepared,\n checkCommitIntent: (request: RawAppendRequest) =>\n executionConflict(executions.checkCommitIntent(request)),\n readExecution: executions.read,\n checkValueBound,\n getThread,\n hasRecord,\n isBatchBoundary,\n loadCheckpoint,\n materialize,\n read: (request: RawReadRequest) => state.read(read(request)),\n saveCheckpoint,\n withWriteTransaction,\n } as const;\n});\n\nexport type DoJournal = Effect.Success<ReturnType<typeof makeJournal>>;\n\nconst InitializedDoJournal = Context.Reference<DoJournal | undefined>(\n \"@effect-agent/storage-cloudflare/InitializedDoJournal\",\n { defaultValue: () => undefined },\n);\n\n/** Build once in the common owner, SQL, configuration, failpoint and lifecycle context. */\nexport const initializedDoJournalLayer = Layer.effect(InitializedDoJournal)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n\n return yield* ensureCurrentStorage(sql, failpoint.hit, config.maxStoredValueBytes);\n }),\n);\n\nexport const initializeDoJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n) =>\n Effect.filterOrElse(InitializedDoJournal, Predicate.isNotUndefined, () =>\n ensureCurrentStorage(sql, failpoint, maxStoredValueBytes),\n );\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import { t as DoMessageDeliveryStore_exports } from "./DoMessageDeliveryStore.mj
5
5
  import { t as DoMemoryStore_exports } from "./DoMemoryStore.mjs";
6
6
  import { t as DoScheduleStore_exports } from "./DoScheduleStore.mjs";
7
7
  import { t as DoStorageVersion_exports } from "./DoStorageVersion.mjs";
8
- import { t as DoThreadStore_exports } from "./DoThreadStore-DG0h5J6u.mjs";
8
+ import { t as DoThreadStore_exports } from "./DoThreadStore-Bi7eQuWE.mjs";
9
9
  import { t as DoSubmissionLedger_exports } from "./DoSubmissionLedger.mjs";
10
10
  import { t as DoSubscriptionStore_exports } from "./DoSubscriptionStore.mjs";
11
11
  import { t as MemoryProtocol_exports } from "./MemoryProtocol.mjs";
@@ -111,9 +111,9 @@ const ownedRows = (schema, table, key, identityColumn, uniqueFields = [], projec
111
111
  return rows;
112
112
  }));
113
113
  }));
114
- const by = (field, value) => matching(JSON.stringify([field, value]), (row) => row[field] === value, sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`);
114
+ const by = (field, value) => matching(JSON.stringify([field, value]), (row) => row[field] === value, Effect.suspend(() => sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`));
115
115
  const seed = (field, value, rows) => retain(JSON.stringify([field, value]), (row) => row[field] === value, rows, Infinity);
116
- const byFields = (fields) => matching(JSON.stringify(fields), (row) => fields.every(([field, value]) => row[field] === value), sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`);
116
+ const byFields = (fields) => matching(JSON.stringify(fields), (row) => fields.every(([field, value]) => row[field] === value), Effect.suspend(() => sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`));
117
117
  const apply = (remove) => (effect) => Effect.gen(function* () {
118
118
  const rows = yield* decode(yield* effect);
119
119
  if (rows.length === 0) return rows;
@@ -149,4 +149,4 @@ const ownedRows = (schema, table, key, identityColumn, uniqueFields = [], projec
149
149
  //#endregion
150
150
  export { ownedRows as n, ownedState as r, invalidateOwnedState as t };
151
151
 
152
- //# sourceMappingURL=owned-state-BgGOA2Ak.mjs.map
152
+ //# sourceMappingURL=owned-state-Tk_KahHn.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"owned-state-BgGOA2Ak.mjs","names":[],"sources":["../src/internal/owned-state.ts"],"sourcesContent":["import { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport { makeStorageOwner, type StorageOwner } from \"@yielded/agent/run-storage\";\nimport { Deferred, Effect, Exit, Predicate, Schema, Scope, Semaphore } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { DoStorageCorruptionError, DoStorageError } from \"../DoStorageError.ts\";\n\n/** One disposable view per physical Object database, including separately acquired adapters. */\nexport class OwnedState {\n constructor(readonly owner: StorageOwner[\"Service\"]) {}\n readonly invalidators = new Set<() => void>();\n\n readonly invalidate = Effect.sync(() => {\n for (const invalidate of this.invalidators) invalidate();\n });\n\n /** Cached readers must wait for the complete transaction, including rollback/commit. */\n readonly read = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n this.owner.withMutation(effect);\n\n readonly transaction = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R | SqlClient> =>\n this.read(\n Effect.flatMap(SqlClient, (sql) =>\n sql\n .withTransaction(effect)\n .pipe(Effect.onExit((exit) => (Exit.isFailure(exit) ? this.invalidate : Effect.void))),\n ),\n );\n}\n\ninterface RetainedState {\n readonly ready: Deferred.Deferred<OwnedState>;\n readonly disposed: Deferred.Deferred<void>;\n readonly scope: Scope.Closeable;\n references: number;\n closing: boolean;\n}\n\nconst states = new WeakMap<object, RetainedState>();\n\n/** Explicit invalidation for maintenance that writes private tables outside the adapters. */\nexport const invalidateOwnedState = (storage: DurableObjectStorage): Effect.Effect<void> =>\n Effect.suspend(() => {\n const state = states.get(storage);\n\n return state === undefined\n ? Effect.void\n : Deferred.await(state.ready).pipe(Effect.flatMap((state) => state.read(state.invalidate)));\n });\n\nconst DoClient = Schema.declare<SqliteClient.SqliteClient>(\n (value): value is SqliteClient.SqliteClient => Predicate.hasProperty(value, SqliteClient.TypeId),\n);\n\nexport const ownedState = (sql: SqlClient) =>\n Schema.decodeUnknownEffect(DoClient)(sql).pipe(\n Effect.mapError(() =>\n DoStorageError.make({\n operation: \"open owned state\",\n message: \"Owned state requires a Durable Object SQLite client.\",\n }),\n ),\n Effect.flatMap((client) =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n // Instrumentation may return fresh wrappers; the physical Object identity owns the root.\n const key = client.config.storage ?? client.config.db ?? client;\n\n for (;;) {\n let retained = states.get(key);\n\n if (retained?.closing) {\n yield* Deferred.await(retained.disposed);\n continue;\n }\n if (retained === undefined) {\n retained = {\n ready: Deferred.makeUnsafe(),\n disposed: Deferred.makeUnsafe(),\n scope: Scope.makeUnsafe(),\n references: 1,\n closing: false,\n };\n states.set(key, retained);\n\n const owner = yield* makeStorageOwner(Semaphore.makeUnsafe(1).withPermits(1)).pipe(\n Scope.provide(retained.scope),\n );\n\n yield* Deferred.succeed(retained.ready, new OwnedState(owner));\n } else retained.references++;\n const current = retained;\n\n yield* Effect.addFinalizer(() =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n current.references--;\n if (current.references !== 0) return;\n current.closing = true;\n yield* Scope.close(current.scope, Exit.void).pipe(\n Effect.ensuring(\n Effect.gen(function* () {\n if (states.get(key) === current) states.delete(key);\n yield* Deferred.succeed(current.disposed, undefined);\n }),\n ),\n );\n }),\n ),\n );\n\n return yield* Deferred.await(current.ready);\n }\n }),\n ),\n ),\n );\n\n/**\n * Demand-loaded row views. Writes apply SQLite's RETURNING rows to affected retained views in\n * the same transaction; rollback discards them. Bounded views avoid loading a host's entire\n * retained submission history just to fence one live submission.\n */\nexport const ownedRows = <A, I>(\n schema: Schema.Codec<A, I>,\n table: string,\n key: (row: A) => string,\n identityColumn?: keyof A & string,\n uniqueFields: ReadonlyArray<ReadonlyArray<keyof A & string>> = [],\n projection: (sql: SqlClient) => ReturnType<SqlClient[\"literal\"]> = (sql) => sql.literal(\"*\"),\n) => {\n type View = {\n readonly id: string;\n readonly matches: (row: A) => boolean;\n readonly maxRows: number;\n readonly rows: ReadonlyArray<A>;\n readonly bytes: number;\n };\n const caches = new WeakMap<OwnedState, Map<string, View>>();\n const decodeRows = Schema.decodeUnknownEffect(Schema.Array(schema));\n\n return (state: OwnedState, sql: SqlClient) => {\n let cache = caches.get(state);\n\n if (cache === undefined) {\n cache = new Map();\n caches.set(state, cache);\n const current = cache;\n\n state.invalidators.add(() => current.clear());\n }\n const current = cache;\n\n const decode = (rows: unknown) =>\n decodeRows(rows).pipe(\n Effect.mapErrorEager(() =>\n DoStorageCorruptionError.make({\n table,\n rowKey: \"owned-state\",\n message: \"Stored rows do not satisfy the storage schema\",\n }),\n ),\n );\n\n const retain = (\n id: string,\n matches: View[\"matches\"],\n rows: ReadonlyArray<A>,\n maxRows: number,\n ) => {\n const bytes = new TextEncoder().encode(JSON.stringify(rows)).byteLength;\n\n current.delete(id);\n if (rows.length > maxRows || bytes > 4 * 1024 * 1024) return;\n current.set(id, { id, matches, maxRows, rows, bytes });\n let total = 0;\n\n for (const view of current.values()) total += view.bytes;\n while (current.size > 128 || total > 4 * 1024 * 1024) {\n const oldest = current.entries().next().value;\n\n if (oldest === undefined) break;\n total -= oldest[1].bytes;\n current.delete(oldest[0]);\n }\n };\n\n const matching = (\n id: string,\n matches: View[\"matches\"],\n query: Effect.Effect<ReadonlyArray<unknown>, SqlError>,\n maxRows = Infinity,\n ) =>\n state.read(\n Effect.suspend(() => {\n const view = current.get(id);\n\n if (view !== undefined) return Effect.succeed(view.rows);\n\n return Effect.flatMap(query, (rows) =>\n Effect.mapEager(decode(rows), (rows) => {\n retain(id, matches, rows, maxRows);\n\n return rows;\n }),\n );\n }),\n );\n\n const by = (field: keyof A & string, value: string) =>\n matching(\n JSON.stringify([field, value]),\n (row) => row[field] === value,\n sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`,\n );\n\n // Only a source mutation proving the complete result may seed a view. This must run\n // under the owner transaction; rollback invalidates it with every other retained view.\n const seed = (field: keyof A & string, value: string, rows: ReadonlyArray<A>) =>\n retain(JSON.stringify([field, value]), (row) => row[field] === value, rows, Infinity);\n\n const byFields = (fields: ReadonlyArray<readonly [keyof A & string, string]>) =>\n matching(\n JSON.stringify(fields),\n (row) => fields.every(([field, value]) => row[field] === value),\n sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`,\n );\n\n const apply =\n (remove: boolean) =>\n <E, R>(effect: Effect.Effect<ReadonlyArray<unknown>, E, R>) =>\n Effect.gen(function* () {\n const rows = yield* decode(yield* effect);\n\n if (rows.length === 0) return rows;\n const changed = new Set(rows.map(key));\n\n for (const { id, matches, maxRows, rows: prior } of Array.from(current.values())) {\n const matchingRows = remove ? [] : rows.filter(matches);\n\n if (matchingRows.length === 0 && !prior.some((row) => changed.has(key(row)))) continue;\n const next = prior.filter((row) => !changed.has(key(row)));\n\n next.push(...matchingRows);\n retain(id, matches, next, maxRows);\n }\n // A RETURNING row completely defines its unique-key view, even on a new Thread.\n if (identityColumn !== undefined)\n for (const row of rows) {\n const value = row[identityColumn];\n\n if (typeof value === \"string\")\n retain(\n JSON.stringify([identityColumn, value]),\n (row) => row[identityColumn] === value,\n remove ? [] : [row],\n Infinity,\n );\n }\n\n for (const row of rows)\n for (const fields of uniqueFields) {\n const values = fields.map((field) => [field, row[field]] as const);\n\n retain(\n JSON.stringify(values),\n (candidate) => values.every(([field, value]) => candidate[field] === value),\n remove ? [] : [row],\n 1,\n );\n }\n\n return rows;\n });\n\n return {\n by,\n byFields,\n matching,\n seed,\n seedMatching: retain,\n write: apply(false),\n remove: apply(true),\n };\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"owned-state-Tk_KahHn.mjs","names":[],"sources":["../src/internal/owned-state.ts"],"sourcesContent":["import { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport { makeStorageOwner, type StorageOwner } from \"@yielded/agent/run-storage\";\nimport { Deferred, Effect, Exit, Predicate, Schema, Scope, Semaphore } from \"effect\";\nimport { SqlClient } from \"effect/sql/SqlClient\";\nimport type { SqlError } from \"effect/sql/SqlError\";\n\nimport { DoStorageCorruptionError, DoStorageError } from \"../DoStorageError.ts\";\n\n/** One disposable view per physical Object database, including separately acquired adapters. */\nexport class OwnedState {\n constructor(readonly owner: StorageOwner[\"Service\"]) {}\n readonly invalidators = new Set<() => void>();\n\n readonly invalidate = Effect.sync(() => {\n for (const invalidate of this.invalidators) invalidate();\n });\n\n /** Cached readers must wait for the complete transaction, including rollback/commit. */\n readonly read = <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n this.owner.withMutation(effect);\n\n readonly transaction = <A, E, R>(\n effect: Effect.Effect<A, E, R>,\n ): Effect.Effect<A, E | SqlError, R | SqlClient> =>\n this.read(\n Effect.flatMap(SqlClient, (sql) =>\n sql\n .withTransaction(effect)\n .pipe(Effect.onExit((exit) => (Exit.isFailure(exit) ? this.invalidate : Effect.void))),\n ),\n );\n}\n\ninterface RetainedState {\n readonly ready: Deferred.Deferred<OwnedState>;\n readonly disposed: Deferred.Deferred<void>;\n readonly scope: Scope.Closeable;\n references: number;\n closing: boolean;\n}\n\nconst states = new WeakMap<object, RetainedState>();\n\n/** Explicit invalidation for maintenance that writes private tables outside the adapters. */\nexport const invalidateOwnedState = (storage: DurableObjectStorage): Effect.Effect<void> =>\n Effect.suspend(() => {\n const state = states.get(storage);\n\n return state === undefined\n ? Effect.void\n : Deferred.await(state.ready).pipe(Effect.flatMap((state) => state.read(state.invalidate)));\n });\n\nconst DoClient = Schema.declare<SqliteClient.SqliteClient>(\n (value): value is SqliteClient.SqliteClient => Predicate.hasProperty(value, SqliteClient.TypeId),\n);\n\nexport const ownedState = (sql: SqlClient) =>\n Schema.decodeUnknownEffect(DoClient)(sql).pipe(\n Effect.mapError(() =>\n DoStorageError.make({\n operation: \"open owned state\",\n message: \"Owned state requires a Durable Object SQLite client.\",\n }),\n ),\n Effect.flatMap((client) =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n // Instrumentation may return fresh wrappers; the physical Object identity owns the root.\n const key = client.config.storage ?? client.config.db ?? client;\n\n for (;;) {\n let retained = states.get(key);\n\n if (retained?.closing) {\n yield* Deferred.await(retained.disposed);\n continue;\n }\n if (retained === undefined) {\n retained = {\n ready: Deferred.makeUnsafe(),\n disposed: Deferred.makeUnsafe(),\n scope: Scope.makeUnsafe(),\n references: 1,\n closing: false,\n };\n states.set(key, retained);\n\n const owner = yield* makeStorageOwner(Semaphore.makeUnsafe(1).withPermits(1)).pipe(\n Scope.provide(retained.scope),\n );\n\n yield* Deferred.succeed(retained.ready, new OwnedState(owner));\n } else retained.references++;\n const current = retained;\n\n yield* Effect.addFinalizer(() =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n current.references--;\n if (current.references !== 0) return;\n current.closing = true;\n yield* Scope.close(current.scope, Exit.void).pipe(\n Effect.ensuring(\n Effect.gen(function* () {\n if (states.get(key) === current) states.delete(key);\n yield* Deferred.succeed(current.disposed, undefined);\n }),\n ),\n );\n }),\n ),\n );\n\n return yield* Deferred.await(current.ready);\n }\n }),\n ),\n ),\n );\n\n/**\n * Demand-loaded row views. Writes apply SQLite's RETURNING rows to affected retained views in\n * the same transaction; rollback discards them. Bounded views avoid loading a host's entire\n * retained submission history just to fence one live submission.\n */\nexport const ownedRows = <A, I>(\n schema: Schema.Codec<A, I>,\n table: string,\n key: (row: A) => string,\n identityColumn?: keyof A & string,\n uniqueFields: ReadonlyArray<ReadonlyArray<keyof A & string>> = [],\n projection: (sql: SqlClient) => ReturnType<SqlClient[\"literal\"]> = (sql) => sql.literal(\"*\"),\n) => {\n type View = {\n readonly id: string;\n readonly matches: (row: A) => boolean;\n readonly maxRows: number;\n readonly rows: ReadonlyArray<A>;\n readonly bytes: number;\n };\n const caches = new WeakMap<OwnedState, Map<string, View>>();\n const decodeRows = Schema.decodeUnknownEffect(Schema.Array(schema));\n\n return (state: OwnedState, sql: SqlClient) => {\n let cache = caches.get(state);\n\n if (cache === undefined) {\n cache = new Map();\n caches.set(state, cache);\n const current = cache;\n\n state.invalidators.add(() => current.clear());\n }\n const current = cache;\n\n const decode = (rows: unknown) =>\n decodeRows(rows).pipe(\n Effect.mapErrorEager(() =>\n DoStorageCorruptionError.make({\n table,\n rowKey: \"owned-state\",\n message: \"Stored rows do not satisfy the storage schema\",\n }),\n ),\n );\n\n const retain = (\n id: string,\n matches: View[\"matches\"],\n rows: ReadonlyArray<A>,\n maxRows: number,\n ) => {\n const bytes = new TextEncoder().encode(JSON.stringify(rows)).byteLength;\n\n current.delete(id);\n if (rows.length > maxRows || bytes > 4 * 1024 * 1024) return;\n current.set(id, { id, matches, maxRows, rows, bytes });\n let total = 0;\n\n for (const view of current.values()) total += view.bytes;\n while (current.size > 128 || total > 4 * 1024 * 1024) {\n const oldest = current.entries().next().value;\n\n if (oldest === undefined) break;\n total -= oldest[1].bytes;\n current.delete(oldest[0]);\n }\n };\n\n const matching = (\n id: string,\n matches: View[\"matches\"],\n query: Effect.Effect<ReadonlyArray<unknown>, SqlError>,\n maxRows = Infinity,\n ) =>\n state.read(\n Effect.suspend(() => {\n const view = current.get(id);\n\n if (view !== undefined) return Effect.succeed(view.rows);\n\n return Effect.flatMap(query, (rows) =>\n Effect.mapEager(decode(rows), (rows) => {\n retain(id, matches, rows, maxRows);\n\n return rows;\n }),\n );\n }),\n );\n\n const by = (field: keyof A & string, value: string) =>\n matching(\n JSON.stringify([field, value]),\n (row) => row[field] === value,\n Effect.suspend(\n () => sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`,\n ),\n );\n\n // Only a source mutation proving the complete result may seed a view. This must run\n // under the owner transaction; rollback invalidates it with every other retained view.\n const seed = (field: keyof A & string, value: string, rows: ReadonlyArray<A>) =>\n retain(JSON.stringify([field, value]), (row) => row[field] === value, rows, Infinity);\n\n const byFields = (fields: ReadonlyArray<readonly [keyof A & string, string]>) =>\n matching(\n JSON.stringify(fields),\n (row) => fields.every(([field, value]) => row[field] === value),\n Effect.suspend(\n () =>\n sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`,\n ),\n );\n\n const apply =\n (remove: boolean) =>\n <E, R>(effect: Effect.Effect<ReadonlyArray<unknown>, E, R>) =>\n Effect.gen(function* () {\n const rows = yield* decode(yield* effect);\n\n if (rows.length === 0) return rows;\n const changed = new Set(rows.map(key));\n\n for (const { id, matches, maxRows, rows: prior } of Array.from(current.values())) {\n const matchingRows = remove ? [] : rows.filter(matches);\n\n if (matchingRows.length === 0 && !prior.some((row) => changed.has(key(row)))) continue;\n const next = prior.filter((row) => !changed.has(key(row)));\n\n next.push(...matchingRows);\n retain(id, matches, next, maxRows);\n }\n // A RETURNING row completely defines its unique-key view, even on a new Thread.\n if (identityColumn !== undefined)\n for (const row of rows) {\n const value = row[identityColumn];\n\n if (typeof value === \"string\")\n retain(\n JSON.stringify([identityColumn, value]),\n (row) => row[identityColumn] === value,\n remove ? [] : [row],\n Infinity,\n );\n }\n\n for (const row of rows)\n for (const fields of uniqueFields) {\n const values = fields.map((field) => [field, row[field]] as const);\n\n retain(\n JSON.stringify(values),\n (candidate) => values.every(([field, value]) => candidate[field] === value),\n remove ? [] : [row],\n 1,\n );\n }\n\n return rows;\n });\n\n return {\n by,\n byFields,\n matching,\n seed,\n seedMatching: retain,\n write: apply(false),\n remove: apply(true),\n };\n };\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@yielded/agent-storage-cloudflare","version":"0.1.0-beta.177","dependencies":{"@effect/platform-browser":"4.0.4","@effect/sql-sqlite-do":"4.0.4","@yielded/agent":"0.1.0-beta.177","@yielded/agent-storage-sql":"0.1.0-beta.177"},"devDependencies":{"@cloudflare/vitest-plugin":"1.4.0","@cloudflare/workers-types":"5.20260926.1","@effect/vitest":"4.0.4","@yielded/agent-testing":"0.1.0-beta.177","effect":"4.0.4","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./do-memory-store":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./do-schedule-store":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./do-storage-config":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./do-storage-error":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./do-storage-failpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./do-storage-version":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./do-submission-ledger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./do-subscription-store":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./do-thread-store":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./memory-protocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./port-protocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./port-routing":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/do-storage-failpoint-testing":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./do-message-delivery-store":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
1
+ {"name":"@yielded/agent-storage-cloudflare","version":"0.1.0-beta.179","dependencies":{"@effect/platform-browser":"4.0.4","@effect/sql-sqlite-do":"4.0.4","@yielded/agent":"0.1.0-beta.179","@yielded/agent-storage-sql":"0.1.0-beta.179"},"devDependencies":{"@cloudflare/vitest-plugin":"1.4.0","@cloudflare/workers-types":"5.20260926.1","@effect/vitest":"4.0.4","@yielded/agent-testing":"0.1.0-beta.179","effect":"4.0.4","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"effect":"^4.0.3"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./do-memory-store":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./do-schedule-store":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./do-storage-config":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./do-storage-error":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./do-storage-failpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./do-storage-version":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./do-submission-ledger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./do-subscription-store":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./do-thread-store":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./memory-protocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./port-protocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./port-routing":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/do-storage-failpoint-testing":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.mjs"},"./do-message-delivery-store":{"types":"./dist/DoMessageDeliveryStore.d.mts","default":"./dist/DoMessageDeliveryStore.mjs"}},"description":"Durable Object SQLite storage adapters and the routed port protocol for Effect Agent on Cloudflare.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/agent.git","directory":"packages/storage-cloudflare"},"files":["dist","src"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json"}}
@@ -597,6 +597,7 @@ const makeServices = Effect.fnUntraced(function* () {
597
597
  ? {}
598
598
  : { lifecyclePublications: journal.lifecycle.storage }),
599
599
  readIdentity: selectedReads.readIdentity,
600
+ readFreshRun: selectedReads.readFreshRun,
600
601
  readExecution: (request) =>
601
602
  journal.state.read(
602
603
  requireThread(journal, request.threadId).pipe(
@@ -1004,6 +1004,10 @@ const makeRoutedStoreServices = Effect.fnUntraced(function* (options: RoutedPort
1004
1004
  };
1005
1005
 
1006
1006
  const routed = ThreadStore.of({
1007
+ readFreshRun: (request) =>
1008
+ options.ownsThread(request.threadId) && local.readFreshRun !== undefined
1009
+ ? local.readFreshRun(request)
1010
+ : Effect.succeed(Option.none()),
1007
1011
  readExecution: (request) =>
1008
1012
  options.ownsThread(request.threadId)
1009
1013
  ? local.readExecution(request)
@@ -1000,7 +1000,7 @@ const makeJournal = Effect.fnUntraced(function* (
1000
1000
  if (request.records.length > 0) {
1001
1001
  const workFields = yield* work
1002
1002
  .apply(
1003
- yield* Schema.decodeEffect(ThreadId)(request.threadId).pipe(Effect.mapError(workFailure)),
1003
+ request.threadId,
1004
1004
  firstSequence,
1005
1005
  request.records.map((record) => record.canonical),
1006
1006
  )
@@ -214,7 +214,9 @@ export const ownedRows = <A, I>(
214
214
  matching(
215
215
  JSON.stringify([field, value]),
216
216
  (row) => row[field] === value,
217
- sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`,
217
+ Effect.suspend(
218
+ () => sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql(field)} = ${value}`,
219
+ ),
218
220
  );
219
221
 
220
222
  // Only a source mutation proving the complete result may seed a view. This must run
@@ -226,7 +228,10 @@ export const ownedRows = <A, I>(
226
228
  matching(
227
229
  JSON.stringify(fields),
228
230
  (row) => fields.every(([field, value]) => row[field] === value),
229
- sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`,
231
+ Effect.suspend(
232
+ () =>
233
+ sql`SELECT ${projection(sql)} FROM ${sql(table)} WHERE ${sql.and(fields.map(([field, value]) => sql`${sql(field)} = ${value}`))}`,
234
+ ),
230
235
  );
231
236
 
232
237
  const apply =
@@ -1 +0,0 @@
1
- {"version":3,"file":"do-journal-ySC3eXNv.mjs","names":["isSqlError","SqlClient"],"sources":["../src/internal/storage-span.ts","../src/internal/do-journal.ts"],"sourcesContent":["import { Effect, Predicate, References, Result, Tracer } from \"effect\";\n\ntype Tagged = { readonly _tag: string; readonly reason?: unknown };\n\nexport const isAppendContention = (error: Tagged): boolean =>\n (error._tag === \"DoAppendConflict\" || error._tag === \"AppendConflict\") && error.reason === \"tail\";\n\n/** Expected refusals remain typed at the port, but are outcomes of the storage operation. */\nexport const storageResult = <A, E extends Tagged, R>(\n effect: Effect.Effect<A, E, R>,\n expected: (error: E) => boolean,\n) =>\n effect.pipe(\n Effect.map(Result.succeed),\n Effect.catchIf(expected, (error) => Effect.succeed(Result.fail(error))),\n );\n\n/** Only error discriminants enter telemetry; messages, SQL, identities and payloads do not. */\nexport const annotateStorageError = (error: Tagged) =>\n Effect.annotateCurrentSpan({\n \"error.type\": error._tag,\n ...(Predicate.hasProperty(error, \"cause\") &&\n Predicate.hasProperty(error.cause, \"_tag\") &&\n typeof error.cause._tag === \"string\"\n ? { \"error.cause.type\": error.cause._tag }\n : {}),\n });\n\nexport const withStorageSpan = (\n name: string,\n expected: (error: Tagged) => boolean = () => false,\n) => {\n const span = Effect.withSpan(name);\n\n return <A, E extends Tagged, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n Effect.withFiber((fiber) =>\n !fiber.getRef(References.TracerEnabled) || fiber.getRef(Tracer.Tracer) === Tracer.nativeTracer\n ? effect\n : storageResult(effect, expected).pipe(\n Effect.tap((result) =>\n Result.isFailure(result)\n ? Effect.annotateCurrentSpan({ \"storage.outcome\": result.failure._tag })\n : Effect.void,\n ),\n Effect.tapError(annotateStorageError),\n span,\n Effect.flatMap(Effect.fromResult),\n ),\n );\n};\n","import { SqliteClient } from \"@effect/sql-sqlite-do\";\nimport {\n makeCanonicalStorage,\n recordBatchId,\n} from \"@yielded/agent-storage-sql/sql-canonical-storage\";\nimport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\nimport { makeSqlExecutions } from \"@yielded/agent-storage-sql/sql-journal\";\nimport {\n makeSqlLifecyclePublication,\n type SqlLifecycleRetainMany,\n SqlLifecycleSource,\n SqlLifecycleRetainer,\n} from \"@yielded/agent-storage-sql/sql-lifecycle-publication\";\nimport { SqlStorageProgress } from \"@yielded/agent-storage-sql/sql-storage-progress\";\nimport {\n canonicalRecordJson,\n makeSqlThreadArchiveRange,\n} from \"@yielded/agent-storage-sql/sql-thread-archive-range\";\nimport { makeSqlThreadWork } from \"@yielded/agent-storage-sql/sql-thread-work\";\nimport { ThreadId } from \"@yielded/agent/identifiers\";\nimport {\n LifecyclePublicationFact,\n LifecyclePublicationError,\n} from \"@yielded/agent/lifecycle-publication\";\nimport { BatchId, CanonicalRecord, CanonicalSequence } from \"@yielded/agent/records\";\nimport { SqlStorageOwner } from \"@yielded/agent/sql-memory-store\";\nimport {\n type AppendConflict,\n AppendResult,\n ThreadStoreDiagnostic,\n ThreadStoreError,\n} from \"@yielded/agent/thread-store\";\nimport {\n Cause,\n Clock,\n Context,\n Effect,\n Layer,\n Option,\n Predicate,\n References,\n Result,\n Schema,\n Stream,\n Tracer,\n} from \"effect\";\nimport * as SqlClient from \"effect/sql/SqlClient\";\nimport { classifySqliteError, SqlError } from \"effect/sql/SqlError\";\nimport { CurrentTransformer, type Statement } from \"effect/sql/Statement\";\n\nimport { DoStorageConfig } from \"../DoStorageConfig.ts\";\nimport {\n type DoStorageFailpointError,\n DoAppendConflict,\n DoCheckpointConflict,\n DoStorageCorruptionError,\n DoStorageError,\n DoValueBoundExceeded,\n type DoStorageFailpointLocation,\n} from \"../DoStorageError.ts\";\nimport { DoStorageFailpoint, isDefaultDoStorageFailpoint } from \"../DoStorageFailpoint.ts\";\nimport { ensureDoStorageLayout } from \"./migrations.ts\";\nimport { ownedState, ownedRows, type OwnedState } from \"./owned-state.ts\";\nimport {\n isAppendContention,\n annotateStorageError,\n storageResult,\n withStorageSpan,\n} from \"./storage-span.ts\";\n\n/**\n * Static schema ceiling for stored text columns. Writes are bounded in BYTES by the\n * configured `maxStoredValueBytes` (always ≤ 2,000,000); UTF-8 byte length is never smaller\n * than UTF-16 string length, so any value that passed the byte bound also passes this\n * decode-side character ceiling.\n */\nconst BoundedStoredText = Schema.String.check(Schema.isMaxLength(2_000_000));\nconst BoundedIdentifier = Schema.NonEmptyString.check(Schema.isMaxLength(1024));\nconst MAX_IDENTIFIER_LENGTH = 1_024;\nconst MAX_READ_PAGE_JSON_BYTES = 4 * 1024 * 1024;\n// A shared isolate budget permits multi-page hydration without multiplying its\n// retained payload by the number of resident Durable Object instances.\nconst MAX_RECORD_CACHE_JSON_BYTES = 8 * 1024 * 1024;\nconst MAX_RECORD_CACHE_ENTRIES = 4_096;\n/** Durable Object SQL storage allows at most 100 bound parameters per statement. */\nconst MAX_BOUND_PARAMETERS = 100;\nconst isSqlError = Schema.is(SqlError);\n\nconst isNativeClient = Schema.is(\n Schema.declare<SqliteClient.SqliteClient>((value): value is SqliteClient.SqliteClient =>\n Predicate.hasProperty(value, SqliteClient.TypeId),\n ),\n);\n\nconst storedTextBytes = (value: string): number => new TextEncoder().encode(value).byteLength;\n\nconst chunked = <A>(values: ReadonlyArray<A>, size: number): Array<ReadonlyArray<A>> => {\n const chunks: Array<ReadonlyArray<A>> = [];\n\n for (let index = 0; index < values.length; index += size) {\n chunks.push(values.slice(index, index + size));\n }\n\n return chunks;\n};\n\nclass ThreadRow extends Schema.Class<ThreadRow>(\"ThreadRow\")({\n thread_id: BoundedIdentifier,\n created_at: Schema.NullOr(Schema.NonEmptyString.check(Schema.isMaxLength(128))),\n tail_sequence: CanonicalSequence,\n}) {}\n\nconst threadRows = ownedRows(\n ThreadRow,\n \"effect_agent_threads\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nclass RecordRow extends Schema.Class<RecordRow>(\"RecordRow\")({\n batch_id: Schema.fromJsonString(BatchId.check(Schema.isMaxLength(MAX_IDENTIFIER_LENGTH))),\n thread_id: ThreadId.check(Schema.isMaxLength(MAX_IDENTIFIER_LENGTH)),\n record_id: Schema.fromJsonString(BoundedIdentifier),\n record_json: BoundedStoredText,\n sequence: CanonicalSequence,\n}) {}\n\ninterface RecordCacheEntry {\n readonly row: RecordRow;\n readonly bytes: number;\n readonly evict: () => void;\n}\n\n// Entries retain only their local row map, never a storage owner or incarnation.\nconst isolateRecords = new Map<RecordCacheEntry, true>();\nlet isolateRecordBytes = 0;\n\nconst releaseRecord = (entry: RecordCacheEntry) => {\n if (!isolateRecords.delete(entry)) return;\n isolateRecordBytes -= entry.bytes;\n entry.evict();\n};\n\nconst recordCaches = new WeakMap<OwnedState, ReturnType<typeof makeRecordCache>>();\n\nconst makeRecordCache = () => {\n const records = new Map<string, RecordCacheEntry>();\n const key = (thread: string, sequence: number) => JSON.stringify([thread, sequence]);\n\n return {\n clear: () => {\n for (const entry of records.values()) releaseRecord(entry);\n },\n get: (thread: string, sequence: number) => records.get(key(thread, sequence))?.row,\n prefix: (thread: string, through: number): ReadonlyArray<RecordRow> | undefined => {\n const prefix: Array<RecordRow> = [];\n\n for (let sequence = 1; sequence <= through; sequence++) {\n const row = records.get(key(thread, sequence));\n\n if (row === undefined) return undefined;\n prefix.push(row.row);\n }\n\n return prefix;\n },\n put: (row: RecordRow, capturedBytes?: number) => {\n const id = key(row.thread_id, row.sequence);\n const prior = records.get(id);\n\n if (prior?.row === row) return;\n const size = capturedBytes ?? storedTextBytes(row.record_json);\n\n if (prior !== undefined) releaseRecord(prior);\n\n const entry: RecordCacheEntry = {\n row,\n bytes: size,\n evict: () => records.delete(id),\n };\n\n records.set(id, entry);\n isolateRecords.set(entry, true);\n isolateRecordBytes += size;\n while (\n isolateRecordBytes > MAX_RECORD_CACHE_JSON_BYTES ||\n isolateRecords.size > MAX_RECORD_CACHE_ENTRIES\n ) {\n const oldest = isolateRecords.keys().next().value;\n\n if (oldest === undefined) break;\n releaseRecord(oldest);\n }\n },\n };\n};\n\nconst ReadPlanRow = Schema.Struct({\n sequence: CanonicalSequence,\n record_json_bytes: Schema.Natural.check(Schema.isLessThanOrEqualTo(MAX_READ_PAGE_JSON_BYTES)),\n});\n\ntype ReadPage = [typeof ReadPlanRow.Type, ...Array<typeof ReadPlanRow.Type>];\n\nclass CheckpointRow extends Schema.Class<CheckpointRow>(\"CheckpointRow\")({\n checkpoint_json: BoundedStoredText,\n thread_id: BoundedIdentifier,\n through_sequence: CanonicalSequence,\n}) {}\n\nconst LifecycleCursorRow = Schema.Struct({\n thread_id: BoundedIdentifier,\n through_sequence: CanonicalSequence,\n});\n\nconst lifecycleCursorRows = ownedRows(\n LifecycleCursorRow,\n \"effect_agent_lifecycle_cursors\",\n (row) => row.thread_id,\n \"thread_id\",\n);\n\nconst initializedLifecycleSources = new WeakSet<OwnedState>();\n\nexport type { RawAppendRequest } from \"@yielded/agent-storage-sql/sql-journal\";\n\nexport class RawReadRequest extends Schema.Class<RawReadRequest>(\n \"@effect-agent/storage-cloudflare/RawReadRequest\",\n)({\n threadId: BoundedIdentifier,\n fromSequenceExclusive: CanonicalSequence,\n limit: Schema.Int.check(Schema.isGreaterThan(0), Schema.isLessThanOrEqualTo(1_024)),\n}) {}\n\nexport class RawCheckpoint extends Schema.Class<RawCheckpoint>(\n \"@effect-agent/storage-cloudflare/RawCheckpoint\",\n)({\n checkpointJson: BoundedStoredText,\n threadId: BoundedIdentifier,\n throughSequence: CanonicalSequence,\n}) {}\n\ntype AppendError =\n | ThreadStoreError\n | DoAppendConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoStorageFailpointError\n | DoValueBoundExceeded;\n\ntype CheckpointError =\n | DoCheckpointConflict\n | DoStorageCorruptionError\n | DoStorageError\n | DoValueBoundExceeded;\n\ntype DoJournalFailpoint = (\n location: DoStorageFailpointLocation,\n) => Effect.Effect<void, DoStorageFailpointError>;\n\nconst noFailpoint: DoJournalFailpoint = () => Effect.void;\n\nconst storageError =\n (operation: string) =>\n (error: SqlError): DoStorageError =>\n DoStorageError.make({\n cause: error,\n operation,\n message: error.message,\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation,\n issueTag: error.reason._tag,\n }),\n });\n\n/** Decode raw Durable Object SQLite rows against a Schema, reporting failures as typed corruption. */\nexport const decodeRows = <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n decoder: string = table,\n): Effect.Effect<ReadonlyArray<A>, DoStorageCorruptionError> =>\n Schema.decodeUnknownEffect(schema)(rows).pipe(\n Effect.mapError((error) =>\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: \"Stored rows do not satisfy the storage schema\",\n diagnostic: ThreadStoreDiagnostic.make({\n causeTag: error._tag,\n operation: \"decode storage rows\",\n decoder,\n issueTag: error.issue._tag,\n }),\n }),\n ),\n Effect.tapError((error) =>\n Effect.annotateCurrentSpan({\n \"storage.failure.operation\": error.diagnostic?.operation,\n \"storage.failure.cause\": error.diagnostic?.causeTag,\n \"storage.failure.decoder\": decoder,\n \"storage.failure.issue\": error.diagnostic?.issueTag,\n }),\n ),\n );\n\n/** Decode exactly one raw row against a Schema, reporting failures as typed corruption. */\nexport const decodeSingleRow = <A, I>(\n schema: Schema.Codec<ReadonlyArray<A>, ReadonlyArray<I>>,\n table: string,\n rowKey: string,\n rows: unknown,\n): Effect.Effect<A, DoStorageCorruptionError> =>\n decodeRows(schema, table, rowKey, rows).pipe(\n Effect.flatMap((decoded) =>\n decoded.length === 1\n ? Effect.succeed(decoded[0])\n : Effect.fail(\n DoStorageCorruptionError.make({\n table,\n rowKey,\n message: `Expected exactly one row but found ${decoded.length}.`,\n }),\n ),\n ),\n );\n\n/** Open a validated layout and bind this Object's storage owner. */\nconst ensureCurrentStorage = Effect.fnUntraced(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint = noFailpoint,\n maxStoredValueBytes: number,\n) {\n const state = yield* ownedState(sql);\n const owner = (yield* SqlStorageOwner) ?? state;\n\n yield* ensureDoStorageLayout().pipe(\n Effect.provideService(SqlStorageOwner, owner),\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n let journal: DoJournal | undefined;\n\n const lifecycle = yield* makeSqlLifecyclePublication(undefined, maxStoredValueBytes).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n Effect.provideService(SqlLifecycleSource, {\n beforeRetain: (threadId) =>\n Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushCanonical(threadId),\n ),\n beforePending: Effect.suspend(() =>\n journal === undefined\n ? Effect.fail(LifecyclePublicationError.make({ reason: \"unavailable\" }))\n : journal.flushPublications(),\n ),\n }),\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle publication\",\n message: \"Native publication storage unavailable\",\n cause,\n }),\n ),\n );\n\n journal = yield* makeJournal(sql, failpoint, maxStoredValueBytes, lifecycle, state).pipe(\n Effect.provideService(SqlStorageOwner, owner),\n );\n if (lifecycle !== undefined) yield* journal.initializeLifecycleSource();\n\n return journal;\n});\n\nconst makeJournal = Effect.fnUntraced(function* (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n lifecycle: Effect.Success<ReturnType<typeof makeSqlLifecyclePublication>>,\n state: OwnedState,\n) {\n const owner = (yield* SqlStorageOwner) ?? state;\n const progress = yield* SqlStorageProgress;\n\n const nativeDb =\n isNativeClient(sql) &&\n sql.config.transformQueryNames === undefined &&\n sql.config.transformResultNames === undefined &&\n isDefaultDoStorageFailpoint(failpoint)\n ? sql.config.storage?.sql\n : undefined;\n\n const work = yield* makeSqlThreadWork({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"rebuild Thread work\",\n message: \"Thread work transaction failed\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n yield* Effect.acquireRelease(\n Effect.sync(() => state.invalidators.add(work.invalidate)),\n () => Effect.sync(() => state.invalidators.delete(work.invalidate)),\n );\n\n const workFailure = (cause: unknown) =>\n DoStorageError.make({\n operation: \"publish Thread work\",\n message: \"Canonical work metadata could not be published\",\n cause,\n });\n\n const executions = yield* makeSqlExecutions().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n const executionConflict = <A>(effect: Effect.Effect<A, AppendConflict | ThreadStoreError>) =>\n effect.pipe(\n Effect.catchTag(\"AppendConflict\", (error) =>\n Effect.fail(\n DoAppendConflict.make({\n reason: error.reason,\n message: \"Active execution conflicts with the captured commit\",\n ...(error.actualTailSequence === undefined\n ? {}\n : { actualTailSequence: error.actualTailSequence }),\n }),\n ),\n ),\n );\n\n const threads = threadRows(state, sql);\n const cursors = lifecycleCursorRows(state, sql);\n let records = recordCaches.get(state);\n\n if (records === undefined) {\n records = makeRecordCache();\n recordCaches.set(state, records);\n state.invalidators.add(records.clear);\n }\n const recordCache = records;\n\n const archives = yield* makeSqlThreadArchiveRange({\n read: (body) => state.read(body),\n write: (body) =>\n owner.transaction(body.pipe(Effect.tap(() => state.invalidate))).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.catchTag(\"SqlError\", (cause) =>\n ThreadStoreError.make({\n operation: \"archive write\",\n message: \"Archive transaction failed.\",\n cause,\n }),\n ),\n ),\n }).pipe(Effect.provideService(SqlClient.SqlClient, sql));\n\n const recordJson = canonicalRecordJson(sql);\n\n const physical = yield* makeCanonicalStorage().pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n );\n\n /** Typed pre-write refusal for any single value over the configured byte bound. */\n const checkValueBound = (\n operation: string,\n value: string,\n actualBytes = storedTextBytes(value),\n ): Effect.Effect<void, DoValueBoundExceeded> => {\n return actualBytes > maxStoredValueBytes\n ? Effect.fail(\n DoValueBoundExceeded.make({\n actualBytes,\n maxBytes: maxStoredValueBytes,\n operation,\n }),\n )\n : Effect.void;\n };\n\n /**\n * Runs one journal write transaction on the Durable Object storage-backed\n * `withTransaction` (`ctx.storage.transaction()` under the hood). Within one Durable\n * Object there is exactly ONE writer, so the Node `BEGIN IMMEDIATE` + busy-retry +\n * `SqliteWriteContention` machinery has no analogue here and is deliberately absent.\n * The shared local owner gate covers the transaction and acknowledgement.\n *\n * Journal write transactions are always top level: the Durable Object client rejects\n * nested transactions, so new journal operations must not wrap this helper inside another\n * transaction. Expected outcomes may be captured only when every such refusal precedes\n * mutation; real faults still roll back. Successful preflight reads never authorize a write.\n */\n const withWriteTransaction = (\n operation: string,\n expected?: (error: { readonly _tag: string }) => boolean,\n ) => {\n const transaction = <A, E extends { readonly _tag: string }>(\n effect: Effect.Effect<A, E>,\n ): Effect.Effect<A, E | DoStorageError> =>\n Effect.withFiber((fiber) => {\n const body = state.owner.withMutation(owner.transaction(effect)).pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((error) => (isSqlError(error) ? storageError(operation)(error) : error)),\n );\n\n const traced =\n fiber.getRef(References.TracerEnabled) &&\n fiber.getRef(Tracer.Tracer) !== Tracer.nativeTracer;\n\n return traced\n ? body.pipe(\n Effect.tapError(annotateStorageError),\n Effect.withSpan(\"DoJournal.withWriteTransaction\", { attributes: { operation } }),\n )\n : body;\n });\n\n return <A, E extends { readonly _tag: string }>(effect: Effect.Effect<A, E>) =>\n expected === undefined\n ? transaction(effect)\n : transaction(storageResult(effect, expected)).pipe(Effect.flatMap(Effect.fromResult));\n };\n\n const materialize = Effect.fnUntraced(function* (\n threadId: string,\n createdAt: string,\n ): Effect.fn.Return<void, DoStorageCorruptionError | DoStorageError | DoValueBoundExceeded> {\n if (threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"materialize thread\",\n message: \"Thread identity exceeds the Durable Object storage bounds.\",\n });\n }\n // Refusals and idempotent materialization need no transaction. Recheck before writes.\n const current = yield* getThread(threadId);\n\n if (current.length === 1) {\n return;\n }\n yield* withWriteTransaction(\"materialize transaction\")(\n Effect.gen(function* () {\n const existingRows = yield* getThread(threadId);\n\n const existing = yield* decodeRows(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n threadId,\n existingRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: threadId,\n message: \"A thread primary key returned more than one row.\",\n });\n }\n if (existing.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_threads (\n thread_id,\n created_at,\n tail_sequence\n ) VALUES (\n ${threadId},\n ${createdAt},\n 0\n ) ON CONFLICT(thread_id) DO UPDATE SET created_at=excluded.created_at\n WHERE effect_agent_threads.created_at IS NULL\n RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"materialize thread\")(error) : error,\n ),\n );\n\n if (lifecycle !== undefined)\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors (thread_id, through_sequence)\n VALUES (${threadId}, 0) RETURNING *`.pipe(\n cursors.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\"\n ? storageError(\"initialize lifecycle source\")(error)\n : error,\n ),\n );\n\n return;\n }\n }),\n );\n }, withStorageSpan(\"DoJournal.materialize\"));\n\n const getThread = Effect.fnUntraced(function* (threadId: string) {\n return (yield* threads\n .by(\"thread_id\", threadId)\n .pipe(\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"read thread\")(error) : error,\n ),\n )).filter((row) => row.thread_id === threadId && row.created_at !== null);\n });\n\n const hasRecord = Effect.fnUntraced(function* (threadId: string, recordId: string) {\n const thread = (yield* getThread(threadId))[0];\n const prefix = recordCache.prefix(threadId, thread?.tail_sequence ?? 0);\n\n if (prefix !== undefined) return prefix.some((row) => row.record_id === recordId);\n\n const rows = yield* sql`SELECT record_id FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND record_id = ${JSON.stringify(recordId)}`.pipe(\n Effect.mapError(storageError(\"read canonical record identity\")),\n );\n\n return rows.length > 0;\n });\n\n const prepareAppend = Effect.fnUntraced(function* (request: RawAppendRequest) {\n if (\n request.threadId.length > MAX_IDENTIFIER_LENGTH ||\n request.batchId.length > MAX_IDENTIFIER_LENGTH ||\n request.executionWrites.some(\n ({ update }) => update.checkpoint.progress.runId.length > MAX_IDENTIFIER_LENGTH,\n ) ||\n request.records.some((record) => record.recordId.length > MAX_IDENTIFIER_LENGTH)\n ) {\n return yield* DoStorageError.make({\n operation: \"append canonical batch\",\n message: \"Canonical identifiers exceed the Durable Object storage bounds.\",\n });\n }\n // Archives store the full batch as one value, so their ceiling also bounds hot appends.\n // The trusted append SPI pairs captured JSON with its exact UTF-8 width.\n yield* checkValueBound(\"append canonical batch\", request.batchJson, request.batchBytes);\n for (const record of request.records) {\n if (record.recordBytes > maxStoredValueBytes)\n return yield* DoValueBoundExceeded.make({\n actualBytes: record.recordBytes,\n maxBytes: maxStoredValueBytes,\n operation: \"append canonical record\",\n });\n }\n for (const write of request.executionWrites)\n yield* checkValueBound(\"commit active execution\", write.json, write.bytes);\n\n const recordIds: Array<string> = request.records.map((record) => record.recordId);\n\n if (new Set(recordIds).size !== recordIds.length) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} contains duplicate canonical record IDs.`,\n reason: \"record-identity\",\n });\n }\n\n return request;\n });\n\n // Replay and progress validation precede this body in the same owner transaction.\n // A miss makes no native change; the ordinary path reuses any tentative batch.\n // After advancing the frontier, failures must roll back rather than fall back.\n const appendNativeBody = Effect.fnUntraced(function* (\n request: RawAppendRequest,\n first: CanonicalSequence,\n last: CanonicalSequence,\n batchInserted: boolean,\n ) {\n const db = nativeDb;\n\n // Effectful statement transformers and exported SQL spans retain the ordinary path.\n const ordinaryStatement = yield* Effect.withFiber((fiber) =>\n Effect.succeed(\n fiber.getRef(CurrentTransformer) !== undefined ||\n (fiber.getRef(References.TracerEnabled) &&\n fiber.getRef(Tracer.Tracer) !== Tracer.nativeTracer),\n ),\n );\n\n if (ordinaryStatement) return false;\n if (\n db === undefined ||\n request.executionWrites.length !== 1 ||\n request.executionWrites[0]?.update.retire ||\n request.executionWrites[0]?.update.facts.length !== 0\n )\n return false;\n\n const workPlan = yield* work.prepareClosedPair(\n request.threadId,\n first,\n last,\n request.records.map((record) => record.canonical),\n );\n\n if (workPlan === undefined) return false;\n\n const native = yield* Effect.suspend(() => {\n const query = (statement: Statement<object>, operation: string) =>\n Result.try({\n try: () => {\n const [text, parameters] = statement.compile();\n\n return db.exec(text, ...parameters).toArray();\n },\n catch: (cause) =>\n storageError(operation)(\n SqlError.make({\n reason: classifySqliteError(cause, {\n operation,\n message: \"Native canonical statement failed\",\n }),\n }),\n ),\n });\n\n return Effect.fromResult(\n Result.gen(function* () {\n const captured = physical.cachedRecords(request.threadId, first, request.records);\n\n if (captured === undefined) return undefined;\n const physicalRecords = yield* captured;\n const rows = yield* query(workPlan.advance, \"advance native work frontier\");\n\n // A zero-row predicate miss has made no change. A successful update\n // must never fall back: every later refusal rolls back this transaction.\n if (rows.length === 0) return undefined;\n const executionPlans = executions.prepareCommit(request);\n\n if (!batchInserted)\n yield* query(\n sql`INSERT INTO effect_agent_canonical_batches\n (thread_id, batch_id, first_sequence, last_sequence, producer_id_json)\n VALUES (${request.threadId}, ${JSON.stringify(request.batchId)}, ${first}, ${last}, ${request.producerIdJson})`,\n \"insert canonical batch\",\n );\n\n const inserted = yield* query(\n sql`INSERT INTO effect_agent_canonical_records ${sql.insert(physicalRecords.map((row) => row.columns))}\n ON CONFLICT(thread_id, record_id) DO NOTHING RETURNING 1`,\n \"insert canonical records\",\n );\n\n if (inserted.length !== request.records.length)\n return yield* Result.fail(\n DoAppendConflict.make({\n message: \"A canonical record ID already exists.\",\n reason: \"record-identity\",\n }),\n );\n const memberships = physicalRecords.flatMap((row) => row.memberships);\n\n for (const group of chunked(memberships, Math.floor(MAX_BOUND_PARAMETERS / 3)))\n yield* query(\n sql`INSERT INTO effect_agent_record_runs ${sql.insert(group)}`,\n \"index canonical Run membership\",\n );\n for (const pointer of workPlan.pointers)\n yield* query(pointer, \"index canonical pointers\");\n\n for (const plan of executionPlans) {\n const changed = yield* query(plan.statement, \"commit active execution\");\n const accepted = plan.accept(changed);\n\n if (Result.isFailure(accepted))\n return yield* Result.fail(\n DoAppendConflict.make({\n reason: accepted.failure.reason,\n message: \"Active execution conflicts with the captured commit\",\n ...(accepted.failure.actualTailSequence === undefined\n ? {}\n : { actualTailSequence: accepted.failure.actualTailSequence }),\n }),\n );\n }\n for (let index = 0; index < request.records.length; index++) {\n const record = request.records[index]!;\n\n recordCache.put(\n RecordRow.make({\n ...physicalRecords[index]!.columns,\n thread_id: request.threadId,\n record_id: record.recordId,\n batch_id: request.batchId,\n record_json: record.recordJson,\n sequence: CanonicalSequence.make(first + index),\n }),\n record.recordBytes,\n );\n }\n\n return rows;\n }),\n );\n });\n\n if (native === undefined) return false;\n yield* threads.write(Effect.succeed(native));\n\n return true;\n });\n\n const appendPrepared = Effect.fnUntraced(function* (\n request: RawAppendRequest,\n ): Effect.fn.Return<AppendResult, AppendError> {\n const threadRows = yield* getThread(request.threadId);\n\n const thread = threadRows.length === 1 ? threadRows[0] : undefined;\n\n if (thread === undefined)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_threads\",\n rowKey: request.threadId,\n message: `Expected exactly one row but found ${threadRows.length}.`,\n });\n\n // A fresh canonical batch key and absence of an active receipt prove the two\n // negative replay lookups in the same statement that retains the batch header.\n // Keep the read-first path for stale/overflowed coordinates so exact retries\n // still precede sequence and tail refusals.\n const canInsert =\n request.records.length > 0 &&\n request.expectedTailSequence === thread.tail_sequence &&\n Number.isSafeInteger(thread.tail_sequence + request.records.length);\n\n const inserted = canInsert\n ? yield* sql`INSERT INTO effect_agent_canonical_batches\n (thread_id, batch_id, first_sequence, last_sequence, producer_id_json)\n SELECT ${request.threadId}, ${JSON.stringify(request.batchId)},\n ${thread.tail_sequence + 1}, ${thread.tail_sequence + request.records.length},\n ${request.producerIdJson}\n WHERE NOT EXISTS (\n SELECT 1 FROM effect_agent_executions\n WHERE thread_id=${request.threadId} AND last_commit_id=${request.batchId}\n )\n ON CONFLICT(thread_id, batch_id) DO NOTHING RETURNING 1`.pipe(\n Effect.mapError(storageError(\"insert canonical batch\")),\n )\n : [];\n\n if (inserted.length === 0) {\n const replay = yield* executionConflict(executions.replay(request));\n\n if (replay !== undefined) return AppendResult.make(replay);\n\n const prefix = recordCache.prefix(request.threadId, thread.tail_sequence);\n\n const existing =\n prefix !== undefined && !prefix.some((row) => row.batch_id === request.batchId)\n ? undefined\n : yield* archives.replay(request.threadId, request.batchId);\n\n if (existing !== undefined) {\n if (existing.batch_json !== request.batchJson) {\n return yield* DoAppendConflict.make({\n message: `Batch ${request.batchId} already exists with different canonical content.`,\n reason: \"batch-content\",\n });\n }\n\n return AppendResult.make({\n firstSequence: existing.first_sequence,\n lastSequence: existing.last_sequence,\n replayed: true,\n });\n }\n if (canInsert)\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_batches\",\n rowKey: request.threadId,\n message: \"Batch insertion conflicted without a durable replay receipt.\",\n });\n }\n\n yield* executionConflict(executions.rejectSuperseded(request));\n\n if (request.expectedTailSequence !== thread.tail_sequence) {\n return yield* DoAppendConflict.make({\n message:\n `Expected tail ${request.expectedTailSequence} ` + `but found ${thread.tail_sequence}.`,\n reason: \"tail\",\n actualTailSequence: thread.tail_sequence,\n });\n }\n\n const result = yield* Schema.decodeEffect(AppendResult)({\n firstSequence: thread.tail_sequence + (request.records.length === 0 ? 0 : 1),\n lastSequence: thread.tail_sequence + request.records.length,\n replayed: false,\n }).pipe(\n Effect.mapError((error) =>\n DoStorageError.make({\n cause: error,\n operation: \"append canonical batch\",\n message: error.message,\n }),\n ),\n );\n\n const { firstSequence, lastSequence } = result;\n\n yield* executionConflict(executions.validate(request));\n\n if (yield* appendNativeBody(request, firstSequence, lastSequence, inserted.length > 0)) {\n yield* progress.committed(\"canonical\").pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) =>\n DoStorageError.make({\n operation: \"enroll canonical progress\",\n message: error.message,\n cause: error,\n }),\n ),\n ),\n ),\n );\n\n return result;\n }\n\n if (request.records.length > 0 && inserted.length === 0) {\n yield* sql`\n INSERT INTO effect_agent_canonical_batches (\n thread_id,\n batch_id,\n first_sequence,\n last_sequence,\n producer_id_json\n ) VALUES (\n ${request.threadId},\n ${JSON.stringify(request.batchId)},\n ${firstSequence},\n ${lastSequence},\n ${request.producerIdJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert canonical batch\")));\n }\n yield* failpoint(\"append:after-batch-insert\");\n\n const physicalRecords = yield* physical.records(\n request.threadId,\n firstSequence,\n request.records,\n );\n\n const records = physicalRecords.map(({ columns, memberships }, index) => ({\n record: request.records[index]!,\n canonical: request.records[index]!.canonical,\n row: columns,\n memberships,\n }));\n\n // Captured scalar locators avoid parsing canonical JSON under the writer.\n // Eighteen bound columns per row stay within workerd's statement limit.\n for (const group of chunked(records, Math.floor(MAX_BOUND_PARAMETERS / 18))) {\n const inserted =\n yield* sql`INSERT INTO effect_agent_canonical_records ${sql.insert(group.map(({ row }) => row))}\n ON CONFLICT(thread_id, record_id) DO NOTHING RETURNING 1`.pipe(\n Effect.mapError(storageError(\"insert canonical records\")),\n );\n\n if (inserted.length !== group.length)\n return yield* DoAppendConflict.make({\n message: \"A canonical record ID already exists.\",\n reason: \"record-identity\",\n });\n\n const memberships = group.flatMap(({ memberships }) => memberships);\n\n for (const members of chunked(memberships, Math.floor(MAX_BOUND_PARAMETERS / 3)))\n yield* sql`INSERT INTO effect_agent_record_runs ${sql.insert(members)}`.pipe(\n Effect.mapError(storageError(\"index canonical Run membership\")),\n );\n for (const { row, record } of group) {\n recordCache.put(\n RecordRow.make({\n ...row,\n thread_id: request.threadId,\n record_id: record.recordId,\n batch_id: request.batchId,\n record_json: record.recordJson,\n sequence: Schema.decodeSync(CanonicalSequence)(row.sequence),\n }),\n record.recordBytes,\n );\n yield* failpoint(\"append:after-record-insert\");\n }\n }\n\n if (request.records.length > 0) {\n const workFields = yield* work\n .apply(\n yield* Schema.decodeEffect(ThreadId)(request.threadId).pipe(Effect.mapError(workFailure)),\n firstSequence,\n request.records.map((record) => record.canonical),\n )\n .pipe(Effect.mapError(workFailure));\n\n yield* sql`UPDATE effect_agent_threads SET ${sql.update({ tail_sequence: lastSequence, ...workFields })}\n WHERE thread_id=${request.threadId} RETURNING *`.pipe(\n threads.write,\n Effect.mapError((error) =>\n error._tag === \"SqlError\" ? storageError(\"advance thread tail\")(error) : error,\n ),\n );\n }\n yield* executionConflict(executions.commit(request, result));\n if (request.executionWrites.length > 0) yield* failpoint(\"append:after-record-insert\");\n if (\n lifecycle !== undefined &&\n request.executionWrites.some(({ update }) =>\n update.facts.some(({ payload }) => payload._tag === \"RunStarted\"),\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n for (const { update } of request.executionWrites) {\n for (const fact of update.facts) {\n if (\n lifecycle !== undefined &&\n Schema.is(Schema.toType(LifecyclePublicationFact))(fact.payload)\n )\n yield* lifecycle\n .retain({\n id: JSON.stringify([request.threadId, \"record\", fact.recordId]),\n ownerThreadId: request.threadId,\n canonicalSequence: lastSequence,\n createdAt: fact.createdAt,\n fact: fact.payload,\n })\n .pipe(\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain operational lifecycle\",\n message: cause.message,\n cause,\n }),\n ),\n );\n }\n }\n yield* failpoint(\"append:after-tail-update\");\n\n // Retain one start prefix atomically with its canonical proof, before model/tool\n // execution. Later facts stay journal-backed until the settlement publication wave.\n if (\n lifecycle !== undefined &&\n records.some(\n ({ canonical: { payload } }) =>\n payload._tag === \"RunStarted\" || payload._tag === \"SubagentStarted\",\n )\n )\n yield* flushCanonical(request.threadId).pipe(\n Effect.provideService(SqlLifecycleRetainer, { retainMany: lifecycle.retainMany }),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"retain lifecycle start prefix\",\n message: \"Lifecycle start intent could not be retained\",\n cause,\n }),\n ),\n );\n\n yield* progress.committed(\"canonical\").pipe(\n Effect.catchCause((cause) =>\n Effect.failCause(\n Cause.map(cause, (error) =>\n DoStorageError.make({\n operation: \"enroll canonical progress\",\n message: error.message,\n cause: error,\n }),\n ),\n ),\n ),\n );\n\n return result;\n });\n\n const append = Effect.fnUntraced(\n function* (\n request: RawAppendRequest,\n observed: ThreadRow,\n ): Effect.fn.Return<AppendResult, AppendError> {\n yield* prepareAppend(request);\n // The facade already read this tail. Reject a known stale writer without opening a\n // transaction; a matching tail is still checked atomically below. Replays precede tail\n // conflicts, preserving retry identity even after the log has advanced.\n if (request.records.length > 0 && request.expectedTailSequence !== observed.tail_sequence) {\n const batches = yield* sql`\n SELECT batch_id FROM effect_agent_canonical_batches\n WHERE thread_id = ${request.threadId} AND batch_id = ${JSON.stringify(request.batchId)}\n UNION ALL SELECT last_commit_id FROM effect_agent_executions\n WHERE thread_id = ${request.threadId} AND last_commit_id = ${request.batchId}\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"preflight append replay\")));\n\n // A possible replay still checks exact content in the transaction.\n if (batches.length === 0) {\n return yield* DoAppendConflict.make({\n reason: \"tail\",\n message: \"The canonical tail has advanced.\",\n actualTailSequence: observed.tail_sequence,\n });\n }\n }\n\n // Receipt arbitration may have tentatively inserted a batch. Even typed\n // contention must roll back before leaving the owner mutation gate.\n return yield* withWriteTransaction(\"append transaction\")(appendPrepared(request));\n },\n withStorageSpan(\"DoJournal.append\", isAppendContention),\n );\n\n const read = Effect.fnUntraced(function* (request: RawReadRequest) {\n const thread = (yield* getThread(request.threadId))[0];\n\n const through = Math.min(\n thread?.tail_sequence ?? 0,\n request.fromSequenceExclusive + request.limit,\n );\n\n const cached: Array<RecordRow> = [];\n\n for (let sequence = request.fromSequenceExclusive + 1; sequence <= through; sequence++) {\n const record = recordCache.get(request.threadId, sequence);\n\n if (record === undefined) break;\n cached.push(record);\n }\n if (cached.length === Math.max(0, through - request.fromSequenceExclusive)) {\n return { count: cached.length, records: Stream.fromIterable(cached) };\n }\n\n // Capture membership without retaining payloads. Append-only sequences keep each later\n // payload query inside this snapshot, even when new records arrive during consumption.\n const planRows = yield* sql<Record<string, unknown>>`\n SELECT\n sequence,\n length(CAST(${recordJson} AS BLOB)) AS record_json_bytes\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence > ${request.fromSequenceExclusive}\n ORDER BY sequence\n LIMIT ${request.limit}\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const plan = yield* decodeRows(\n Schema.Array(ReadPlanRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}>${request.fromSequenceExclusive}`,\n planRows,\n \"ReadPlanRow\",\n );\n\n const mismatch = () =>\n DoStorageCorruptionError.make({\n table: \"effect_agent_canonical_records\",\n rowKey: `${request.threadId}>${request.fromSequenceExclusive}`,\n message: \"Canonical read membership, sequence, or payload size changed from its read plan.\",\n });\n\n if (plan.length > request.limit) return yield* mismatch();\n\n const pages: Array<ReadPage> = [];\n let page: ReadPage | undefined;\n let pageBytes = 0;\n let previousSequence = request.fromSequenceExclusive;\n\n for (const row of plan) {\n if (row.sequence !== previousSequence + 1) return yield* mismatch();\n previousSequence = row.sequence;\n if (page === undefined || pageBytes + row.record_json_bytes > MAX_READ_PAGE_JSON_BYTES) {\n page = [row];\n pages.push(page);\n pageBytes = row.record_json_bytes;\n } else {\n page.push(row);\n pageBytes += row.record_json_bytes;\n }\n }\n\n const readPage = Effect.fnUntraced(function* (page: ReadPage) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT thread_id, sequence, record_id, ${recordBatchId(sql)} AS batch_id, ${recordJson} AS record_json\n FROM effect_agent_canonical_records\n WHERE thread_id = ${request.threadId}\n AND sequence >= ${page[0].sequence}\n AND sequence <= ${page[page.length - 1].sequence}\n ORDER BY sequence\n `.pipe(Effect.mapError(storageError(\"read canonical records\")));\n\n const decoded = yield* decodeRows(\n Schema.Array(RecordRow),\n \"effect_agent_canonical_records\",\n `${request.threadId}/${page[0].sequence}`,\n rows,\n \"RecordRow\",\n );\n\n if (\n decoded.length !== page.length ||\n decoded.some(\n (row, index) =>\n row.thread_id !== request.threadId ||\n row.sequence !== page[index].sequence ||\n storedTextBytes(row.record_json) !== page[index].record_json_bytes,\n )\n ) {\n return yield* mismatch();\n }\n\n for (const row of decoded) recordCache.put(row);\n\n return decoded;\n });\n\n return {\n count: plan.length,\n records: Stream.fromIterable(pages).pipe(\n Stream.flatMap((page) => Stream.fromIterableEffect(state.read(readPage(page)))),\n ),\n };\n });\n\n const saveCheckpoint = Effect.fnUntraced(function* (\n checkpoint: RawCheckpoint,\n ): Effect.fn.Return<void, CheckpointError> {\n if (checkpoint.threadId.length > MAX_IDENTIFIER_LENGTH) {\n return yield* DoStorageError.make({\n operation: \"save checkpoint\",\n message: \"Checkpoint identity exceeds the Durable Object storage bounds.\",\n });\n }\n yield* checkValueBound(\"save checkpoint\", checkpoint.checkpointJson);\n yield* withWriteTransaction(\"checkpoint transaction\")(\n Effect.gen(function* () {\n const threadRows = yield* getThread(checkpoint.threadId);\n\n const thread = yield* decodeSingleRow(\n Schema.Array(ThreadRow),\n \"effect_agent_threads\",\n checkpoint.threadId,\n threadRows,\n );\n\n if (checkpoint.throughSequence > thread.tail_sequence) {\n return yield* DoCheckpointConflict.make({\n reason: \"ahead-of-tail\",\n message:\n `Checkpoint sequence ${checkpoint.throughSequence} is after canonical tail ` +\n `${thread.tail_sequence}.`,\n });\n }\n\n if (!(yield* isBatchBoundary(checkpoint.threadId, checkpoint.throughSequence))) {\n return yield* DoCheckpointConflict.make({\n reason: \"not-batch-boundary\",\n message: \"Checkpoint sequence is not the end of a complete canonical batch.\",\n });\n }\n\n const checkpointRows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${checkpoint.threadId}\n AND through_sequence = ${checkpoint.throughSequence}\n `.pipe(Effect.mapError(storageError(\"read idempotent checkpoint\")));\n\n const existing = yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n checkpointRows,\n );\n\n if (existing.length > 1) {\n return yield* DoStorageCorruptionError.make({\n table: \"effect_agent_checkpoints\",\n rowKey: `${checkpoint.threadId}/${checkpoint.throughSequence}`,\n message: \"A checkpoint primary key returned more than one row.\",\n });\n }\n if (existing.length === 1) {\n if (existing[0].checkpoint_json !== checkpoint.checkpointJson) {\n return yield* DoCheckpointConflict.make({\n reason: \"corrupt\",\n message: \"A different checkpoint already exists at this canonical sequence.\",\n });\n }\n\n return;\n }\n\n yield* sql`\n INSERT INTO effect_agent_checkpoints (\n thread_id,\n through_sequence,\n checkpoint_json\n ) VALUES (\n ${checkpoint.threadId},\n ${checkpoint.throughSequence},\n ${checkpoint.checkpointJson}\n )\n `.pipe(Effect.mapError(storageError(\"insert checkpoint\")));\n }),\n );\n });\n\n const loadCheckpoint = Effect.fnUntraced(function* (\n threadId: string,\n atOrBeforeSequence: CanonicalSequence,\n ) {\n const rows = yield* sql<Record<string, unknown>>`\n SELECT\n thread_id,\n through_sequence,\n checkpoint_json\n FROM effect_agent_checkpoints\n WHERE thread_id = ${threadId}\n AND through_sequence <= ${atOrBeforeSequence}\n ORDER BY through_sequence DESC\n LIMIT 1\n `.pipe(Effect.mapError(storageError(\"load checkpoint\")));\n\n return yield* decodeRows(\n Schema.Array(CheckpointRow),\n \"effect_agent_checkpoints\",\n `${threadId}<=${atOrBeforeSequence}`,\n rows,\n );\n });\n\n const isBatchBoundary = Effect.fnUntraced(function* (\n threadId: string,\n sequence: CanonicalSequence,\n ) {\n if (sequence === 0) return true;\n\n const rows = yield* sql<Record<string, unknown>>`\n SELECT last_sequence FROM effect_agent_canonical_batches\n WHERE thread_id = ${threadId}\n AND batch_id = (\n SELECT ${recordBatchId(sql)} FROM effect_agent_canonical_records\n WHERE thread_id = ${threadId} AND sequence = ${sequence}\n )\n AND last_sequence = ${sequence}\n `.pipe(Effect.mapError(storageError(\"read canonical batch boundary\")));\n\n const batches = yield* decodeRows(\n Schema.Array(Schema.Struct({ last_sequence: CanonicalSequence })),\n \"effect_agent_canonical_batches\",\n `${threadId}/${sequence}`,\n rows,\n );\n\n return batches.length === 1;\n });\n\n const sourceFailure = (cause: unknown) =>\n LifecyclePublicationError.make({ reason: \"unavailable\", cause });\n\n const sourceThreads = Effect.fnUntraced(function* () {\n const all = yield* threads.matching(\n \"lifecycle-owners\",\n (row) => row.created_at !== null,\n sql`SELECT * FROM effect_agent_threads WHERE created_at IS NOT NULL LIMIT 129`,\n 128,\n );\n\n if (all.length <= 128) return all;\n\n // Large custom hosts hydrate only owners whose journal has an unmaterialized suffix.\n return yield* Schema.decodeUnknownEffect(Schema.Array(ThreadRow))(\n yield* sql`SELECT t.* FROM effect_agent_threads t LEFT JOIN effect_agent_lifecycle_cursors c ON c.thread_id=t.thread_id\n WHERE t.created_at IS NOT NULL AND (c.thread_id IS NULL OR t.tail_sequence > c.through_sequence) ORDER BY t.thread_id LIMIT 128`,\n );\n });\n\n const initializeLifecycleSource = Effect.fnUntraced(function* () {\n if (initializedLifecycleSources.has(state)) return;\n yield* state\n .transaction(\n Effect.gen(function* () {\n const existing =\n yield* sql`SELECT name FROM sqlite_master WHERE name='effect_agent_lifecycle_cursors'`;\n\n if (existing.length === 0) {\n yield* sql`CREATE TABLE effect_agent_lifecycle_cursors (\n thread_id TEXT PRIMARY KEY, through_sequence INTEGER NOT NULL\n )`;\n // Existing inline writers already retained their facts. Enabling publication on an\n // old store starts here too; it does not publish historical facts retroactively.\n }\n // New Threads created with publication disabled have no cursor. Never advance\n // existing cursors: they can owe intent from an interrupted Attempt.\n yield* sql`INSERT INTO effect_agent_lifecycle_cursors(thread_id, through_sequence)\n SELECT thread_id, tail_sequence FROM effect_agent_threads WHERE created_at IS NOT NULL\n ON CONFLICT(thread_id) DO NOTHING`;\n yield* sourceThreads();\n }),\n )\n .pipe(\n Effect.provideService(SqlClient.SqlClient, sql),\n Effect.mapError((cause) =>\n DoStorageError.make({\n operation: \"initialize lifecycle source\",\n message: \"Lifecycle source cursor unavailable\",\n cause,\n }),\n ),\n );\n initializedLifecycleSources.add(state);\n });\n\n /** The journal is durable intent; only the bounded publication wave materializes a write set. */\n const flushCanonical = Effect.fnUntraced(function* (threadId: string, maxRecords = Infinity) {\n const { retainMany } = yield* SqlLifecycleRetainer;\n const thread = (yield* getThread(threadId))[0];\n\n if (thread === undefined) return;\n const cursor = (yield* cursors.by(\"thread_id\", threadId))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n let through = cursor.through_sequence;\n const bound = Math.min(thread.tail_sequence, through + maxRecords);\n\n while (through < bound) {\n const page = yield* read(\n RawReadRequest.make({\n threadId,\n fromSequenceExclusive: through,\n limit: Math.min(128, bound - through),\n }),\n );\n\n const facts: Array<Parameters<SqlLifecycleRetainMany>[0][number]> = [];\n let bytes = 0;\n\n yield* Stream.runForEach(page.records, (row) =>\n Effect.gen(function* () {\n const record = yield* Schema.decodeEffect(Schema.fromJsonString(CanonicalRecord))(\n row.record_json,\n );\n\n if (record.recordId !== row.record_id || row.sequence !== through + 1)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (Schema.is(Schema.toType(LifecyclePublicationFact))(record.payload)) {\n if (\n bytes + storedTextBytes(row.record_json) > MAX_READ_PAGE_JSON_BYTES &&\n facts.length > 0\n ) {\n yield* retainMany(facts);\n facts.length = 0;\n bytes = 0;\n }\n facts.push({\n id: JSON.stringify([threadId, \"record\", record.recordId]),\n ownerThreadId: yield* Schema.decodeEffect(ThreadId)(threadId),\n canonicalSequence: row.sequence,\n createdAt: record.createdAt,\n fact: record.payload,\n });\n bytes += storedTextBytes(row.record_json);\n }\n through = row.sequence;\n }),\n );\n if (page.count === 0) return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n yield* retainMany(facts);\n yield* sql`UPDATE effect_agent_lifecycle_cursors SET through_sequence=${through} WHERE thread_id=${threadId} RETURNING *`.pipe(\n cursors.write,\n );\n }\n }, Effect.mapError(sourceFailure));\n\n const flushPublications = Effect.fnUntraced(function* () {\n let owners = 0;\n\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor !== undefined && cursor.through_sequence === thread.tail_sequence) continue;\n yield* flushCanonical(thread.thread_id, 1024);\n if (++owners === 4) break;\n }\n }, Effect.mapError(sourceFailure));\n\n const sourcePending = Effect.gen(function* () {\n for (const thread of yield* sourceThreads()) {\n const cursor = (yield* cursors.by(\"thread_id\", thread.thread_id))[0];\n\n if (cursor === undefined || cursor.through_sequence > thread.tail_sequence)\n return yield* LifecyclePublicationError.make({ reason: \"corrupt\" });\n if (cursor.through_sequence < thread.tail_sequence) return true;\n }\n\n return false;\n }).pipe(Effect.mapError(sourceFailure));\n\n const ownedLifecycle =\n lifecycle === undefined\n ? undefined\n : {\n ...lifecycle,\n storage: {\n ...lifecycle.storage,\n retainedPendingDeadline: lifecycle.storage.pendingDeadline,\n pendingDeadline: state.read(\n Effect.gen(function* () {\n const deadline = yield* lifecycle.storage.pendingDeadline;\n\n if (!(yield* sourcePending)) return deadline;\n const now = yield* Clock.currentTimeMillis;\n\n return Option.some(Option.isSome(deadline) ? Math.min(now, deadline.value) : now);\n }),\n ),\n },\n };\n\n return {\n archives: archives.storage,\n archiveRanges: archives,\n work,\n state,\n owner,\n threads,\n lifecycle: ownedLifecycle,\n initializeLifecycleSource,\n flushCanonical,\n flushPublications,\n append,\n prepareAppend,\n appendPrepared,\n checkCommitIntent: (request: RawAppendRequest) =>\n executionConflict(executions.checkCommitIntent(request)),\n readExecution: executions.read,\n checkValueBound,\n getThread,\n hasRecord,\n isBatchBoundary,\n loadCheckpoint,\n materialize,\n read: (request: RawReadRequest) => state.read(read(request)),\n saveCheckpoint,\n withWriteTransaction,\n } as const;\n});\n\nexport type DoJournal = Effect.Success<ReturnType<typeof makeJournal>>;\n\nconst InitializedDoJournal = Context.Reference<DoJournal | undefined>(\n \"@effect-agent/storage-cloudflare/InitializedDoJournal\",\n { defaultValue: () => undefined },\n);\n\n/** Build once in the common owner, SQL, configuration, failpoint and lifecycle context. */\nexport const initializedDoJournalLayer = Layer.effect(InitializedDoJournal)(\n Effect.gen(function* () {\n const sql = yield* SqlClient.SqlClient;\n const config = yield* DoStorageConfig;\n const failpoint = yield* DoStorageFailpoint;\n\n return yield* ensureCurrentStorage(sql, failpoint.hit, config.maxStoredValueBytes);\n }),\n);\n\nexport const initializeDoJournal = (\n sql: SqlClient.SqlClient,\n failpoint: DoJournalFailpoint,\n maxStoredValueBytes: number,\n) =>\n Effect.filterOrElse(InitializedDoJournal, Predicate.isNotUndefined, () =>\n ensureCurrentStorage(sql, failpoint, maxStoredValueBytes),\n );\n"],"mappings":"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"}