@effect-agent/storage-cloudflare 0.1.0-beta.48 → 0.1.0-beta.50

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.
@@ -1 +1 @@
1
- {"version":3,"file":"DoSubscriptionStore.mjs","names":[],"sources":["../src/DoSubscriptionStore.ts"],"sourcesContent":["import { Digest } from \"@effect-agent/thread/Records\";\nimport { type SubscriptionFailpointError } from \"@effect-agent/thread/Subscription\";\nimport {\n AcceptedEvent,\n DeliveryChange,\n SourcePartition,\n SubscriptionDelivery,\n SubscriptionDeliveryKey,\n SubscriptionError,\n SubscriptionFailpoint,\n SubscriptionKey,\n SubscriptionLimits,\n SubscriptionName,\n SubscriptionRecord,\n SubscriptionScanCursors,\n SubscriptionStore,\n subscriptionDeliveryKeyString,\n} from \"@effect-agent/thread/Subscription\";\nimport {\n applySubscriptionDeliveryChange,\n sameAcceptedEventIdentity,\n sameSourcePartition,\n subscriptionCanSelect,\n subscriptionDeliveryCanSelect,\n} from \"@effect-agent/thread/SubscriptionTransition\";\nimport { Clock, Context, Effect, Layer, Result, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst CURRENT_SUBSCRIPTION_STORE_VERSION = 2;\nconst StoredJson = Schema.String.check(Schema.isMaxLength(1_900_000));\nconst CountRow = Schema.Struct({ count: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)) });\nconst SequenceRow = Schema.Struct({ sequence: Schema.Natural });\n\nconst ScanRow = Schema.Struct({\n event_scan_cursor: Schema.String,\n delivery_scan_cursor: Schema.String,\n recovery_scan_cursor: Schema.Natural,\n});\n\nconst JsonRow = Schema.Struct({ record_json: StoredJson });\n\nconst RegistrationRow = Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n ordinal: Schema.Natural,\n source_name: Schema.String,\n source_version: Schema.String,\n matching_key: Schema.String,\n state: SubscriptionRecord.fields.state,\n expires_at_millis: Schema.Number,\n recovery_at_millis: Schema.NullOr(Schema.Number),\n record_json: StoredJson,\n});\n\nconst EventRow = Schema.Struct({\n event_id: Schema.String,\n source_name: Schema.String,\n source_version: Schema.String,\n matching_key: Schema.String,\n payload_digest: Digest,\n cutoff: Schema.Natural,\n cursor: Schema.Natural,\n routing_complete: Schema.Number,\n next_attempt_at_millis: Schema.Number,\n record_json: StoredJson,\n});\n\nconst DeliveryRow = Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n event_id: Schema.String,\n delivery_key: Schema.String,\n state: SubscriptionDelivery.fields.state,\n next_attempt_at_millis: Schema.Number,\n record_json: StoredJson,\n});\n\nconst StoreStateRow = Schema.Struct({\n storage_version: Schema.Int,\n alarm_generation: Schema.Natural,\n});\n\nexport interface DoSubscriptionAlarmReplacement {\n readonly deadlineAtMillis: number | null;\n readonly generation: number;\n}\n\nexport type DoSubscriptionReplaceAlarm = (\n replacement: DoSubscriptionAlarmReplacement,\n) => Effect.Effect<void, SubscriptionError>;\n\n/** One Durable Object transaction combining subscription SQL and its single native alarm. */\nexport class DoSubscriptionTransaction extends Context.Service<\n DoSubscriptionTransaction,\n {\n readonly run: <A, E, R>(\n body: (replaceAlarm: DoSubscriptionReplaceAlarm) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SubscriptionError, R>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionTransaction\") {}\n\nexport class DoSubscriptionAlarmControl extends Context.Service<\n DoSubscriptionAlarmControl,\n {\n readonly prearm: (\n deadlineAtMillis: number,\n ) => Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n readonly reconcile: Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionAlarmControl\") {}\n\nconst error = (reason: SubscriptionError[\"reason\"], code: string) =>\n SubscriptionError.make({ reason, code });\n\nconst unavailable = (operation: string) => error(\"storage\", operation);\nconst corrupt = (operation: string) => error(\"corrupt\", operation);\nconst bytes = (value: unknown) => new TextEncoder().encode(JSON.stringify(value)).byteLength;\n\nconst validate = <A, I>(schema: Schema.Codec<A, I>, value: unknown, code: string) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => error(\"validation\", code)));\n\nconst encode = <A, I>(schema: Schema.Codec<A, I>, value: A, code: string) =>\n Schema.encodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => corrupt(code)),\n );\n\nconst decode = <A, I>(schema: Schema.Codec<A, I>, value: string, code: string) =>\n Schema.decodeEffect(Schema.fromJsonString(schema))(value).pipe(\n Effect.mapError(() => corrupt(code)),\n );\n\nconst decodeRows = <A, I>(schema: Schema.Codec<A, I>, rows: unknown, code: string) =>\n Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(Effect.mapError(() => corrupt(code)));\n\nconst sameDeliveryIdentity = (left: SubscriptionDelivery, right: SubscriptionDelivery): boolean =>\n subscriptionDeliveryKeyString(left.key) === subscriptionDeliveryKeyString(right.key) &&\n left.deliveryId === right.deliveryId &&\n left.source.name === right.source.name &&\n left.source.version === right.source.version &&\n left.threadId === right.threadId &&\n left.admissionKey === right.admissionKey &&\n left.subscriptionFingerprint === right.subscriptionFingerprint &&\n left.eventDigest === right.eventDigest;\n\nconst initializeDoSubscriptionStore = Effect.fn(\"DoSubscriptionStore.initialize\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n\n const names = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'effect_agent_subscription_%'\n `.pipe(Effect.mapError(() => unavailable(\"inspect subscription storage\")));\n\n const decodedNames = yield* decodeRows(\n Schema.Struct({ name: Schema.String }),\n names,\n \"inspect subscription storage\",\n );\n\n const expected = new Set([\n \"effect_agent_subscription_store_state\",\n \"effect_agent_subscription_sequences\",\n \"effect_agent_subscriptions\",\n \"effect_agent_subscription_events\",\n \"effect_agent_subscription_deliveries\",\n ]);\n\n const hasState = decodedNames.some(\n ({ name }) => name === \"effect_agent_subscription_store_state\",\n );\n\n if (!hasState && decodedNames.length > 0) return yield* corrupt(\"partial subscription storage\");\n if (!hasState) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`CREATE TABLE effect_agent_subscription_store_state (\n singleton INTEGER PRIMARY KEY NOT NULL CHECK(singleton=1), storage_version INTEGER NOT NULL, alarm_generation INTEGER NOT NULL\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_sequences (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, sequence INTEGER NOT NULL,\n event_scan_cursor TEXT NOT NULL, delivery_scan_cursor TEXT NOT NULL, recovery_scan_cursor INTEGER NOT NULL,\n PRIMARY KEY (tenant_id, source_address)\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscriptions (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n ordinal INTEGER NOT NULL, source_name TEXT NOT NULL, source_version TEXT NOT NULL, matching_key TEXT NOT NULL,\n state TEXT NOT NULL, expires_at_millis INTEGER NOT NULL, recovery_at_millis INTEGER, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id), UNIQUE (tenant_id, source_address, ordinal)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_owner ON effect_agent_subscriptions (tenant_id, source_address, owner_id, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_candidates ON effect_agent_subscriptions (tenant_id, source_address, source_name, source_version, matching_key, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_recovery ON effect_agent_subscriptions (tenant_id, source_address, recovery_at_millis, ordinal) WHERE recovery_at_millis IS NOT NULL`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_events (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, event_id TEXT NOT NULL, source_name TEXT NOT NULL,\n source_version TEXT NOT NULL, matching_key TEXT NOT NULL, payload_digest TEXT NOT NULL, cutoff INTEGER NOT NULL,\n cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, event_id)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_events_pending ON effect_agent_subscription_events (tenant_id, source_address, routing_complete, next_attempt_at_millis, event_id)`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_deliveries (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n event_id TEXT NOT NULL, delivery_key TEXT NOT NULL, state TEXT NOT NULL, next_attempt_at_millis INTEGER NOT NULL,\n record_json TEXT NOT NULL, PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id, event_id),\n UNIQUE (tenant_id, source_address, delivery_key)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_pending ON effect_agent_subscription_deliveries (tenant_id, source_address, state, next_attempt_at_millis, delivery_key)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`\n .withoutTransform;\n yield* sql`INSERT INTO effect_agent_subscription_store_state (singleton, storage_version, alarm_generation)\n VALUES (1, ${CURRENT_SUBSCRIPTION_STORE_VERSION}, 0)`.withoutTransform;\n }),\n )\n .pipe(Effect.mapError(() => unavailable(\"initialize subscription storage\")));\n\n return;\n }\n if (decodedNames.length !== expected.size || decodedNames.some(({ name }) => !expected.has(name)))\n return yield* corrupt(\"subscription storage tables\");\n\n const rows = yield* sql<\n Record<string, unknown>\n >`SELECT storage_version, alarm_generation FROM effect_agent_subscription_store_state WHERE singleton=1`.pipe(\n Effect.mapError(() => unavailable(\"read subscription storage version\")),\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"read subscription storage version\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\n state.length === 1\n ? `incompatible subscription storage version ${state[0].storage_version}; expected ${CURRENT_SUBSCRIPTION_STORE_VERSION}`\n : \"invalid subscription storage version row\",\n );\n});\n\nconst makeSubscriptionStore = Effect.fn(\"SqliteSubscriptionStore.make\")(function* (\n owned: SourcePartition,\n) {\n const partition = yield* validate(SourcePartition, owned, \"partition\");\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* SubscriptionFailpoint;\n const transactions = yield* DoSubscriptionTransaction;\n\n yield* initializeDoSubscriptionStore();\n yield* sql`\n INSERT INTO effect_agent_subscription_sequences (\n tenant_id, source_address, sequence, event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor\n ) VALUES (${partition.tenantId}, ${partition.address}, 0, '', '', 0) ON CONFLICT DO NOTHING\n `.pipe(Effect.mapError(() => unavailable(\"initialize subscription partition\")));\n\n const query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n code: string,\n ) => effect.pipe(Effect.mapError(() => unavailable(code)));\n\n const readIndexedDeadline = Effect.fn(\"DoSubscriptionStore.readIndexedDeadline\")(function* () {\n const scanRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor FROM effect_agent_subscription_sequences\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"read scan cursor deadline\",\n );\n\n const scans = yield* decodeRows(ScanRow, scanRows, \"read scan cursor deadline\");\n\n if (scans.length !== 1) return yield* corrupt(\"scan cursor deadline\");\n if (\n scans[0].event_scan_cursor !== \"\" ||\n scans[0].delivery_scan_cursor !== \"\" ||\n scans[0].recovery_scan_cursor !== 0\n )\n return 0;\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT MIN(deadline) AS deadline FROM (\n SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0\n UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state NOT IN ('delivered','refused')\n UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL\n )\n `,\n \"read subscription deadline\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({ deadline: Schema.NullOr(Schema.Number) }),\n rows,\n \"read subscription deadline\",\n );\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription deadline\");\n\n return decoded[0].deadline;\n });\n\n const replaceAlarm = Effect.fn(\"DoSubscriptionStore.replaceAlarm\")(function* (\n replace: DoSubscriptionReplaceAlarm,\n deadlineAtMillis: number | null,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_store_state SET alarm_generation=alarm_generation+1\n WHERE singleton=1 RETURNING storage_version, alarm_generation\n `,\n \"advance subscription alarm generation\",\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"advance subscription alarm generation\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\"subscription alarm state\");\n yield* failpoint.hit(\"subscription:alarm:before\");\n yield* replace({ deadlineAtMillis, generation: state[0].alarm_generation });\n yield* failpoint.hit(\"subscription:alarm:after\");\n });\n\n const transact = <A>(effect: Effect.Effect<A, SubscriptionError | SubscriptionFailpointError>) =>\n transactions.run((replace) =>\n Effect.gen(function* () {\n const value = yield* effect;\n\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n\n return value;\n }),\n );\n\n const requirePartition = (candidate: SourcePartition, code: string) =>\n sameSourcePartition(candidate, partition)\n ? Effect.void\n : Effect.fail(error(\"validation\", code));\n\n const requireKey = Effect.fn(\"SqliteSubscriptionStore.requireKey\")(function* (\n input: SubscriptionKey,\n code: string,\n ) {\n const key = yield* validate(SubscriptionKey, input, code);\n\n yield* requirePartition(key.partition, code);\n\n return key;\n });\n\n const readRegistration = Effect.fn(\"SqliteSubscriptionStore.readRegistration\")(function* (\n key: SubscriptionKey,\n code: string,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, ordinal, source_name, source_version, matching_key, state,\n expires_at_millis, recovery_at_millis, record_json FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${key.ownerId} AND subscription_id=${key.subscriptionId}\n `,\n code,\n );\n\n const decodedRows = yield* decodeRows(RegistrationRow, rows, code);\n\n if (decodedRows.length > 1) return yield* corrupt(code);\n const row = decodedRows[0];\n\n if (row === undefined) return null;\n const record = yield* decode(SubscriptionRecord, row.record_json, code);\n\n if (\n !sameSourcePartition(record.key.partition, partition) ||\n record.key.ownerId !== row.owner_id ||\n record.key.subscriptionId !== row.subscription_id ||\n record.ordinal !== row.ordinal ||\n record.configuration.source.name !== row.source_name ||\n record.configuration.source.version !== row.source_version ||\n record.configuration.matchingKey !== row.matching_key ||\n record.state !== row.state ||\n record.configuration.expiresAtMillis !== row.expires_at_millis ||\n (record.recovery?.nextAttemptAtMillis ?? null) !== row.recovery_at_millis\n )\n return yield* corrupt(`${code}-projection`);\n\n return record;\n });\n\n const readEvent = Effect.fn(\"SqliteSubscriptionStore.readEvent\")(function* (\n eventId: string,\n code: string,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_id, source_name, source_version, matching_key, payload_digest, cutoff, cursor,\n routing_complete, next_attempt_at_millis, record_json FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND event_id=${eventId}\n `,\n code,\n );\n\n const decodedRows = yield* decodeRows(EventRow, rows, code);\n\n if (decodedRows.length > 1) return yield* corrupt(code);\n const row = decodedRows[0];\n\n if (row === undefined) return null;\n const event = yield* decode(AcceptedEvent, row.record_json, code);\n\n if (\n !sameSourcePartition(event.partition, partition) ||\n event.eventId !== row.event_id ||\n event.source.name !== row.source_name ||\n event.source.version !== row.source_version ||\n event.matchingKey !== row.matching_key ||\n event.payloadDigest !== row.payload_digest ||\n event.cutoff !== row.cutoff ||\n event.cursor !== row.cursor ||\n (event.routingComplete ? 1 : 0) !== row.routing_complete ||\n event.nextAttemptAtMillis !== row.next_attempt_at_millis\n )\n return yield* corrupt(`${code}-projection`);\n\n return event;\n });\n\n const readDelivery = Effect.fn(\"SqliteSubscriptionStore.readDelivery\")(function* (\n key: SubscriptionDeliveryKey,\n code: string,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, event_id, delivery_key, state, next_attempt_at_millis, record_json\n FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${key.subscription.ownerId} AND subscription_id=${key.subscription.subscriptionId}\n AND event_id=${key.eventId}\n `,\n code,\n );\n\n const decodedRows = yield* decodeRows(DeliveryRow, rows, code);\n\n if (decodedRows.length > 1) return yield* corrupt(code);\n const row = decodedRows[0];\n\n if (row === undefined) return null;\n const delivery = yield* decode(SubscriptionDelivery, row.record_json, code);\n\n if (\n !sameSourcePartition(delivery.key.subscription.partition, partition) ||\n delivery.key.subscription.ownerId !== row.owner_id ||\n delivery.key.subscription.subscriptionId !== row.subscription_id ||\n delivery.key.eventId !== row.event_id ||\n subscriptionDeliveryKeyString(delivery.key) !== row.delivery_key ||\n delivery.state !== row.state ||\n delivery.retry.nextAttemptAtMillis !== row.next_attempt_at_millis\n )\n return yield* corrupt(`${code}-projection`);\n\n return delivery;\n });\n\n const count = Effect.fn(\"SqliteSubscriptionStore.count\")(function* (\n statement: Effect.Effect<ReadonlyArray<Record<string, unknown>>, SqlError>,\n code: string,\n ) {\n const rows = yield* query(statement, code);\n const decoded = yield* decodeRows(CountRow, rows, code);\n\n if (decoded.length !== 1) return yield* corrupt(code);\n\n return decoded[0].count;\n });\n\n const nextSequence = Effect.fn(\"SqliteSubscriptionStore.nextSequence\")(function* () {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_sequences SET sequence=sequence+1\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n RETURNING sequence\n `,\n \"advance subscription sequence\",\n );\n\n const decoded = yield* decodeRows(SequenceRow, rows, \"advance subscription sequence\");\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription sequence\");\n\n return decoded[0].sequence;\n });\n\n const writeRegistration = Effect.fn(\"SqliteSubscriptionStore.writeRegistration\")(function* (\n record: SubscriptionRecord,\n ) {\n const json = yield* encode(SubscriptionRecord, record, \"encode subscription\");\n\n yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscriptions SET state=${record.state}, expires_at_millis=${record.configuration.expiresAtMillis},\n recovery_at_millis=${record.recovery?.nextAttemptAtMillis ?? null}, record_json=${json}\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${record.key.ownerId} AND subscription_id=${record.key.subscriptionId}\n `,\n \"write subscription\",\n );\n });\n\n const writeEvent = Effect.fn(\"SqliteSubscriptionStore.writeEvent\")(function* (\n event: AcceptedEvent,\n ) {\n const json = yield* encode(AcceptedEvent, event, \"encode event\");\n\n yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_events SET cursor=${event.cursor}, routing_complete=${event.routingComplete ? 1 : 0},\n next_attempt_at_millis=${event.nextAttemptAtMillis}, record_json=${json}\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND event_id=${event.eventId}\n `,\n \"write event\",\n );\n });\n\n const writeDelivery = Effect.fn(\"SqliteSubscriptionStore.writeDelivery\")(function* (\n delivery: SubscriptionDelivery,\n ) {\n const json = yield* encode(SubscriptionDelivery, delivery, \"encode delivery\");\n\n yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_deliveries SET state=${delivery.state},\n next_attempt_at_millis=${delivery.retry.nextAttemptAtMillis}, record_json=${json}\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${delivery.key.subscription.ownerId} AND subscription_id=${delivery.key.subscription.subscriptionId}\n AND event_id=${delivery.key.eventId}\n `,\n \"write delivery\",\n );\n });\n\n const register: SubscriptionStore[\"Service\"][\"register\"] = Effect.fn(\n \"SqliteSubscriptionStore.register\",\n )(function* (input, inputLimits) {\n const record = yield* validate(SubscriptionRecord, input, \"register-record\");\n const limits = yield* validate(SubscriptionLimits, inputLimits, \"register-limits\");\n\n yield* requirePartition(record.key.partition, \"register-partition\");\n\n const result = yield* transact(\n Effect.gen(function* () {\n const existing = yield* readRegistration(record.key, \"register-existing\");\n\n if (existing !== null) {\n if (existing.creationFingerprint !== record.creationFingerprint)\n return yield* error(\"conflict\", \"registration-identity\");\n\n return { value: existing, changed: false } as const;\n }\n if (bytes(record.configuration.context) > limits.maxContextBytes)\n return yield* error(\"capacity\", \"context-bytes\");\n if (bytes(record.configuration.parameters) > limits.maxPayloadBytes)\n return yield* error(\"capacity\", \"parameters-bytes\");\n if (\n record.configuration.expiresAtMillis - record.createdAtMillis >\n limits.maxLifetimeMillis\n )\n return yield* error(\"capacity\", \"lifetime\");\n if (\n (yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscriptions WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}`,\n \"count registrations\",\n )) >= limits.maxRegistrations\n )\n return yield* error(\"capacity\", \"registrations\");\n if (\n (yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscriptions WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND owner_id=${record.key.ownerId}`,\n \"count owner registrations\",\n )) >= limits.maxRegistrationsPerOwner\n )\n return yield* error(\"capacity\", \"owner-registrations\");\n const assigned = { ...record, ordinal: yield* nextSequence() };\n const json = yield* encode(SubscriptionRecord, assigned, \"encode registration\");\n\n yield* failpoint.hit(\"subscription:register:before\");\n yield* query(\n sql<Record<string, unknown>>`\n INSERT INTO effect_agent_subscriptions (tenant_id, source_address, owner_id, subscription_id, ordinal,\n source_name, source_version, matching_key, state, expires_at_millis, recovery_at_millis, record_json)\n VALUES (${partition.tenantId}, ${partition.address}, ${assigned.key.ownerId}, ${assigned.key.subscriptionId}, ${assigned.ordinal},\n ${assigned.configuration.source.name}, ${assigned.configuration.source.version}, ${assigned.configuration.matchingKey}, ${assigned.state},\n ${assigned.configuration.expiresAtMillis}, ${assigned.recovery?.nextAttemptAtMillis ?? null}, ${json})\n `,\n \"insert registration\",\n );\n\n return { value: assigned, changed: true } as const;\n }),\n );\n\n if (result.changed) yield* failpoint.hit(\"subscription:register:after\");\n\n return result.value;\n });\n\n const get: SubscriptionStore[\"Service\"][\"get\"] = Effect.fn(\"SqliteSubscriptionStore.get\")(\n function* (input) {\n return yield* readRegistration(yield* requireKey(input, \"get-key\"), \"get subscription\");\n },\n );\n\n const list: SubscriptionStore[\"Service\"][\"list\"] = Effect.fn(\"SqliteSubscriptionStore.list\")(\n function* (ownerId, after, limit) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, ordinal FROM effect_agent_subscriptions WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${ownerId} AND ordinal>${after} ORDER BY ordinal LIMIT ${limit}\n `,\n \"list subscriptions\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n ordinal: Schema.Natural,\n }),\n rows,\n \"list subscriptions\",\n );\n\n return yield* Effect.forEach(\n decoded,\n Effect.fn(\"SqliteSubscriptionStore.listRecord\")(function* (row) {\n const record = yield* readRegistration(\n { partition, ownerId: row.owner_id, subscriptionId: row.subscription_id },\n \"list subscription\",\n );\n\n if (record === null || record.ordinal !== row.ordinal)\n return yield* corrupt(\"list subscription projection\");\n\n return record;\n }),\n );\n },\n );\n\n const cancel: SubscriptionStore[\"Service\"][\"cancel\"] = Effect.fn(\n \"SqliteSubscriptionStore.cancel\",\n )(function* (input) {\n const key = yield* requireKey(input, \"cancel-key\");\n\n const result = yield* transact(\n Effect.gen(function* () {\n const current = yield* readRegistration(key, \"cancel subscription\");\n\n if (current === null) return yield* error(\"not-found\", \"subscription\");\n if (current.state === \"cancelled\") return { value: current, changed: false } as const;\n const updated = { ...current, state: \"cancelled\" as const, recovery: null };\n\n yield* failpoint.hit(\"subscription:cancel:before\");\n yield* writeRegistration(updated);\n\n return { value: updated, changed: true } as const;\n }),\n );\n\n if (result.changed) yield* failpoint.hit(\"subscription:cancel:after\");\n\n return result.value;\n });\n\n const accept: SubscriptionStore[\"Service\"][\"accept\"] = Effect.fn(\n \"SqliteSubscriptionStore.accept\",\n )(function* (input, inputLimits) {\n const event = yield* validate(AcceptedEvent, input, \"accept-event\");\n const limits = yield* validate(SubscriptionLimits, inputLimits, \"accept-limits\");\n\n yield* requirePartition(event.partition, \"accept-partition\");\n\n const result = yield* transact(\n Effect.gen(function* () {\n const existing = yield* readEvent(event.eventId, \"accept event\");\n\n if (existing !== null) {\n if (!sameAcceptedEventIdentity(existing, event))\n return yield* error(\"conflict\", \"event-identity\");\n\n return { value: existing, changed: false } as const;\n }\n if (bytes(event.payload) > limits.maxPayloadBytes)\n return yield* error(\"capacity\", \"payload-bytes\");\n if (\n (yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscription_events WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}`,\n \"count events\",\n )) >= limits.maxEvents\n )\n return yield* error(\"capacity\", \"events\");\n\n const accepted: AcceptedEvent = {\n ...event,\n cutoff: yield* nextSequence(),\n cursor: 0,\n routingComplete: false,\n routingFailure: null,\n };\n\n const json = yield* encode(AcceptedEvent, accepted, \"encode accepted event\");\n\n yield* failpoint.hit(\"subscription:accept:before\");\n yield* query(\n sql<Record<string, unknown>>`\n INSERT INTO effect_agent_subscription_events (tenant_id, source_address, event_id, source_name, source_version,\n matching_key, payload_digest, cutoff, cursor, routing_complete, next_attempt_at_millis, record_json)\n VALUES (${partition.tenantId}, ${partition.address}, ${accepted.eventId}, ${accepted.source.name}, ${accepted.source.version},\n ${accepted.matchingKey}, ${accepted.payloadDigest}, ${accepted.cutoff}, ${accepted.cursor}, 0, ${accepted.nextAttemptAtMillis}, ${json})\n `,\n \"insert event\",\n );\n\n return { value: accepted, changed: true } as const;\n }),\n );\n\n if (result.changed) yield* failpoint.hit(\"subscription:accept:after\");\n\n return result.value;\n });\n\n const event: SubscriptionStore[\"Service\"][\"event\"] = Effect.fn(\"SqliteSubscriptionStore.event\")(\n (eventId) => readEvent(eventId, \"get event\"),\n );\n\n const pendingEvents: SubscriptionStore[\"Service\"][\"pendingEvents\"] = Effect.fn(\n \"SqliteSubscriptionStore.pendingEvents\",\n )(function* (nowMillis, after, limit) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_id FROM effect_agent_subscription_events WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND routing_complete=0 AND next_attempt_at_millis<=${nowMillis} AND event_id>${after} ORDER BY event_id LIMIT ${limit}\n `,\n \"pending events\",\n );\n\n return yield* decodeRows(\n Schema.Struct({ event_id: Schema.String }),\n rows,\n \"pending event keys\",\n ).pipe(Effect.map((items) => items.map((item) => item.event_id)));\n });\n\n const candidates: SubscriptionStore[\"Service\"][\"candidates\"] = Effect.fn(\n \"SqliteSubscriptionStore.candidates\",\n )(function* (input, limit) {\n const supplied = yield* validate(AcceptedEvent, input, \"candidates-event\");\n\n yield* requirePartition(supplied.partition, \"candidates-partition\");\n const stored = yield* readEvent(supplied.eventId, \"candidates event\");\n\n if (stored === null) return yield* error(\"not-found\", \"event\");\n if (!sameAcceptedEventIdentity(stored, supplied)) return yield* error(\"conflict\", \"event\");\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, ordinal FROM effect_agent_subscriptions WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND source_name=${stored.source.name} AND source_version=${stored.source.version} AND matching_key=${stored.matchingKey}\n AND ordinal>${stored.cursor} AND ordinal<=${stored.cutoff} ORDER BY ordinal LIMIT ${limit}\n `,\n \"subscription candidates\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n ordinal: Schema.Natural,\n }),\n rows,\n \"subscription candidates\",\n );\n\n return yield* Effect.forEach(\n decoded,\n Effect.fn(\"SqliteSubscriptionStore.candidateRecord\")(function* (row) {\n const record = yield* readRegistration(\n { partition, ownerId: row.owner_id, subscriptionId: row.subscription_id },\n \"subscription candidate\",\n );\n\n if (record === null || record.ordinal !== row.ordinal)\n return yield* corrupt(\"subscription candidate projection\");\n\n return record;\n }),\n );\n });\n\n const insertDelivery = Effect.fn(\"SqliteSubscriptionStore.insertDelivery\")(function* (\n delivery: SubscriptionDelivery,\n ) {\n const json = yield* encode(SubscriptionDelivery, delivery, \"encode selected delivery\");\n\n yield* query(\n sql<Record<string, unknown>>`\n INSERT INTO effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, event_id,\n delivery_key, state, next_attempt_at_millis, record_json)\n VALUES (${partition.tenantId}, ${partition.address}, ${delivery.key.subscription.ownerId}, ${delivery.key.subscription.subscriptionId},\n ${delivery.key.eventId}, ${subscriptionDeliveryKeyString(delivery.key)}, ${delivery.state}, ${delivery.retry.nextAttemptAtMillis}, ${json})\n `,\n \"insert delivery\",\n );\n });\n\n const select: SubscriptionStore[\"Service\"][\"select\"] = Effect.fn(\n \"SqliteSubscriptionStore.select\",\n )(function* (inputEvent, inputDeliveries, cursor, complete, nowMillis, inputLimits) {\n const supplied = yield* validate(AcceptedEvent, inputEvent, \"select-event\");\n\n const deliveries = yield* validate(\n Schema.Array(SubscriptionDelivery),\n inputDeliveries,\n \"select-deliveries\",\n );\n\n const limits = yield* validate(SubscriptionLimits, inputLimits, \"select-limits\");\n\n yield* requirePartition(supplied.partition, \"select-partition\");\n for (const candidate of deliveries)\n yield* requirePartition(candidate.key.subscription.partition, \"select-delivery-partition\");\n\n const changed = yield* transact(\n Effect.gen(function* () {\n const accepted = yield* readEvent(supplied.eventId, \"select event\");\n\n if (accepted === null) return yield* error(\"not-found\", \"event\");\n if (!sameAcceptedEventIdentity(accepted, supplied) || accepted.cursor !== supplied.cursor)\n return yield* error(\"conflict\", \"event-cursor\");\n if (accepted.routingComplete) return false;\n if (!Number.isSafeInteger(cursor) || cursor < accepted.cursor || cursor > accepted.cutoff)\n return yield* error(\"validation\", \"cursor\");\n yield* failpoint.hit(\"subscription:select:before\");\n const effectiveNowMillis = Math.max(nowMillis, yield* Clock.currentTimeMillis);\n const additions: Array<{ delivery: SubscriptionDelivery; record: SubscriptionRecord }> = [];\n\n for (const delivery of deliveries) {\n const record = yield* readRegistration(delivery.key.subscription, \"select registration\");\n\n if (record === null) return yield* error(\"not-found\", \"subscription\");\n if (\n !subscriptionDeliveryCanSelect(delivery, record, accepted) ||\n delivery.key.eventId !== accepted.eventId ||\n delivery.source.name !== accepted.source.name ||\n delivery.source.version !== accepted.source.version ||\n record.ordinal <= accepted.cursor ||\n record.ordinal > cursor\n )\n return yield* error(\"conflict\", \"selection\");\n const existing = yield* readDelivery(delivery.key, \"select existing delivery\");\n\n if (existing !== null) {\n if (!sameDeliveryIdentity(existing, delivery))\n return yield* error(\"conflict\", \"delivery-identity\");\n continue;\n }\n if (!subscriptionCanSelect(record, accepted, effectiveNowMillis, false)) continue;\n additions.push({ delivery, record });\n }\n\n const total = yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}`,\n \"count deliveries\",\n );\n\n if (total + additions.length > limits.maxDeliveries)\n return yield* error(\"capacity\", \"deliveries\");\n for (const ownerId of new Set(additions.map(({ record }) => record.key.ownerId))) {\n const existing = yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND owner_id=${ownerId}`,\n \"count owner deliveries\",\n );\n\n if (\n existing + additions.filter(({ record }) => record.key.ownerId === ownerId).length >\n limits.maxDeliveriesPerOwner\n )\n return yield* error(\"capacity\", \"owner-deliveries\");\n }\n for (const addition of additions) {\n yield* insertDelivery(addition.delivery);\n if (addition.record.configuration.mode === \"once\")\n yield* writeRegistration({ ...addition.record, state: \"consumed\", recovery: null });\n }\n yield* writeEvent({ ...accepted, cursor, routingComplete: complete, routingFailure: null });\n\n return true;\n }),\n );\n\n if (changed) yield* failpoint.hit(\"subscription:select:after\");\n });\n\n const catchUp: SubscriptionStore[\"Service\"][\"catchUp\"] = Effect.fn(\n \"SqliteSubscriptionStore.catchUp\",\n )(function* (inputEvent, inputDelivery, nowMillis, inputLimits) {\n const supplied = yield* validate(AcceptedEvent, inputEvent, \"catch-up-event\");\n const delivery = yield* validate(SubscriptionDelivery, inputDelivery, \"catch-up-delivery\");\n const limits = yield* validate(SubscriptionLimits, inputLimits, \"catch-up-limits\");\n\n yield* requirePartition(supplied.partition, \"catch-up-partition\");\n yield* requirePartition(delivery.key.subscription.partition, \"catch-up-delivery-partition\");\n\n const changed = yield* transact(\n Effect.gen(function* () {\n const accepted = yield* readEvent(supplied.eventId, \"catch-up event\");\n const record = yield* readRegistration(delivery.key.subscription, \"catch-up subscription\");\n\n if (accepted === null || record === null)\n return yield* error(\"not-found\", accepted === null ? \"event\" : \"subscription\");\n if (\n !sameAcceptedEventIdentity(accepted, supplied) ||\n !subscriptionDeliveryCanSelect(delivery, record, accepted) ||\n delivery.key.eventId !== accepted.eventId ||\n delivery.source.name !== accepted.source.name ||\n delivery.source.version !== accepted.source.version ||\n record.configuration.mode !== \"once\"\n )\n return yield* error(\"conflict\", \"catch-up-identity\");\n const existing = yield* readDelivery(delivery.key, \"catch-up existing delivery\");\n\n if (existing !== null) {\n if (!sameDeliveryIdentity(existing, delivery))\n return yield* error(\"conflict\", \"delivery-identity\");\n\n return false;\n }\n yield* failpoint.hit(\"subscription:catch-up:before\");\n const effectiveNowMillis = Math.max(nowMillis, yield* Clock.currentTimeMillis);\n\n if (!subscriptionCanSelect(record, accepted, effectiveNowMillis, true))\n return yield* error(\"conflict\", \"catch-up-eligibility\");\n if (\n (yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}`,\n \"count deliveries\",\n )) >= limits.maxDeliveries\n )\n return yield* error(\"capacity\", \"deliveries\");\n if (\n (yield* count(\n sql<\n Record<string, unknown>\n >`SELECT COUNT(*) AS count FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND owner_id=${record.key.ownerId}`,\n \"count owner deliveries\",\n )) >= limits.maxDeliveriesPerOwner\n )\n return yield* error(\"capacity\", \"owner-deliveries\");\n yield* insertDelivery(delivery);\n yield* writeRegistration({ ...record, state: \"consumed\", recovery: null });\n\n return true;\n }),\n );\n\n if (changed) yield* failpoint.hit(\"subscription:catch-up:after\");\n });\n\n const deferEvent: SubscriptionStore[\"Service\"][\"deferEvent\"] = Effect.fn(\n \"SqliteSubscriptionStore.deferEvent\",\n )(function* (eventId, nextAttemptAtMillis, code) {\n const routingFailure =\n code === undefined\n ? \"routing-failed\"\n : yield* validate(SubscriptionName, code, \"routing-failure\");\n\n yield* transact(\n Effect.gen(function* () {\n const accepted = yield* readEvent(eventId, \"defer event\");\n\n if (accepted === null) return yield* error(\"not-found\", \"event\");\n yield* failpoint.hit(\"subscription:defer-event:before\");\n yield* writeEvent({ ...accepted, nextAttemptAtMillis, routingFailure });\n }),\n );\n yield* failpoint.hit(\"subscription:defer-event:after\");\n });\n\n const delivery: SubscriptionStore[\"Service\"][\"delivery\"] = Effect.fn(\n \"SqliteSubscriptionStore.delivery\",\n )(function* (input) {\n const key = yield* validate(SubscriptionDeliveryKey, input, \"delivery-key\");\n\n yield* requirePartition(key.subscription.partition, \"delivery-partition\");\n\n return yield* readDelivery(key, \"get delivery\");\n });\n\n const pendingDeliveries: SubscriptionStore[\"Service\"][\"pendingDeliveries\"] = Effect.fn(\n \"SqliteSubscriptionStore.pendingDeliveries\",\n )(function* (nowMillis, after, limit) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, event_id FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state NOT IN ('delivered','refused')\n AND next_attempt_at_millis<=${nowMillis} AND delivery_key>${after} ORDER BY delivery_key LIMIT ${limit}\n `,\n \"pending deliveries\",\n );\n\n const rowSchema = Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n event_id: Schema.String,\n });\n\n return yield* decodeRows(rowSchema, rows, \"pending delivery keys\").pipe(\n Effect.map((items) =>\n items.map((item) => ({\n subscription: { partition, ownerId: item.owner_id, subscriptionId: item.subscription_id },\n eventId: item.event_id,\n })),\n ),\n );\n });\n\n const listDeliveries: SubscriptionStore[\"Service\"][\"listDeliveries\"] = Effect.fn(\n \"SqliteSubscriptionStore.listDeliveries\",\n )(function* (input, after, limit) {\n const key = yield* requireKey(input, \"list-deliveries-key\");\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT record_json FROM effect_agent_subscription_deliveries WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n AND owner_id=${key.ownerId} AND subscription_id=${key.subscriptionId} AND delivery_key>${after} ORDER BY delivery_key LIMIT ${limit}\n `,\n \"list deliveries\",\n );\n\n const decoded = yield* decodeRows(JsonRow, rows, \"list deliveries\");\n\n return yield* Effect.forEach(decoded, (row) =>\n decode(SubscriptionDelivery, row.record_json, \"list delivery\"),\n );\n });\n\n const changeDelivery: SubscriptionStore[\"Service\"][\"changeDelivery\"] = Effect.fn(\n \"SqliteSubscriptionStore.changeDelivery\",\n )(function* (inputKey, inputDeliveryId, inputChange) {\n const key = yield* validate(SubscriptionDeliveryKey, inputKey, \"change-delivery-key\");\n const deliveryId = yield* validate(Digest, inputDeliveryId, \"change-delivery-id\");\n const change = yield* validate(DeliveryChange, inputChange, \"change-delivery-change\");\n\n yield* requirePartition(key.subscription.partition, \"change-delivery-partition\");\n\n const result = yield* transact(\n Effect.gen(function* () {\n const existing = yield* readDelivery(key, \"change delivery\");\n const record = yield* readRegistration(key.subscription, \"change delivery subscription\");\n\n if (existing === null || record === null)\n return yield* error(\"not-found\", existing === null ? \"delivery\" : \"subscription\");\n yield* failpoint.hit(`subscription:delivery-${change._tag.toLowerCase()}:before`);\n\n const effectiveChange =\n change._tag === \"Prepare\"\n ? { ...change, nowMillis: Math.max(change.nowMillis, yield* Clock.currentTimeMillis) }\n : change;\n\n const transition = applySubscriptionDeliveryChange(\n existing,\n record,\n deliveryId,\n effectiveChange,\n );\n\n if (Result.isFailure(transition)) return yield* transition.failure;\n if (transition.success === existing) return { value: existing, changed: false } as const;\n yield* writeDelivery(transition.success);\n\n return { value: transition.success, changed: true } as const;\n }),\n );\n\n if (result.changed)\n yield* failpoint.hit(`subscription:delivery-${change._tag.toLowerCase()}:after`);\n\n return result.value;\n });\n\n const recovering: SubscriptionStore[\"Service\"][\"recovering\"] = Effect.fn(\n \"SqliteSubscriptionStore.recovering\",\n )(function* (nowMillis, after, limit) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT owner_id, subscription_id, ordinal FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active'\n AND recovery_at_millis IS NOT NULL AND recovery_at_millis<=${nowMillis} AND ordinal>${after}\n ORDER BY ordinal LIMIT ${limit}\n `,\n \"recovering subscriptions\",\n );\n\n const rowSchema = Schema.Struct({\n owner_id: Schema.String,\n subscription_id: Schema.String,\n ordinal: Schema.Natural,\n });\n\n return yield* decodeRows(rowSchema, rows, \"recovering subscription keys\").pipe(\n Effect.map((items) =>\n items.map((item) => ({\n key: { partition, ownerId: item.owner_id, subscriptionId: item.subscription_id },\n ordinal: item.ordinal,\n })),\n ),\n );\n });\n\n const deferRecovery: SubscriptionStore[\"Service\"][\"deferRecovery\"] = Effect.fn(\n \"SqliteSubscriptionStore.deferRecovery\",\n )(function* (input, recovery) {\n const key = yield* requireKey(input, \"defer-recovery-key\");\n\n yield* transact(\n Effect.gen(function* () {\n const record = yield* readRegistration(key, \"defer recovery\");\n\n if (record === null) return yield* error(\"not-found\", \"subscription\");\n yield* failpoint.hit(\"subscription:defer-recovery:before\");\n yield* writeRegistration({\n ...record,\n recovery: record.state === \"active\" ? recovery : null,\n });\n }),\n );\n yield* failpoint.hit(\"subscription:defer-recovery:after\");\n });\n\n const readScanCursors: SubscriptionStore[\"Service\"][\"readScanCursors\"] = Effect.gen(function* () {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor\n FROM effect_agent_subscription_sequences\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"read subscription scan cursors\",\n );\n\n const decoded = yield* decodeRows(ScanRow, rows, \"read subscription scan cursors\");\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription scan cursors\");\n\n return {\n events: decoded[0].event_scan_cursor,\n deliveries: decoded[0].delivery_scan_cursor,\n recovery: decoded[0].recovery_scan_cursor,\n };\n });\n\n const advanceScanCursors: SubscriptionStore[\"Service\"][\"advanceScanCursors\"] = Effect.fn(\n \"SqliteSubscriptionStore.advanceScanCursors\",\n )(function* (input) {\n const cursors = yield* validate(SubscriptionScanCursors, input, \"scan-cursors\");\n\n yield* transact(\n Effect.gen(function* () {\n yield* failpoint.hit(\"subscription:advance-scan-cursors:before\");\n yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_sequences\n SET event_scan_cursor=${cursors.events}, delivery_scan_cursor=${cursors.deliveries}, recovery_scan_cursor=${cursors.recovery}\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"advance subscription scan cursors\",\n );\n }),\n );\n yield* failpoint.hit(\"subscription:advance-scan-cursors:after\");\n });\n\n const indexedDeadline = query(\n sql<Record<string, unknown>>`\n SELECT MIN(deadline) AS deadline FROM (\n SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0\n UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state NOT IN ('delivered','refused')\n UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL\n )\n `,\n \"next subscription deadline\",\n ).pipe(\n Effect.flatMap((rows) =>\n decodeRows(\n Schema.Struct({ deadline: Schema.NullOr(Schema.Number) }),\n rows,\n \"next subscription deadline\",\n ),\n ),\n Effect.flatMap((rows) =>\n rows.length === 1\n ? Effect.succeed(rows[0].deadline)\n : Effect.fail(corrupt(\"next subscription deadline\")),\n ),\n );\n\n const nextDeadline = Effect.gen(function* () {\n const cursors = yield* readScanCursors;\n\n if (cursors.events !== \"\" || cursors.deliveries !== \"\" || cursors.recovery !== 0) return 0;\n\n return yield* indexedDeadline;\n });\n\n const prearm = Effect.fn(\"DoSubscriptionStore.prearm\")(function* (deadlineAtMillis: number) {\n yield* transactions.run((replace) => replaceAlarm(replace, deadlineAtMillis));\n yield* failpoint.hit(\"subscription:prearm:after\");\n });\n\n const reconcile = Effect.gen(function* () {\n yield* transactions.run((replace) =>\n Effect.gen(function* () {\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n }),\n );\n yield* failpoint.hit(\"subscription:reconcile:after\");\n });\n\n return Context.make(SubscriptionStore, {\n partition,\n register,\n get,\n list,\n cancel,\n accept,\n event,\n pendingEvents,\n candidates,\n select,\n catchUp,\n deferEvent,\n delivery,\n pendingDeliveries,\n listDeliveries,\n changeDelivery,\n recovering,\n deferRecovery,\n readScanCursors,\n advanceScanCursors,\n nextDeadline,\n }).pipe(Context.add(DoSubscriptionAlarmControl, { prearm, reconcile }));\n});\n\nexport const doSubscriptionStoreLayer = (\n partition: SourcePartition,\n): Layer.Layer<\n SubscriptionStore | DoSubscriptionAlarmControl,\n SubscriptionError,\n DoSubscriptionTransaction | SqlClientService.SqlClient\n> => Layer.effectContext(makeSubscriptionStore(partition));\n"],"mappings":"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"}
1
+ {"version":3,"file":"DoSubscriptionStore.mjs","names":[],"sources":["../src/DoSubscriptionStore.ts"],"sourcesContent":["import {\n makeSqlSubscriptionStore,\n SqlSubscriptionTransaction,\n} from \"@effect-agent/thread/SqlSubscriptionStore\";\nimport {\n SourcePartition,\n SubscriptionError,\n SubscriptionFailpoint,\n type SubscriptionFailpointError,\n SubscriptionStore,\n} from \"@effect-agent/thread/Subscription\";\nimport { Context, Effect, Layer, Schema } from \"effect\";\nimport * as SqlClientService from \"effect/unstable/sql/SqlClient\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nconst CURRENT_SUBSCRIPTION_STORE_VERSION = 2;\n\nconst ScanRow = Schema.Struct({\n event_scan_cursor: Schema.String,\n delivery_scan_cursor: Schema.String,\n recovery_scan_cursor: Schema.Natural,\n});\n\nconst StoreStateRow = Schema.Struct({\n storage_version: Schema.Int,\n alarm_generation: Schema.Natural,\n});\n\nexport interface DoSubscriptionAlarmReplacement {\n readonly deadlineAtMillis: number | null;\n readonly generation: number;\n}\n\nexport type DoSubscriptionReplaceAlarm = (\n replacement: DoSubscriptionAlarmReplacement,\n) => Effect.Effect<void, SubscriptionError>;\n\n/** One Durable Object transaction combining subscription SQL and its single native alarm. */\nexport class DoSubscriptionTransaction extends Context.Service<\n DoSubscriptionTransaction,\n {\n readonly run: <A, E, R>(\n body: (replaceAlarm: DoSubscriptionReplaceAlarm) => Effect.Effect<A, E, R>,\n ) => Effect.Effect<A, E | SubscriptionError, R>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionTransaction\") {}\n\nexport class DoSubscriptionAlarmControl extends Context.Service<\n DoSubscriptionAlarmControl,\n {\n readonly prearm: (\n deadlineAtMillis: number,\n ) => Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n readonly reconcile: Effect.Effect<void, SubscriptionError | SubscriptionFailpointError>;\n }\n>()(\"@effect-agent/storage-cloudflare/DoSubscriptionAlarmControl\") {}\n\nconst error = (reason: SubscriptionError[\"reason\"], code: string) =>\n SubscriptionError.make({ reason, code });\n\nconst unavailable = (operation: string) => error(\"storage\", operation);\nconst corrupt = (operation: string) => error(\"corrupt\", operation);\n\nconst validate = <A, I>(schema: Schema.Codec<A, I>, value: unknown, code: string) =>\n Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => error(\"validation\", code)));\n\nconst decodeRows = <A, I>(schema: Schema.Codec<A, I>, rows: unknown, code: string) =>\n Schema.decodeUnknownEffect(Schema.Array(schema))(rows).pipe(Effect.mapError(() => corrupt(code)));\n\nconst initializeDoSubscriptionStore = Effect.fn(\"DoSubscriptionStore.initialize\")(function* () {\n const sql = yield* SqlClientService.SqlClient;\n\n const names = yield* sql<Record<string, unknown>>`\n SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'effect_agent_subscription_%'\n `.pipe(Effect.mapError(() => unavailable(\"inspect subscription storage\")));\n\n const decodedNames = yield* decodeRows(\n Schema.Struct({ name: Schema.String }),\n names,\n \"inspect subscription storage\",\n );\n\n const expected = new Set([\n \"effect_agent_subscription_store_state\",\n \"effect_agent_subscription_sequences\",\n \"effect_agent_subscriptions\",\n \"effect_agent_subscription_events\",\n \"effect_agent_subscription_deliveries\",\n ]);\n\n const hasState = decodedNames.some(\n ({ name }) => name === \"effect_agent_subscription_store_state\",\n );\n\n if (!hasState && decodedNames.length > 0) return yield* corrupt(\"partial subscription storage\");\n if (!hasState) {\n yield* sql\n .withTransaction(\n Effect.gen(function* () {\n yield* sql`CREATE TABLE effect_agent_subscription_store_state (\n singleton INTEGER PRIMARY KEY NOT NULL CHECK(singleton=1), storage_version INTEGER NOT NULL, alarm_generation INTEGER NOT NULL\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_sequences (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, sequence INTEGER NOT NULL,\n event_scan_cursor TEXT NOT NULL, delivery_scan_cursor TEXT NOT NULL, recovery_scan_cursor INTEGER NOT NULL,\n PRIMARY KEY (tenant_id, source_address)\n )`.withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscriptions (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n ordinal INTEGER NOT NULL, source_name TEXT NOT NULL, source_version TEXT NOT NULL, matching_key TEXT NOT NULL,\n state TEXT NOT NULL, expires_at_millis INTEGER NOT NULL, recovery_at_millis INTEGER, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id), UNIQUE (tenant_id, source_address, ordinal)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_owner ON effect_agent_subscriptions (tenant_id, source_address, owner_id, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_candidates ON effect_agent_subscriptions (tenant_id, source_address, source_name, source_version, matching_key, ordinal)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscriptions_recovery ON effect_agent_subscriptions (tenant_id, source_address, recovery_at_millis, ordinal) WHERE recovery_at_millis IS NOT NULL`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_events (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, event_id TEXT NOT NULL, source_name TEXT NOT NULL,\n source_version TEXT NOT NULL, matching_key TEXT NOT NULL, payload_digest TEXT NOT NULL, cutoff INTEGER NOT NULL,\n cursor INTEGER NOT NULL, routing_complete INTEGER NOT NULL, next_attempt_at_millis INTEGER NOT NULL, record_json TEXT NOT NULL,\n PRIMARY KEY (tenant_id, source_address, event_id)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_events_pending ON effect_agent_subscription_events (tenant_id, source_address, routing_complete, next_attempt_at_millis, event_id)`\n .withoutTransform;\n yield* sql`CREATE TABLE effect_agent_subscription_deliveries (\n tenant_id TEXT NOT NULL, source_address TEXT NOT NULL, owner_id TEXT NOT NULL, subscription_id TEXT NOT NULL,\n event_id TEXT NOT NULL, delivery_key TEXT NOT NULL, state TEXT NOT NULL, next_attempt_at_millis INTEGER NOT NULL,\n record_json TEXT NOT NULL, PRIMARY KEY (tenant_id, source_address, owner_id, subscription_id, event_id),\n UNIQUE (tenant_id, source_address, delivery_key)\n )`.withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_pending ON effect_agent_subscription_deliveries (tenant_id, source_address, state, next_attempt_at_millis, delivery_key)`\n .withoutTransform;\n yield* sql`CREATE INDEX effect_agent_subscription_deliveries_registration ON effect_agent_subscription_deliveries (tenant_id, source_address, owner_id, subscription_id, delivery_key)`\n .withoutTransform;\n yield* sql`INSERT INTO effect_agent_subscription_store_state (singleton, storage_version, alarm_generation)\n VALUES (1, ${CURRENT_SUBSCRIPTION_STORE_VERSION}, 0)`.withoutTransform;\n }),\n )\n .pipe(Effect.mapError(() => unavailable(\"initialize subscription storage\")));\n\n return;\n }\n if (decodedNames.length !== expected.size || decodedNames.some(({ name }) => !expected.has(name)))\n return yield* corrupt(\"subscription storage tables\");\n\n const rows = yield* sql<\n Record<string, unknown>\n >`SELECT storage_version, alarm_generation FROM effect_agent_subscription_store_state WHERE singleton=1`.pipe(\n Effect.mapError(() => unavailable(\"read subscription storage version\")),\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"read subscription storage version\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\n state.length === 1\n ? `incompatible subscription storage version ${state[0].storage_version}; expected ${CURRENT_SUBSCRIPTION_STORE_VERSION}`\n : \"invalid subscription storage version row\",\n );\n});\n\nconst makeSubscriptionStore = Effect.fn(\"DoSubscriptionStore.make\")(function* (\n owned: SourcePartition,\n) {\n const partition = yield* validate(SourcePartition, owned, \"partition\");\n const sql = yield* SqlClientService.SqlClient;\n const failpoint = yield* SubscriptionFailpoint;\n const transactions = yield* DoSubscriptionTransaction;\n\n yield* initializeDoSubscriptionStore();\n\n const query = <A extends object>(\n effect: Effect.Effect<ReadonlyArray<A>, SqlError>,\n code: string,\n ) => effect.pipe(Effect.mapError(() => unavailable(code)));\n\n const readIndexedDeadline = Effect.fn(\"DoSubscriptionStore.readIndexedDeadline\")(function* () {\n const scanRows = yield* query(\n sql<Record<string, unknown>>`\n SELECT event_scan_cursor, delivery_scan_cursor, recovery_scan_cursor FROM effect_agent_subscription_sequences\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address}\n `,\n \"read scan cursor deadline\",\n );\n\n const scans = yield* decodeRows(ScanRow, scanRows, \"read scan cursor deadline\");\n\n if (scans.length !== 1) return yield* corrupt(\"scan cursor deadline\");\n if (\n scans[0].event_scan_cursor !== \"\" ||\n scans[0].delivery_scan_cursor !== \"\" ||\n scans[0].recovery_scan_cursor !== 0\n )\n return 0;\n\n const rows = yield* query(\n sql<Record<string, unknown>>`\n SELECT MIN(deadline) AS deadline FROM (\n SELECT next_attempt_at_millis AS deadline FROM effect_agent_subscription_events\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND routing_complete=0\n UNION ALL SELECT next_attempt_at_millis FROM effect_agent_subscription_deliveries\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state NOT IN ('delivered','refused')\n UNION ALL SELECT recovery_at_millis FROM effect_agent_subscriptions\n WHERE tenant_id=${partition.tenantId} AND source_address=${partition.address} AND state='active' AND recovery_at_millis IS NOT NULL\n )\n `,\n \"read subscription deadline\",\n );\n\n const decoded = yield* decodeRows(\n Schema.Struct({ deadline: Schema.NullOr(Schema.Number) }),\n rows,\n \"read subscription deadline\",\n );\n\n if (decoded.length !== 1) return yield* corrupt(\"subscription deadline\");\n\n return decoded[0].deadline;\n });\n\n const replaceAlarm = Effect.fn(\"DoSubscriptionStore.replaceAlarm\")(function* (\n replace: DoSubscriptionReplaceAlarm,\n deadlineAtMillis: number | null,\n ) {\n const rows = yield* query(\n sql<Record<string, unknown>>`\n UPDATE effect_agent_subscription_store_state SET alarm_generation=alarm_generation+1\n WHERE singleton=1 RETURNING storage_version, alarm_generation\n `,\n \"advance subscription alarm generation\",\n );\n\n const state = yield* decodeRows(StoreStateRow, rows, \"advance subscription alarm generation\");\n\n if (state.length !== 1 || state[0].storage_version !== CURRENT_SUBSCRIPTION_STORE_VERSION)\n return yield* corrupt(\"subscription alarm state\");\n yield* failpoint.hit(\"subscription:alarm:before\");\n yield* replace({ deadlineAtMillis, generation: state[0].alarm_generation });\n yield* failpoint.hit(\"subscription:alarm:after\");\n });\n\n const transact = <A>(effect: Effect.Effect<A, SubscriptionError | SubscriptionFailpointError>) =>\n transactions.run((replace) =>\n Effect.gen(function* () {\n const value = yield* effect;\n\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n\n return value;\n }),\n );\n\n const store = yield* makeSqlSubscriptionStore(partition, {\n maxStoredJsonLength: 1_900_000,\n }).pipe(Effect.provide(Layer.succeed(SqlSubscriptionTransaction)({ run: transact })));\n\n const prearm = Effect.fn(\"DoSubscriptionStore.prearm\")(function* (deadlineAtMillis: number) {\n yield* transactions.run((replace) => replaceAlarm(replace, deadlineAtMillis));\n yield* failpoint.hit(\"subscription:prearm:after\");\n });\n\n const reconcile = Effect.gen(function* () {\n yield* transactions.run((replace) =>\n Effect.gen(function* () {\n yield* replaceAlarm(replace, yield* readIndexedDeadline());\n }),\n );\n yield* failpoint.hit(\"subscription:reconcile:after\");\n });\n\n return Context.make(SubscriptionStore, store).pipe(\n Context.add(DoSubscriptionAlarmControl, { prearm, reconcile }),\n );\n});\n\nexport const doSubscriptionStoreLayer = (\n partition: SourcePartition,\n): Layer.Layer<\n SubscriptionStore | DoSubscriptionAlarmControl,\n SubscriptionError,\n DoSubscriptionTransaction | SqlClientService.SqlClient\n> => Layer.effectContext(makeSubscriptionStore(partition));\n"],"mappings":"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"}
@@ -377,9 +377,10 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
377
377
  readonly _tag: "CompactionCreated";
378
378
  readonly runId: string;
379
379
  readonly turn: number;
380
- readonly kind: "clear-tool-results" | "summarize";
380
+ readonly kind: "clear-tool-results" | "rollover" | "summarize";
381
381
  readonly coversThrough: number;
382
382
  readonly summary?: string | undefined;
383
+ readonly handoff?: string | undefined;
383
384
  } | {
384
385
  readonly _tag: "RunFailed";
385
386
  readonly runId: string;
@@ -661,9 +662,10 @@ declare const encodePortRequest: (input: LedgerAdmitCall | LedgerLookupCall | Le
661
662
  readonly _tag: "CompactionCreated";
662
663
  readonly runId: string;
663
664
  readonly turn: number;
664
- readonly kind: "clear-tool-results" | "summarize";
665
+ readonly kind: "clear-tool-results" | "rollover" | "summarize";
665
666
  readonly coversThrough: number;
666
667
  readonly summary?: string | undefined;
668
+ readonly handoff?: string | undefined;
667
669
  } | {
668
670
  readonly _tag: "RunFailed";
669
671
  readonly runId: string;
@@ -1074,9 +1076,10 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
1074
1076
  readonly _tag: "CompactionCreated";
1075
1077
  readonly runId: string;
1076
1078
  readonly turn: number;
1077
- readonly kind: "clear-tool-results" | "summarize";
1079
+ readonly kind: "clear-tool-results" | "rollover" | "summarize";
1078
1080
  readonly coversThrough: number;
1079
1081
  readonly summary?: string | undefined;
1082
+ readonly handoff?: string | undefined;
1080
1083
  } | {
1081
1084
  readonly _tag: "RunFailed";
1082
1085
  readonly runId: string;
@@ -1380,9 +1383,10 @@ declare const encodePortResponse: (input: PortFailed | PortSucceeded, options?:
1380
1383
  readonly _tag: "CompactionCreated";
1381
1384
  readonly runId: string;
1382
1385
  readonly turn: number;
1383
- readonly kind: "clear-tool-results" | "summarize";
1386
+ readonly kind: "clear-tool-results" | "rollover" | "summarize";
1384
1387
  readonly coversThrough: number;
1385
1388
  readonly summary?: string | undefined;
1389
+ readonly handoff?: string | undefined;
1386
1390
  } | {
1387
1391
  readonly _tag: "RunFailed";
1388
1392
  readonly runId: string;
@@ -249,6 +249,7 @@ const makeRoutedLedgerServices = Effect.fn("DoPortRouting.makeRoutedLedgerServic
249
249
  beginChildBudgetRelease: local.beginChildBudgetRelease,
250
250
  releaseChildBudget: local.releaseChildBudget,
251
251
  scanNonterminal: local.scanNonterminal,
252
+ readAbortIntent: (request) => submissionTarget("ledger read abort intent", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.readAbortIntent(request) : Effect.fail(crossThreadLedgerError("ledger read abort intent", target.threadId)))),
252
253
  loadRecoverySnapshot: (request) => submissionTarget("ledger load recovery snapshot", request.submissionId).pipe(Effect.flatMap((target) => target._tag === "local" ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments)) : Effect.fail(crossThreadLedgerError("ledger load recovery snapshot", target.threadId))))
253
254
  });
254
255
  return Context.make(SubmissionLedger, routed);
@@ -1 +1 @@
1
- {"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * The Thread this Durable Object owns (the Object identity rule is\n * `namespace.idFromName(threadId)`). Requests addressed here execute on the local\n * facet; requests addressed anywhere else route through the transport or fail fast typed.\n */\n readonly localThreadId: ThreadId;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n localThreadId: ThreadId,\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n if (tail === localThreadId) return LOCAL;\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget => ({ _tag: \"foreign\", threadId })),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.localThreadId);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n request.threadId === options.localThreadId\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n AdmissionConflict,\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : request.threadId === options.localThreadId\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n request.threadId === options.localThreadId\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n request.threadId === options.localThreadId\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n request.threadId === options.localThreadId\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n request.threadId === options.localThreadId\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n request.threadId === options.localThreadId\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n request.threadId === options.localThreadId\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n request.threadId === options.localThreadId\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n request.threadId === options.localThreadId\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local by construction (plan §1.3): the closed\n // route-capable store subset is materialize/append/read/inspectTail/export, and a\n // foreign address on anything else fails fast typed.\n observe: (request) =>\n request.threadId === options.localThreadId\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport; foreign observation and checkpoints fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"PortRouting.mjs","names":[],"sources":["../src/PortRouting.ts"],"sourcesContent":["import {\n AdmissionIndeterminate,\n AdmissionConflict,\n ChildAttachmentSnapshot,\n JoinedToHost,\n LedgerError,\n RecoverySnapshot,\n SettlementConflict,\n SubmissionLedger,\n SubmissionLookupById,\n type SubmissionLookupByKey,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n FenceRejected,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { Context, Effect, Layer, Option, Predicate, Schema, Stream } from \"effect\";\n\nimport {\n boundPortDiagnostic,\n decodePortRequest,\n decodePortResponse,\n encodePortRequest,\n encodePortResponse,\n LedgerAdmitCall,\n LedgerAdmitResult,\n LedgerLookupCall,\n LedgerLookupResult,\n LedgerMarkReadyCall,\n LedgerMarkReadyResult,\n LedgerRecordChildSettledCall,\n LedgerRecordChildSettledResult,\n LedgerRequestAbortCall,\n LedgerRequestAbortResult,\n LedgerResolveAdmissionCall,\n LedgerResolveAdmissionResult,\n PortFailed,\n PortProtocolError,\n PortSucceeded,\n StoreAppendCall,\n StoreAppendResult,\n StoreExportCall,\n StoreExportResult,\n StoreInspectTailCall,\n StoreInspectTailResult,\n StoreMaterializeCall,\n StoreMaterializeResult,\n StoreReadPageCall,\n StoreReadPageResult,\n type PortFailure,\n type PortRequest,\n type PortRequestEnvelope,\n type PortResponse,\n type PortResult,\n} from \"./PortProtocol.ts\";\n\ntype ThreadId = ThreadMaterialization[\"threadId\"];\ntype SubmissionId = SubmissionSnapshot[\"submissionId\"];\n\nconst ThreadIdSchema = ThreadMaterialization.fields.threadId;\nconst decodeThreadId = Schema.decodeUnknownEffect(ThreadIdSchema);\n\n/**\n * The ledger row bound routable Submission identities must respect (mirrors the local\n * facet's `MAX_IDENTIFIER_LENGTH`; the minting side already refuses longer identities typed\n * at admission, so a longer identity presented here cannot name any stored row).\n */\nconst MAX_ROUTABLE_SUBMISSION_ID_LENGTH = 1_024;\n\n/** The `{uuidv7}` head of a DC-minted routable Submission identity. */\nconst UUID_HEAD_PATTERN =\n /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;\n\n/**\n * A transport could not deliver a port request to (or an answer from) the owning\n * Thread's Durable Object. `retryable` carries the platform's own stub signal when one\n * exists. This error never crosses the wire — it is the CALLER-side evidence that the\n * authority was unreachable, which is exactly the case `AdmissionIndeterminate` was\n * specified for (SUB-031).\n */\nexport class PortTransportError extends Schema.TaggedError<PortTransportError>()(\n \"PortTransportError\",\n {\n target: Schema.String,\n message: Schema.String,\n retryable: Schema.optionalKey(Schema.Boolean),\n cause: Schema.optionalKey(Schema.Defect()),\n },\n) {}\n\nconst safeTransportDiagnostic = (cause: unknown): string => {\n try {\n const message = cause instanceof Error ? cause.message : cause;\n\n return boundPortDiagnostic(typeof message === \"string\" ? message : String(message));\n } catch {\n return \"[unavailable transport diagnostic]\";\n }\n};\n\nconst transportRetryableSignal = (cause: unknown): boolean | undefined => {\n if (!Predicate.isObjectKeyword(cause)) return undefined;\n try {\n const signal = Reflect.get(cause, \"retryable\");\n\n return typeof signal === \"boolean\" ? signal : undefined;\n } catch {\n return undefined;\n }\n};\n\n/**\n * Build a `PortTransportError` from an arbitrary thrown transport cause, preserving the\n * platform stub's own `retryable` signal when present.\n */\nexport const portTransportFailure = (target: string, cause: unknown): PortTransportError => {\n const retryable = transportRetryableSignal(cause);\n\n return PortTransportError.make({\n target,\n message: safeTransportDiagnostic(cause),\n ...(retryable === undefined ? {} : { retryable }),\n cause,\n });\n};\n\n/**\n * Delivery of Schema-encoded port envelopes to the Durable Object that owns a FOREIGN\n * Thread (plan §1.3, D-P6-3). The shipped implementation (platform-cloudflare, WP3)\n * calls the owner's `portCall` over native Durable Object JS RPC via\n * `namespace.idFromName(threadId)`; the protocol is transport-agnostic and any carrier\n * that moves the encoded envelopes verbatim satisfies this service. Implementations MUST\n * surface every delivery problem as `PortTransportError` and must never fabricate an answer.\n */\nexport class ThreadPortTransport extends Context.Service<\n ThreadPortTransport,\n {\n readonly call: (\n threadId: ThreadId,\n request: PortRequestEnvelope,\n ) => Effect.Effect<unknown, PortTransportError>;\n }\n>()(\"@effect-agent/storage-cloudflare/ThreadPortTransport\") {}\n\n/** Construction options shared by both routed port Layers. */\nexport interface RoutedPortOptions {\n /**\n * The Thread this Durable Object owns (the Object identity rule is\n * `namespace.idFromName(threadId)`). Requests addressed here execute on the local\n * facet; requests addressed anywhere else route through the transport or fail fast typed.\n */\n readonly localThreadId: ThreadId;\n}\n\n/** Where one port request must execute. */\ntype RouteTarget =\n | { readonly _tag: \"local\" }\n | { readonly _tag: \"foreign\"; readonly threadId: ThreadId };\n\nconst LOCAL: RouteTarget = { _tag: \"local\" };\n\n/**\n * Parse a DC-minted routable Submission identity — `{uuidv7}:{threadId}`, split at the\n * FIRST `:` because the Thread tail may itself contain colons (D-P6-5). This adapter\n * minted the format at admission and is the ONLY component that parses it; identities that do\n * not carry the minted shape (no separator, non-UUID head, empty tail) fall back to the local\n * facet, which is the only authority this Object can consult without inventing an owner.\n * Identities beyond the ledger's 1,024-character row bound fail typed: the minting side\n * refused them at admission, so they cannot name any stored row anywhere.\n */\nconst routableSubmissionTarget = (\n localThreadId: ThreadId,\n): ((operation: string, submissionId: string) => Effect.Effect<RouteTarget, LedgerError>) =>\n Effect.fn(\"DoPortRouting.routableSubmissionTarget\")(function* (\n operation: string,\n submissionId: string,\n ): Effect.fn.Return<RouteTarget, LedgerError> {\n if (submissionId.length > MAX_ROUTABLE_SUBMISSION_ID_LENGTH) {\n return yield* LedgerError.make({\n operation,\n message:\n `A Submission identity of ${submissionId.length} characters exceeds the ` +\n `${MAX_ROUTABLE_SUBMISSION_ID_LENGTH}-character routable identity bound; admission ` +\n \"refuses such identities, so it cannot name any stored row.\",\n });\n }\n const separator = submissionId.indexOf(\":\");\n\n if (separator === -1) return LOCAL;\n if (!UUID_HEAD_PATTERN.test(submissionId.slice(0, separator))) return LOCAL;\n const tail = submissionId.slice(separator + 1);\n\n if (tail === localThreadId) return LOCAL;\n\n return yield* decodeThreadId(tail).pipe(\n Effect.map((threadId): RouteTarget => ({ _tag: \"foreign\", threadId })),\n Effect.orElseSucceed(() => LOCAL),\n );\n });\n\nconst NoAdditionalPortFailure = Schema.Never;\nconst AbortPortFailure = Schema.Union([SettlementConflict, JoinedToHost]);\nconst AppendPortFailure = Schema.Union([ThreadNotMaterialized, AppendConflict, FenceRejected]);\n\n/**\n * The fail-fast refusal for any foreign operation OUTSIDE the closed route-capable subset\n * (plan §1.3): honesty over accidental distribution.\n */\nconst crossThreadLedgerError = (operation: string, target: string): LedgerError =>\n LedgerError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is admit, markReady, lookup, resolveAdmission, \" +\n \"requestAbort, and recordChildSettled. Every other ledger operation is lane-local by \" +\n \"construction and must execute inside the owning Thread's Durable Object.\",\n });\n\nconst crossThreadStoreError = (operation: string, target: string): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message:\n `${operation} addressed to foreign Thread ${target} is not route-capable; the ` +\n \"closed cross-Object subset is materialize, append, read (paged), inspectTail, and \" +\n \"export. Observation and checkpoints are lane-local by construction and must execute \" +\n \"inside the owning Thread's Durable Object.\",\n });\n\nconst makeTransportCall = (transport: ThreadPortTransport[\"Service\"]) =>\n Effect.fn(\"DoPortRouting.transportCall\")(function* (target: ThreadId, call: PortRequest) {\n const encoded = yield* encodePortRequest(call).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port request could not be encoded: ${error.message}`),\n }),\n ),\n );\n\n const raw = yield* transport.call(target, encoded);\n\n return yield* decodePortResponse(raw).pipe(\n Effect.mapError((error) =>\n PortProtocolError.make({\n message: boundPortDiagnostic(`The port response could not be decoded: ${error.message}`),\n }),\n ),\n );\n });\n\ntype TransportCall = ReturnType<typeof makeTransportCall>;\n\nconst makeRoutedLedgerServices = Effect.fn(\"DoPortRouting.makeRoutedLedgerServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* SubmissionLedger;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n const submissionTarget = routableSubmissionTarget(options.localThreadId);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): LedgerError =>\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /**\n * One routed ledger call: encode, deliver, decode, then narrow the uniform envelope to the\n * operation's own result and failure surface. A foreign `LedgerError` is always in-channel;\n * any failure outside the operation's declared surface — including protocol anomalies — is\n * folded into a `LedgerError` naming the anomaly instead of being erased or re-thrown raw.\n */\n const foreignLedgerCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (response): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | LedgerError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"LedgerError\") return Effect.fail(failure);\n\n return Effect.fail(\n LedgerError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n LedgerError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignLedgerCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n /**\n * Routed `resolveAdmission` — where the S2 tri-state becomes real (plan §1.3): when the\n * owning Object cannot be reached, or its answer cannot be understood, the routed adapter\n * answers `AdmissionIndeterminate{reason}` and NEVER `NotAdmitted` — an unreachable\n * authority proves nothing, and only `NotAdmitted` permits an admission attempt (SUB-031).\n * A typed `LedgerError` answered BY the authority still fails typed: the authority was\n * reached and reported its own storage failure.\n */\n const resolveForeignAdmission = (\n target: ThreadId,\n request: SubmissionLookupByKey,\n ): Effect.Effect<\n | AdmissionIndeterminate\n | Extract<PortResult, { readonly _tag: \"LedgerResolveAdmissionResult\" }>[\"resolution\"],\n LedgerError\n > =>\n transportCall(target, LedgerResolveAdmissionCall.make({ request })).pipe(\n Effect.flatMap((response) => {\n if (response._tag === \"PortFailed\") {\n if (response.failure._tag === \"LedgerError\") return Effect.fail(response.failure);\n\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `out-of-contract failure ${response.failure._tag}: ${response.failure.message}`,\n ),\n }),\n );\n }\n if (response.result._tag !== \"LedgerResolveAdmissionResult\") {\n return Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} answered resolveAdmission with the ` +\n `mismatched result ${response.result._tag}.`,\n ),\n }),\n );\n }\n\n return Effect.succeed(response.result.resolution);\n }),\n Effect.catchTags({\n PortTransportError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The Thread Object owning ${target} is unreachable: ${error.message}`,\n ),\n }),\n ),\n PortProtocolError: (error) =>\n Effect.succeed(\n AdmissionIndeterminate.make({\n reason: boundPortDiagnostic(\n `The answer of the Thread Object owning ${target} could not be ` +\n `understood: ${error.message}`,\n ),\n }),\n ),\n }),\n Effect.withSpan(\"DoPortRouting.resolveForeignAdmission\", { attributes: { target } }),\n );\n\n const foreignLookupById = (\n operation: string,\n target: ThreadId,\n submissionId: SubmissionId,\n ): Effect.Effect<Option.Option<SubmissionSnapshot>, LedgerError> =>\n foreignLedgerCall(\n operation,\n target,\n LedgerLookupCall.make({ request: SubmissionLookupById.make({ submissionId }) }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n );\n\n /**\n * Enrich a LOCAL parent's recovery snapshot with the lane state of attached children whose\n * rows live in other Durable Objects (plan §1.3): markers first (the local facet already\n * consulted them), then a routed per-child `lookup` for any attached child that is neither\n * local nor marker-settled. A transport failure surfaces as `LedgerError` so the alarm\n * pass retries; the child's canonical Settlement remains the only authority (DUR-015).\n */\n const enrichChildAttachments = Effect.fn(\"DoPortRouting.enrichChildAttachments\")(function* (\n snapshot: RecoverySnapshot,\n ): Effect.fn.Return<RecoverySnapshot, LedgerError> {\n const operation = \"ledger load recovery snapshot\";\n\n const attachments = new Map(\n snapshot.childAttachments.map((attachment) => [attachment.childSubmissionId, attachment]),\n );\n\n let enriched = false;\n\n for (const reservation of snapshot.childReservations) {\n const childSubmissionId = reservation.childSubmissionId;\n\n if (childSubmissionId === undefined || attachments.has(childSubmissionId)) continue;\n const target = yield* submissionTarget(operation, childSubmissionId);\n\n // A local or opaque child identity was already answered authoritatively by the local\n // facet; absence there means the child admission never committed.\n if (target._tag !== \"foreign\") continue;\n const child = yield* foreignLookupById(operation, target.threadId, childSubmissionId);\n\n if (Option.isNone(child)) continue;\n attachments.set(\n childSubmissionId,\n ChildAttachmentSnapshot.make({\n toolCallId: reservation.parentToolCallId,\n childSubmissionId,\n childState: child.value.state,\n ...(child.value.settledOutcome === undefined\n ? {}\n : { childOutcome: child.value.settledOutcome }),\n }),\n );\n enriched = true;\n }\n if (!enriched) return snapshot;\n // Rebuild in reservation (parent Tool Call) order, the order the local facet documents.\n const ordered: Array<ChildAttachmentSnapshot> = [];\n\n for (const reservation of snapshot.childReservations) {\n if (reservation.childSubmissionId === undefined) continue;\n const attachment = attachments.get(reservation.childSubmissionId);\n\n if (attachment !== undefined) ordered.push(attachment);\n }\n\n return RecoverySnapshot.make({ ...snapshot, childAttachments: ordered });\n });\n\n const routed = SubmissionLedger.of({\n capabilities: local.capabilities,\n\n admit: (request) =>\n request.threadId === options.localThreadId\n ? local.admit(request)\n : foreignLedgerCall(\n \"ledger admit\",\n request.threadId,\n LedgerAdmitCall.make({ request }),\n LedgerAdmitResult,\n AdmissionConflict,\n ).pipe(Effect.map((reply) => reply.result)),\n\n markReady: (request) =>\n submissionTarget(\"ledger mark ready\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markReady(request)\n : foreignLedgerCall(\n \"ledger mark ready\",\n target.threadId,\n LedgerMarkReadyCall.make({ request }),\n LedgerMarkReadyResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.asVoid),\n ),\n ),\n\n lookup: (request) =>\n request._tag === \"SubmissionLookupById\"\n ? submissionTarget(\"ledger lookup\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.lookup(request)\n : foreignLookupById(\"ledger lookup\", target.threadId, request.submissionId),\n ),\n )\n : request.threadId === options.localThreadId\n ? local.lookup(request)\n : foreignLedgerCall(\n \"ledger lookup\",\n request.threadId,\n LedgerLookupCall.make({ request }),\n LedgerLookupResult,\n NoAdditionalPortFailure,\n ).pipe(\n Effect.map((result) =>\n result.submission === undefined ? Option.none() : Option.some(result.submission),\n ),\n ),\n\n resolveAdmission: (request) =>\n request.threadId === options.localThreadId\n ? local.resolveAdmission(request)\n : resolveForeignAdmission(request.threadId, request),\n\n requestAbort: (request) =>\n submissionTarget(\"ledger request abort\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.requestAbort(request)\n : foreignLedgerCall(\n \"ledger request abort\",\n target.threadId,\n LedgerRequestAbortCall.make({ request }),\n LedgerRequestAbortResult,\n AbortPortFailure,\n ).pipe(Effect.map((reply) => reply.intent)),\n ),\n ),\n\n recordChildSettled: (request) =>\n submissionTarget(\"ledger record child settled\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordChildSettled(request)\n : foreignLedgerCall(\n \"ledger record child settled\",\n target.threadId,\n LedgerRecordChildSettledCall.make({ request }),\n LedgerRecordChildSettledResult,\n NoAdditionalPortFailure,\n ).pipe(Effect.map((reply) => reply.outcome)),\n ),\n ),\n\n // Every operation below is lane-local by construction (plan §1.3): a foreign address is\n // an out-of-contract call and fails fast typed instead of being quietly distributed.\n claim: (request) =>\n request.threadId === options.localThreadId\n ? local.claim(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim\", request.threadId)),\n\n claimJoining: (request) =>\n request.threadId === options.localThreadId\n ? local.claimJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger claim joining\", request.threadId)),\n\n renewOwnership: (request) =>\n submissionTarget(\"ledger renew ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.renewOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger renew ownership\", target.threadId)),\n ),\n ),\n\n releaseOwnership: (request) =>\n submissionTarget(\"ledger release ownership\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.releaseOwnership(request)\n : Effect.fail(crossThreadLedgerError(\"ledger release ownership\", target.threadId)),\n ),\n ),\n\n markInputApplied: (request) =>\n submissionTarget(\"ledger mark input applied\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markInputApplied(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark input applied\", target.threadId)),\n ),\n ),\n\n reserveSettlement: (request) =>\n submissionTarget(\"ledger reserve settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve settlement\", target.threadId)),\n ),\n ),\n\n finalizeSettlement: (request) =>\n submissionTarget(\"ledger finalize settlement\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.finalizeSettlement(request)\n : Effect.fail(crossThreadLedgerError(\"ledger finalize settlement\", target.threadId)),\n ),\n ),\n\n markJoined: (request) =>\n submissionTarget(\"ledger mark joined\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markJoined(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark joined\", target.threadId)),\n ),\n ),\n\n revertJoining: (request) =>\n submissionTarget(\"ledger revert joining\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.revertJoining(request)\n : Effect.fail(crossThreadLedgerError(\"ledger revert joining\", target.threadId)),\n ),\n ),\n\n suspend: (request) =>\n submissionTarget(\"ledger suspend\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.suspend(request)\n : Effect.fail(crossThreadLedgerError(\"ledger suspend\", target.threadId)),\n ),\n ),\n\n recordApprovalDecision: (command) =>\n submissionTarget(\"ledger record approval decision\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordApprovalDecision(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record approval decision\", target.threadId),\n ),\n ),\n ),\n\n markUnknown: (request) =>\n submissionTarget(\"ledger mark unknown\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.markUnknown(request)\n : Effect.fail(crossThreadLedgerError(\"ledger mark unknown\", target.threadId)),\n ),\n ),\n\n recordUnknownResolution: (command) =>\n submissionTarget(\"ledger record unknown resolution\", command.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.recordUnknownResolution(command)\n : Effect.fail(\n crossThreadLedgerError(\"ledger record unknown resolution\", target.threadId),\n ),\n ),\n ),\n\n reserveChildBudget: (request) =>\n submissionTarget(\"ledger reserve child budget\", request.parentSubmissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.reserveChildBudget(request)\n : Effect.fail(crossThreadLedgerError(\"ledger reserve child budget\", target.threadId)),\n ),\n ),\n\n // Reservation identities carry no Thread address; the reservation row lives in the\n // parent's own Object and these transitions are parent-lane-local by construction, so\n // they always execute on the local facet (which fails typed for an unknown row).\n attachChildToReservation: local.attachChildToReservation,\n beginChildBudgetRelease: local.beginChildBudgetRelease,\n releaseChildBudget: local.releaseChildBudget,\n\n // The local scan IS the whole worklist: one Thread per Object (durability §5).\n scanNonterminal: local.scanNonterminal,\n\n readAbortIntent: (request) =>\n submissionTarget(\"ledger read abort intent\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.readAbortIntent(request)\n : Effect.fail(crossThreadLedgerError(\"ledger read abort intent\", target.threadId)),\n ),\n ),\n\n loadRecoverySnapshot: (request) =>\n submissionTarget(\"ledger load recovery snapshot\", request.submissionId).pipe(\n Effect.flatMap((target) =>\n target._tag === \"local\"\n ? local.loadRecoverySnapshot(request).pipe(Effect.flatMap(enrichChildAttachments))\n : Effect.fail(crossThreadLedgerError(\"ledger load recovery snapshot\", target.threadId)),\n ),\n ),\n });\n\n return Context.make(SubmissionLedger, routed);\n});\n\nconst makeRoutedStoreServices = Effect.fn(\"DoPortRouting.makeRoutedStoreServices\")(function* (\n options: RoutedPortOptions,\n) {\n const local = yield* ThreadStore;\n const checkpoints = local.checkpoints;\n const transport = yield* ThreadPortTransport;\n const transportCall: TransportCall = makeTransportCall(transport);\n\n const routeFailure =\n (operation: string, target: string) =>\n (error: PortTransportError | PortProtocolError): ThreadStoreError =>\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `Routed ${operation} to the Thread Object owning ${target} failed: ${error.message}`,\n ),\n cause: error,\n });\n\n /** The store twin of `foreignLedgerCall` with `ThreadStoreError` as the base error. */\n const foreignStoreCall = <ResultSchema extends Schema.Top, FailureSchema extends Schema.Top>(\n operation: string,\n target: ThreadId,\n call: PortRequest,\n resultSchema: ResultSchema,\n failureSchema: FailureSchema,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n const isExpectedResult = Schema.is(resultSchema);\n const isExpectedFailure = Schema.is(failureSchema);\n\n return transportCall(target, call).pipe(\n Effect.mapError(routeFailure(operation, target)),\n Effect.flatMap(\n (\n response,\n ): Effect.Effect<ResultSchema[\"Type\"], FailureSchema[\"Type\"] | ThreadStoreError> => {\n if (response._tag === \"PortFailed\") {\n const failure = response.failure;\n\n if (isExpectedFailure(failure)) return Effect.fail(failure);\n if (failure._tag === \"ThreadStoreError\") return Effect.fail(failure);\n\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message: boundPortDiagnostic(\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `out-of-contract failure ${failure._tag}: ${failure.message}`,\n ),\n cause: failure,\n }),\n );\n }\n const result = response.result;\n\n if (!isExpectedResult(result)) {\n return Effect.fail(\n ThreadStoreError.make({\n operation,\n message:\n `The Thread Object owning ${target} answered ${operation} with the ` +\n `mismatched result ${result._tag}.`,\n }),\n );\n }\n\n return Effect.succeed(result);\n },\n ),\n Effect.withSpan(\"DoPortRouting.foreignStoreCall\", {\n attributes: { operation, target },\n }),\n );\n };\n\n const routed = ThreadStore.of({\n materialize: (request) =>\n request.threadId === options.localThreadId\n ? local.materialize(request)\n : foreignStoreCall(\n \"thread materialize\",\n request.threadId,\n StoreMaterializeCall.make({ request }),\n StoreMaterializeResult,\n FenceRejected,\n ).pipe(Effect.asVoid),\n\n append: (request) =>\n request.threadId === options.localThreadId\n ? local.append(request)\n : foreignStoreCall(\n \"thread append\",\n request.threadId,\n StoreAppendCall.make({ request }),\n StoreAppendResult,\n AppendPortFailure,\n ).pipe(Effect.map((reply) => reply.result)),\n\n read: (request) =>\n request.threadId === options.localThreadId\n ? local.read(request)\n : Stream.unwrap(\n foreignStoreCall(\n \"thread read\",\n request.threadId,\n StoreReadPageCall.make({ request }),\n StoreReadPageResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => Stream.fromIterable(reply.records))),\n ),\n\n inspectTail: (request) =>\n request.threadId === options.localThreadId\n ? local.inspectTail(request)\n : foreignStoreCall(\n \"thread inspect tail\",\n request.threadId,\n StoreInspectTailCall.make({ request }),\n StoreInspectTailResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.tail)),\n\n export: (request) =>\n request.threadId === options.localThreadId\n ? local.export(request)\n : foreignStoreCall(\n \"thread export\",\n request.threadId,\n StoreExportCall.make({ request }),\n StoreExportResult,\n ThreadNotMaterialized,\n ).pipe(Effect.map((reply) => reply.export)),\n\n // Observation and checkpoints are lane-local by construction (plan §1.3): the closed\n // route-capable store subset is materialize/append/read/inspectTail/export, and a\n // foreign address on anything else fails fast typed.\n observe: (request) =>\n request.threadId === options.localThreadId\n ? local.observe(request)\n : Stream.unwrap(Effect.fail(crossThreadStoreError(\"thread observe\", request.threadId))),\n\n ...(checkpoints === undefined\n ? {}\n : {\n checkpoints: {\n save: (request) =>\n request.checkpoint.threadId === options.localThreadId\n ? checkpoints.save(request)\n : Effect.fail(\n crossThreadStoreError(\"thread save checkpoint\", request.checkpoint.threadId),\n ),\n load: (request) =>\n request.threadId === options.localThreadId\n ? checkpoints.load(request)\n : Effect.fail(crossThreadStoreError(\"thread load checkpoint\", request.threadId)),\n },\n }),\n });\n\n return Context.make(ThreadStore, routed);\n});\n\n/**\n * Routing decorator over the LOCAL `SubmissionLedger` facet (plan §1.3): a request addressing\n * this Object's Thread executes locally; a route-capable request addressing another\n * Thread is Schema-encoded onto the `ThreadPortTransport` and executed by the\n * owning Object's local facet; any other foreign request fails fast typed. Provide the WP1\n * local facet (`submissionLedgerLayer`/`ledgerLayer`) and a transport to close it.\n */\nexport const routedSubmissionLedgerLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<SubmissionLedger, never, SubmissionLedger | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedLedgerServices(options));\n\n/**\n * Routing decorator over the LOCAL `ThreadStore` facet (plan §1.3): this-thread\n * requests execute locally; foreign materialize/append/read/inspectTail/export travel the\n * transport; foreign observation and checkpoints fail fast typed.\n */\nexport const routedThreadStoreLayer = (\n options: RoutedPortOptions,\n): Layer.Layer<ThreadStore, never, ThreadStore | ThreadPortTransport> =>\n Layer.effectContext(makeRoutedStoreServices(options));\n\n// ---------------------------------------------------------------------------\n// Owner-side execution\n// ---------------------------------------------------------------------------\n\n/** Fold one port operation's typed failures into the uniform response envelope. */\nconst capture = <Failure extends PortFailure>(\n effect: Effect.Effect<PortResult, Failure>,\n): Effect.Effect<PortResponse> =>\n effect.pipe(\n Effect.map((result): PortResponse => PortSucceeded.make({ result })),\n Effect.catch((failure) => Effect.succeed<PortResponse>(PortFailed.make({ failure }))),\n );\n\n/**\n * Execute one decoded port request against THIS Object's LOCAL facets — the owner-side half\n * of the routed ports (plan §1.3). Callers must provide the WP1 local facets, never the\n * routed decorators: the routing layer already established that this Object owns the\n * addressed Thread, and re-routing here could bounce a request between Objects.\n * Failures never escape — every typed port failure becomes a `PortFailed` envelope that\n * re-decodes on the caller side.\n */\nexport const executePortRequest = Effect.fn(\"DoPortRouting.executePortRequest\")(function* (\n request: PortRequest,\n): Effect.fn.Return<PortResponse, never, SubmissionLedger | ThreadStore> {\n switch (request._tag) {\n case \"LedgerAdmit\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .admit(request.request)\n .pipe(Effect.map((result) => LedgerAdmitResult.make({ result }))),\n );\n }\n case \"LedgerMarkReady\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger.markReady(request.request).pipe(Effect.map(() => LedgerMarkReadyResult.make({}))),\n );\n }\n case \"LedgerLookup\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .lookup(request.request)\n .pipe(\n Effect.map((submission) =>\n Option.isSome(submission)\n ? LedgerLookupResult.make({ submission: submission.value })\n : LedgerLookupResult.make({}),\n ),\n ),\n );\n }\n case \"LedgerResolveAdmission\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .resolveAdmission(request.request)\n .pipe(Effect.map((resolution) => LedgerResolveAdmissionResult.make({ resolution }))),\n );\n }\n case \"LedgerRequestAbort\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .requestAbort(request.request)\n .pipe(Effect.map((intent) => LedgerRequestAbortResult.make({ intent }))),\n );\n }\n case \"LedgerRecordChildSettled\": {\n const ledger = yield* SubmissionLedger;\n\n return yield* capture(\n ledger\n .recordChildSettled(request.request)\n .pipe(Effect.map((outcome) => LedgerRecordChildSettledResult.make({ outcome }))),\n );\n }\n case \"StoreMaterialize\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.materialize(request.request).pipe(Effect.map(() => StoreMaterializeResult.make({}))),\n );\n }\n case \"StoreAppend\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .append(request.request)\n .pipe(Effect.map((result) => StoreAppendResult.make({ result }))),\n );\n }\n case \"StoreReadPage\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store.read(request.request).pipe(\n Stream.runCollect,\n Effect.map((records) => StoreReadPageResult.make({ records: [...records] })),\n ),\n );\n }\n case \"StoreInspectTail\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .inspectTail(request.request)\n .pipe(Effect.map((tail) => StoreInspectTailResult.make({ tail }))),\n );\n }\n case \"StoreExport\": {\n const store = yield* ThreadStore;\n\n return yield* capture(\n store\n .export(request.request)\n .pipe(Effect.map((threadExport) => StoreExportResult.make({ export: threadExport }))),\n );\n }\n }\n});\n\n/**\n * The last-resort wire fallback when even encoding a response fails: the literal encoded\n * form of `PortFailed(PortProtocolError)` — tagged classes of bounded strings encode to\n * exactly this shape, so no Schema round trip is needed to produce it.\n */\nconst encodedProtocolFailure = (message: string): unknown => ({\n _tag: \"PortFailed\",\n failure: { _tag: \"PortProtocolError\", message: boundPortDiagnostic(message) },\n});\n\n/**\n * The complete owner-side endpoint body for `portCall` (D-P6-3): decode the wire request,\n * execute it against this Object's LOCAL facets, and answer with the encoded response\n * envelope. Total by construction — a request that cannot be decoded, or a response that\n * cannot be encoded, answers `PortFailed(PortProtocolError)` instead of throwing, so the\n * transport never has to interpret exceptions as protocol answers.\n */\nexport const handleEncodedPortRequest = Effect.fn(\"DoPortRouting.handleEncodedPortRequest\")(\n function* (encoded: unknown): Effect.fn.Return<unknown, never, SubmissionLedger | ThreadStore> {\n const response = yield* decodePortRequest(encoded).pipe(\n Effect.flatMap(executePortRequest),\n Effect.catch((error) =>\n Effect.succeed<PortResponse>(\n PortFailed.make({\n failure: PortProtocolError.make({\n message: boundPortDiagnostic(\n `The port request could not be decoded: ${error.message}`,\n ),\n }),\n }),\n ),\n ),\n );\n\n return yield* encodePortResponse(response).pipe(\n Effect.catch((error) =>\n Effect.succeed(\n encodedProtocolFailure(`The port response could not be encoded: ${error.message}`),\n ),\n ),\n );\n },\n);\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.48","dependencies":{"@effect-agent/core":"0.1.0-beta.48","@effect-agent/thread":"0.1.0-beta.48","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.48","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.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/danieljvdm/effect-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":"@effect-agent/storage-cloudflare","version":"0.1.0-beta.50","dependencies":{"@effect-agent/core":"0.1.0-beta.50","@effect-agent/thread":"0.1.0-beta.50","@effect/platform-browser":"4.0.0-rc.112","@effect/sql-sqlite-do":"4.0.0-rc.112"},"devDependencies":{"@cloudflare/vitest-pool-workers":"0.21.3","@cloudflare/workers-types":"5.20260825.1","@effect-agent/testing":"0.1.0-beta.50","@effect/vitest":"4.0.0-rc.112","effect":"4.0.0-rc.112","typescript":"7.0.2","vite-plus":"0.3.0","vitest":"4.1.11"},"peerDependencies":{"effect":"^4.0.0-rc.112"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./DoMemoryStore":{"types":"./dist/DoMemoryStore.d.mts","default":"./dist/DoMemoryStore.mjs"},"./DoScheduleStore":{"types":"./dist/DoScheduleStore.d.mts","default":"./dist/DoScheduleStore.mjs"},"./DoStorageConfig":{"types":"./dist/DoStorageConfig.d.mts","default":"./dist/DoStorageConfig.mjs"},"./DoStorageError":{"types":"./dist/DoStorageError.d.mts","default":"./dist/DoStorageError.mjs"},"./DoStorageFailpoint":{"types":"./dist/DoStorageFailpoint.d.mts","default":"./dist/DoStorageFailpoint.mjs"},"./DoStorageVersion":{"types":"./dist/DoStorageVersion.d.mts","default":"./dist/DoStorageVersion.mjs"},"./DoSubmissionLedger":{"types":"./dist/DoSubmissionLedger.d.mts","default":"./dist/DoSubmissionLedger.mjs"},"./DoSubscriptionStore":{"types":"./dist/DoSubscriptionStore.d.mts","default":"./dist/DoSubscriptionStore.mjs"},"./DoThreadStore":{"types":"./dist/DoThreadStore.d.mts","default":"./dist/DoThreadStore.mjs"},"./MemoryProtocol":{"types":"./dist/MemoryProtocol.d.mts","default":"./dist/MemoryProtocol.mjs"},"./PortProtocol":{"types":"./dist/PortProtocol.d.mts","default":"./dist/PortProtocol.mjs"},"./PortRouting":{"types":"./dist/PortRouting.d.mts","default":"./dist/PortRouting.mjs"},"./testing/DoStorageFailpointTesting":{"types":"./dist/DoStorageFailpointTesting.d.mts","default":"./dist/DoStorageFailpointTesting.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/danieljvdm/effect-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"}}