@smthrs/journal 0.0.0-stage → 1.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +149 -0
- package/LICENSE +21 -0
- package/README.md +206 -2
- package/dist/cjs/CallFact.d.ts +129 -0
- package/dist/cjs/CallFact.d.ts.map +1 -0
- package/dist/cjs/CallFact.js +106 -0
- package/dist/cjs/CallFact.js.map +7 -0
- package/dist/cjs/Consensus.d.ts +440 -0
- package/dist/cjs/Consensus.d.ts.map +1 -0
- package/dist/cjs/Consensus.js +251 -0
- package/dist/cjs/Consensus.js.map +7 -0
- package/dist/cjs/EngineEvent.d.ts +890 -0
- package/dist/cjs/EngineEvent.d.ts.map +1 -0
- package/dist/cjs/EngineEvent.js +383 -0
- package/dist/cjs/EngineEvent.js.map +7 -0
- package/dist/cjs/ExecutionFact.d.ts +216 -0
- package/dist/cjs/ExecutionFact.d.ts.map +1 -0
- package/dist/cjs/ExecutionFact.js +303 -0
- package/dist/cjs/ExecutionFact.js.map +7 -0
- package/dist/cjs/Journal.d.ts +617 -0
- package/dist/cjs/Journal.d.ts.map +1 -0
- package/dist/cjs/Journal.js +190 -0
- package/dist/cjs/Journal.js.map +7 -0
- package/dist/cjs/JournalEvent.d.ts +421 -0
- package/dist/cjs/JournalEvent.d.ts.map +1 -0
- package/dist/cjs/JournalEvent.js +281 -0
- package/dist/cjs/JournalEvent.js.map +7 -0
- package/dist/cjs/JournalGeneration.d.ts +34 -0
- package/dist/cjs/JournalGeneration.d.ts.map +1 -0
- package/dist/cjs/JournalGeneration.js +72 -0
- package/dist/cjs/JournalGeneration.js.map +7 -0
- package/dist/cjs/JournalMetrics.d.ts +72 -0
- package/dist/cjs/JournalMetrics.d.ts.map +1 -0
- package/dist/cjs/JournalMetrics.js +55 -0
- package/dist/cjs/JournalMetrics.js.map +7 -0
- package/dist/cjs/Migrations.d.ts +42 -0
- package/dist/cjs/Migrations.d.ts.map +1 -0
- package/dist/cjs/Migrations.js +58 -0
- package/dist/cjs/Migrations.js.map +7 -0
- package/dist/cjs/OwnerId.d.ts +40 -0
- package/dist/cjs/OwnerId.d.ts.map +1 -0
- package/dist/cjs/OwnerId.js +40 -0
- package/dist/cjs/OwnerId.js.map +7 -0
- package/dist/cjs/Projection.d.ts +29 -0
- package/dist/cjs/Projection.d.ts.map +1 -0
- package/dist/cjs/Projection.js +25 -0
- package/dist/cjs/Projection.js.map +7 -0
- package/dist/cjs/RedactedLogger.d.ts +121 -0
- package/dist/cjs/RedactedLogger.d.ts.map +1 -0
- package/dist/cjs/RedactedLogger.js +235 -0
- package/dist/cjs/RedactedLogger.js.map +7 -0
- package/dist/cjs/Redaction.d.ts +350 -0
- package/dist/cjs/Redaction.d.ts.map +1 -0
- package/dist/cjs/Redaction.js +928 -0
- package/dist/cjs/Redaction.js.map +7 -0
- package/dist/cjs/SqlConsensus.d.ts +44 -0
- package/dist/cjs/SqlConsensus.d.ts.map +1 -0
- package/dist/cjs/SqlConsensus.js +243 -0
- package/dist/cjs/SqlConsensus.js.map +7 -0
- package/dist/cjs/SqlJournal.d.ts +173 -0
- package/dist/cjs/SqlJournal.d.ts.map +1 -0
- package/dist/cjs/SqlJournal.js +1568 -0
- package/dist/cjs/SqlJournal.js.map +7 -0
- package/dist/cjs/StepFact.d.ts +66 -0
- package/dist/cjs/StepFact.d.ts.map +1 -0
- package/dist/cjs/StepFact.js +68 -0
- package/dist/cjs/StepFact.js.map +7 -0
- package/dist/cjs/index.d.ts +95 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +63 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/JournalInternalFault.d.ts +37 -0
- package/dist/cjs/internal/JournalInternalFault.d.ts.map +1 -0
- package/dist/cjs/internal/JournalInternalFault.js +43 -0
- package/dist/cjs/internal/JournalInternalFault.js.map +7 -0
- package/dist/cjs/migrations/0001_initial.d.ts +15 -0
- package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
- package/dist/cjs/migrations/0001_initial.js +54 -0
- package/dist/cjs/migrations/0001_initial.js.map +7 -0
- package/dist/cjs/migrations/0002_checkpoints.d.ts +27 -0
- package/dist/cjs/migrations/0002_checkpoints.d.ts.map +1 -0
- package/dist/cjs/migrations/0002_checkpoints.js +48 -0
- package/dist/cjs/migrations/0002_checkpoints.js.map +7 -0
- package/dist/cjs/migrations/0003_startup_index.d.ts +15 -0
- package/dist/cjs/migrations/0003_startup_index.d.ts.map +1 -0
- package/dist/cjs/migrations/0003_startup_index.js +40 -0
- package/dist/cjs/migrations/0003_startup_index.js.map +7 -0
- package/dist/cjs/migrations/0004_dedup.d.ts +15 -0
- package/dist/cjs/migrations/0004_dedup.d.ts.map +1 -0
- package/dist/cjs/migrations/0004_dedup.js +57 -0
- package/dist/cjs/migrations/0004_dedup.js.map +7 -0
- package/dist/cjs/migrations/0005_run_event_type.d.ts +15 -0
- package/dist/cjs/migrations/0005_run_event_type.d.ts.map +1 -0
- package/dist/cjs/migrations/0005_run_event_type.js +40 -0
- package/dist/cjs/migrations/0005_run_event_type.js.map +7 -0
- package/dist/cjs/migrations/0006_consensus.d.ts +22 -0
- package/dist/cjs/migrations/0006_consensus.d.ts.map +1 -0
- package/dist/cjs/migrations/0006_consensus.js +84 -0
- package/dist/cjs/migrations/0006_consensus.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/test/Notifying.d.ts +65 -0
- package/dist/cjs/test/Notifying.d.ts.map +1 -0
- package/dist/cjs/test/Notifying.js +62 -0
- package/dist/cjs/test/Notifying.js.map +7 -0
- package/dist/cjs/test/TestJournal.d.ts +43 -0
- package/dist/cjs/test/TestJournal.d.ts.map +1 -0
- package/dist/cjs/test/TestJournal.js +43 -0
- package/dist/cjs/test/TestJournal.js.map +7 -0
- package/dist/esm/CallFact.d.ts +129 -0
- package/dist/esm/CallFact.d.ts.map +1 -0
- package/dist/esm/CallFact.js +96 -0
- package/dist/esm/CallFact.js.map +1 -0
- package/dist/esm/Consensus.d.ts +440 -0
- package/dist/esm/Consensus.d.ts.map +1 -0
- package/dist/esm/Consensus.js +454 -0
- package/dist/esm/Consensus.js.map +1 -0
- package/dist/esm/EngineEvent.d.ts +890 -0
- package/dist/esm/EngineEvent.d.ts.map +1 -0
- package/dist/esm/EngineEvent.js +614 -0
- package/dist/esm/EngineEvent.js.map +1 -0
- package/dist/esm/ExecutionFact.d.ts +216 -0
- package/dist/esm/ExecutionFact.d.ts.map +1 -0
- package/dist/esm/ExecutionFact.js +374 -0
- package/dist/esm/ExecutionFact.js.map +1 -0
- package/dist/esm/Journal.d.ts +617 -0
- package/dist/esm/Journal.d.ts.map +1 -0
- package/dist/esm/Journal.js +323 -0
- package/dist/esm/Journal.js.map +1 -0
- package/dist/esm/JournalEvent.d.ts +421 -0
- package/dist/esm/JournalEvent.d.ts.map +1 -0
- package/dist/esm/JournalEvent.js +517 -0
- package/dist/esm/JournalEvent.js.map +1 -0
- package/dist/esm/JournalGeneration.d.ts +34 -0
- package/dist/esm/JournalGeneration.d.ts.map +1 -0
- package/dist/esm/JournalGeneration.js +65 -0
- package/dist/esm/JournalGeneration.js.map +1 -0
- package/dist/esm/JournalMetrics.d.ts +72 -0
- package/dist/esm/JournalMetrics.d.ts.map +1 -0
- package/dist/esm/JournalMetrics.js +79 -0
- package/dist/esm/JournalMetrics.js.map +1 -0
- package/dist/esm/Migrations.d.ts +42 -0
- package/dist/esm/Migrations.d.ts.map +1 -0
- package/dist/esm/Migrations.js +59 -0
- package/dist/esm/Migrations.js.map +1 -0
- package/dist/esm/OwnerId.d.ts +40 -0
- package/dist/esm/OwnerId.d.ts.map +1 -0
- package/dist/esm/OwnerId.js +33 -0
- package/dist/esm/OwnerId.js.map +1 -0
- package/dist/esm/Projection.d.ts +29 -0
- package/dist/esm/Projection.d.ts.map +1 -0
- package/dist/esm/Projection.js +13 -0
- package/dist/esm/Projection.js.map +1 -0
- package/dist/esm/RedactedLogger.d.ts +121 -0
- package/dist/esm/RedactedLogger.d.ts.map +1 -0
- package/dist/esm/RedactedLogger.js +445 -0
- package/dist/esm/RedactedLogger.js.map +1 -0
- package/dist/esm/Redaction.d.ts +350 -0
- package/dist/esm/Redaction.d.ts.map +1 -0
- package/dist/esm/Redaction.js +1584 -0
- package/dist/esm/Redaction.js.map +1 -0
- package/dist/esm/SqlConsensus.d.ts +44 -0
- package/dist/esm/SqlConsensus.d.ts.map +1 -0
- package/dist/esm/SqlConsensus.js +252 -0
- package/dist/esm/SqlConsensus.js.map +1 -0
- package/dist/esm/SqlJournal.d.ts +173 -0
- package/dist/esm/SqlJournal.d.ts.map +1 -0
- package/dist/esm/SqlJournal.js +1858 -0
- package/dist/esm/SqlJournal.js.map +1 -0
- package/dist/esm/StepFact.d.ts +66 -0
- package/dist/esm/StepFact.d.ts.map +1 -0
- package/dist/esm/StepFact.js +50 -0
- package/dist/esm/StepFact.js.map +1 -0
- package/dist/esm/index.d.ts +95 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +95 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/JournalInternalFault.d.ts +37 -0
- package/dist/esm/internal/JournalInternalFault.d.ts.map +1 -0
- package/dist/esm/internal/JournalInternalFault.js +28 -0
- package/dist/esm/internal/JournalInternalFault.js.map +1 -0
- package/dist/esm/migrations/0001_initial.d.ts +15 -0
- package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
- package/dist/esm/migrations/0001_initial.js +32 -0
- package/dist/esm/migrations/0001_initial.js.map +1 -0
- package/dist/esm/migrations/0002_checkpoints.d.ts +27 -0
- package/dist/esm/migrations/0002_checkpoints.d.ts.map +1 -0
- package/dist/esm/migrations/0002_checkpoints.js +38 -0
- package/dist/esm/migrations/0002_checkpoints.js.map +1 -0
- package/dist/esm/migrations/0003_startup_index.d.ts +15 -0
- package/dist/esm/migrations/0003_startup_index.d.ts.map +1 -0
- package/dist/esm/migrations/0003_startup_index.js +18 -0
- package/dist/esm/migrations/0003_startup_index.js.map +1 -0
- package/dist/esm/migrations/0004_dedup.d.ts +15 -0
- package/dist/esm/migrations/0004_dedup.d.ts.map +1 -0
- package/dist/esm/migrations/0004_dedup.js +38 -0
- package/dist/esm/migrations/0004_dedup.js.map +1 -0
- package/dist/esm/migrations/0005_run_event_type.d.ts +15 -0
- package/dist/esm/migrations/0005_run_event_type.d.ts.map +1 -0
- package/dist/esm/migrations/0005_run_event_type.js +18 -0
- package/dist/esm/migrations/0005_run_event_type.js.map +1 -0
- package/dist/esm/migrations/0006_consensus.d.ts +22 -0
- package/dist/esm/migrations/0006_consensus.d.ts.map +1 -0
- package/dist/esm/migrations/0006_consensus.js +69 -0
- package/dist/esm/migrations/0006_consensus.js.map +1 -0
- package/dist/esm/test/Notifying.d.ts +65 -0
- package/dist/esm/test/Notifying.d.ts.map +1 -0
- package/dist/esm/test/Notifying.js +62 -0
- package/dist/esm/test/Notifying.js.map +1 -0
- package/dist/esm/test/TestJournal.d.ts +43 -0
- package/dist/esm/test/TestJournal.d.ts.map +1 -0
- package/dist/esm/test/TestJournal.js +27 -0
- package/dist/esm/test/TestJournal.js.map +1 -0
- package/docs/README.md +164 -0
- package/docs/api.md +639 -0
- package/docs/concepts/compaction.md +157 -0
- package/docs/concepts/idempotency.md +127 -0
- package/docs/concepts/owner-fence.md +124 -0
- package/docs/concepts/redaction.md +218 -0
- package/docs/concepts/state-event-authority.md +159 -0
- package/docs/concepts/two-channels.md +167 -0
- package/docs/guides/commit-state-and-entry.md +114 -0
- package/docs/guides/compact-a-run.md +134 -0
- package/docs/guides/fold-a-projection.md +106 -0
- package/docs/guides/read-a-run.md +139 -0
- package/docs/guides/redact-log-output.md +94 -0
- package/docs/guides/testing.md +124 -0
- package/docs/guides/write-lifecycle-events.md +110 -0
- package/docs/installation.md +133 -0
- package/docs/quickstart.md +143 -0
- package/docs/troubleshooting.md +214 -0
- package/package.json +263 -3
- package/src/CallFact.ts +117 -0
- package/src/Consensus.ts +683 -0
- package/src/EngineEvent.ts +823 -0
- package/src/ExecutionFact.ts +433 -0
- package/src/Journal.ts +688 -0
- package/src/JournalEvent.ts +654 -0
- package/src/JournalGeneration.ts +77 -0
- package/src/JournalMetrics.ts +89 -0
- package/src/Migrations.ts +62 -0
- package/src/OwnerId.ts +42 -0
- package/src/Projection.ts +31 -0
- package/src/RedactedLogger.ts +483 -0
- package/src/Redaction.ts +1784 -0
- package/src/SqlConsensus.ts +344 -0
- package/src/SqlJournal.ts +2732 -0
- package/src/StepFact.ts +69 -0
- package/src/index.ts +109 -0
- package/src/internal/JournalInternalFault.ts +40 -0
- package/src/migrations/0001_initial.ts +41 -0
- package/src/migrations/0002_checkpoints.ts +46 -0
- package/src/migrations/0003_startup_index.ts +19 -0
- package/src/migrations/0004_dedup.ts +43 -0
- package/src/migrations/0005_run_event_type.ts +19 -0
- package/src/migrations/0006_consensus.ts +83 -0
- package/src/test/Notifying.ts +101 -0
- package/src/test/TestJournal.ts +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlConsensus.js","sourceRoot":"","sources":["../../src/SqlConsensus.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The default database-backed consensus strategy.\n *\n * This is the run store's former `flows_runs` ownership compare-and-swap\n * relocated: the owner tuple, the two-phase claim columns, claim recovery, and\n * the grant timestamp are the private schema of one strategy — the\n * `flows_consensus_leases` table — instead of a public contract on the run\n * row. The run row still mirrors the outcome, but the lease is what\n * arbitrates.\n *\n * Commit-time admission (R3) is exact: `guard` is a plain SELECT that joins\n * the caller's open write transaction — `DurableWriter` serializes write\n * transactions, so no reclaim can commit between the guard read and the\n * statements beside it — and every mutating operation runs through\n * `DurableWriter.write`, joining an enclosing transaction as a savepoint.\n * Prior art: Temporal's shard `rangeID` check\n * (`reference/temporal/service/history/shard/context_impl.go`,\n * `renewRangeLocked`).\n *\n * Governing design: `packages/smithers/flows/journal/docs/concepts/owner-fence.md`.\n *\n * @since 1.0.0\n */\n\nimport * as Dialect from \"@smthrs/database/Dialect\"\nimport { DurableWriter } from \"@smthrs/database/DurableWriter\"\nimport * as Duration from \"effect/Duration\"\nimport * as Effect from \"effect/Effect\"\nimport * as Layer from \"effect/Layer\"\nimport * as SqlClient from \"effect/unstable/sql/SqlClient\"\nimport {\n type ActivateOutcome,\n type Claimed,\n type ClaimOutcome,\n Consensus,\n ConsensusError,\n fenceLost,\n type HeartbeatOutcome,\n heartbeatStaleAfter,\n type LivenessEvidence,\n matchesEvidence,\n type RecoverOutcome,\n type Rejected,\n type RejectionReason,\n type Service\n} from \"./Consensus.ts\"\nimport type { OwnerId } from \"./OwnerId.ts\"\n\nconst staleAfterMs = Duration.toMillis(heartbeatStaleAfter)\n\nconst rejected = (reason: RejectionReason): Rejected => ({ _tag: \"Rejected\", reason })\nconst claimed = (grantedAtMs: number): Claimed => ({ _tag: \"Claimed\", grantedAtMs })\nconst lost = { _tag: \"Lost\" } as const\nconst activated = { _tag: \"Activated\" } as const\nconst recovered = { _tag: \"Recovered\" } as const\n\ninterface LeaseRow {\n readonly owner_host_id: string | null\n readonly owner_pid: number | null\n readonly owner_nonce: string | null\n readonly claim_host_id: string | null\n readonly claim_pid: number | null\n readonly claim_nonce: string | null\n}\n\n/**\n * Constructs the database-backed strategy over the context's SQL client and\n * durable writer.\n *\n * @since 1.0.0\n * @category constructors\n */\nexport const make: Effect.Effect<Service, never, DurableWriter | SqlClient.SqlClient> = Effect.gen(function*() {\n const sql = yield* Effect.service(SqlClient.SqlClient)\n const writer = yield* DurableWriter\n\n const strategyError = (cause: unknown): ConsensusError =>\n new ConsensusError({\n code: \"persistence_failed\",\n message: \"consensus lease operation failed\",\n cause\n })\n\n // The original cause is preserved through the wrapper so an enclosing\n // `DurableWriter.write`'s retry classification still sees a transient\n // conflict raised by a savepoint-nested lease statement.\n const write = <A>(\n body: Effect.Effect<A, unknown>\n ): Effect.Effect<A, ConsensusError> =>\n writer.write(body).pipe(Effect.mapError((cause) => cause instanceof ConsensusError ? cause : strategyError(cause)))\n\n const leaseOf = (runId: string) =>\n sql<LeaseRow>`\n SELECT owner_host_id, owner_pid, owner_nonce, claim_host_id, claim_pid, claim_nonce\n FROM flows_consensus_leases\n WHERE run_id = ${runId}\n `\n\n const prune = (runId: string) =>\n sql`\n DELETE FROM flows_consensus_leases\n WHERE run_id = ${runId} AND owner_host_id IS NULL AND claim_host_id IS NULL\n `\n\n const claim: Service[\"claim\"] = Effect.fn(\"Consensus.claim\")((\n runId: string,\n claimant: OwnerId,\n nowMs: number\n ) =>\n write(Effect.gen(function*() {\n const rows = yield* sql<{ readonly run_id: string }>`\n INSERT INTO flows_consensus_leases (run_id, claim_host_id, claim_pid, claim_nonce, claimed_at_ms)\n VALUES (${runId}, ${claimant.hostId}, ${claimant.pid}, ${claimant.nonce}, ${nowMs})\n ON CONFLICT (run_id) DO UPDATE SET\n claim_host_id = excluded.claim_host_id,\n claim_pid = excluded.claim_pid,\n claim_nonce = excluded.claim_nonce,\n claimed_at_ms = excluded.claimed_at_ms\n WHERE flows_consensus_leases.claim_host_id IS NULL\n AND flows_consensus_leases.owner_host_id IS NULL\n RETURNING run_id\n `\n if (rows.length > 0) return claimed(nowMs)\n // The upsert only misses on a conflicting row, so the lease exists and\n // holds a claim, an owner, or both.\n const lease = (yield* leaseOf(runId))[0]!\n return lease.claim_host_id !== null ? rejected(\"already_claimed\") : rejected(\"owner_held\")\n }))\n )\n\n const activate: Service[\"activate\"] = Effect.fn(\"Consensus.activate\")((\n runId: string,\n owner: OwnerId,\n grantedAtMs: number,\n nowMs: number\n ) =>\n write(Effect.gen(function*() {\n const rows = yield* sql<{ readonly run_id: string }>`\n UPDATE flows_consensus_leases\n SET\n owner_host_id = ${owner.hostId},\n owner_pid = ${owner.pid},\n owner_nonce = ${owner.nonce},\n granted_at_ms = ${grantedAtMs},\n heartbeat_at_ms = ${nowMs},\n claim_host_id = NULL,\n claim_pid = NULL,\n claim_nonce = NULL,\n claimed_at_ms = NULL\n WHERE run_id = ${runId}\n AND claim_host_id = ${owner.hostId}\n AND claim_pid = ${owner.pid}\n AND claim_nonce = ${owner.nonce}\n AND claimed_at_ms = ${grantedAtMs}\n RETURNING run_id\n `\n return (rows.length > 0 ? activated : lost) satisfies ActivateOutcome\n }))\n )\n\n const heartbeat: Service[\"heartbeat\"] = Effect.fn(\"Consensus.heartbeat\")((\n runId: string,\n owner: OwnerId,\n nowMs: number\n ) =>\n write(Effect.gen(function*() {\n // Monotonic: a pulse delayed past a newer one from the same owner never\n // moves the lease backwards and never makes a live run look stale.\n const rows = yield* sql<{ readonly heartbeat_at_ms: number }>`\n UPDATE flows_consensus_leases\n SET heartbeat_at_ms = ${Dialect.greatest(sql)}(heartbeat_at_ms, ${nowMs})\n WHERE run_id = ${runId}\n AND owner_host_id = ${owner.hostId}\n AND owner_pid = ${owner.pid}\n AND owner_nonce = ${owner.nonce}\n RETURNING heartbeat_at_ms\n `\n const row = rows[0]\n return (row === undefined\n ? lost\n : { _tag: \"Renewed\", heartbeatAtMs: Number(row.heartbeat_at_ms) }) satisfies HeartbeatOutcome\n }))\n )\n\n const reconfirm: Service[\"reconfirm\"] = Effect.fn(\"Consensus.reconfirm\")((\n runId: string,\n owner: OwnerId,\n nowMs: number\n ) =>\n write(Effect.gen(function*() {\n // A pending steal has already reserved the lease, even before activation.\n // Compare both owner and claim in the same update as the renewal.\n const rows = yield* sql<{ readonly heartbeat_at_ms: number }>`\n UPDATE flows_consensus_leases\n SET heartbeat_at_ms = ${Dialect.greatest(sql)}(heartbeat_at_ms, ${nowMs})\n WHERE run_id = ${runId}\n AND owner_host_id = ${owner.hostId}\n AND owner_pid = ${owner.pid}\n AND owner_nonce = ${owner.nonce}\n AND claim_host_id IS NULL\n RETURNING heartbeat_at_ms\n `\n const row = rows[0]\n return (row === undefined\n ? lost\n : { _tag: \"Renewed\", heartbeatAtMs: Number(row.heartbeat_at_ms) }) satisfies HeartbeatOutcome\n }))\n )\n\n const release: Service[\"release\"] = Effect.fn(\"Consensus.release\")((runId: string, owner: OwnerId) =>\n write(Effect.gen(function*() {\n yield* sql`\n UPDATE flows_consensus_leases\n SET claim_host_id = NULL, claim_pid = NULL, claim_nonce = NULL, claimed_at_ms = NULL\n WHERE run_id = ${runId}\n AND claim_host_id = ${owner.hostId}\n AND claim_pid = ${owner.pid}\n AND claim_nonce = ${owner.nonce}\n `\n yield* sql`\n UPDATE flows_consensus_leases\n SET owner_host_id = NULL, owner_pid = NULL, owner_nonce = NULL,\n granted_at_ms = NULL, heartbeat_at_ms = NULL\n WHERE run_id = ${runId}\n AND owner_host_id = ${owner.hostId}\n AND owner_pid = ${owner.pid}\n AND owner_nonce = ${owner.nonce}\n `\n yield* prune(runId)\n }))\n )\n\n const steal: Service[\"steal\"] = Effect.fn(\"Consensus.steal\")((\n runId: string,\n claimant: OwnerId,\n nowMs: number,\n evidence: LivenessEvidence\n ) =>\n Effect.suspend((): Effect.Effect<ClaimOutcome, ConsensusError> => {\n if (!matchesEvidence(evidence.expectedOwner, claimant, nowMs, evidence)) {\n return Effect.succeed(rejected(\"evidence_invalid\"))\n }\n return write(Effect.gen(function*() {\n const rows = yield* sql<{ readonly run_id: string }>`\n UPDATE flows_consensus_leases\n SET\n claim_host_id = ${claimant.hostId},\n claim_pid = ${claimant.pid},\n claim_nonce = ${claimant.nonce},\n claimed_at_ms = ${nowMs}\n WHERE run_id = ${runId}\n AND owner_host_id = ${evidence.expectedOwner.hostId}\n AND owner_pid = ${evidence.expectedOwner.pid}\n AND owner_nonce = ${evidence.expectedOwner.nonce}\n AND heartbeat_at_ms < ${nowMs - staleAfterMs}\n AND claim_host_id IS NULL\n RETURNING run_id\n `\n if (rows.length > 0) return claimed(nowMs)\n const lease = (yield* leaseOf(runId))[0]\n if (lease !== undefined && lease.claim_host_id !== null) return rejected(\"already_claimed\")\n if (\n lease === undefined ||\n lease.owner_host_id !== evidence.expectedOwner.hostId ||\n Number(lease.owner_pid) !== evidence.expectedOwner.pid ||\n lease.owner_nonce !== evidence.expectedOwner.nonce\n ) {\n // A run nobody owns, or one owned by somebody else, has no owner\n // this evidence could disprove.\n return rejected(\"evidence_invalid\")\n }\n return rejected(\"owner_live\")\n }))\n })\n )\n\n const recover: Service[\"recover\"] = Effect.fn(\"Consensus.recover\")((\n runId: string,\n staleClaimant: OwnerId,\n grantedAtMs: number,\n observer: OwnerId,\n nowMs: number,\n evidence: LivenessEvidence\n ) =>\n Effect.suspend((): Effect.Effect<RecoverOutcome, ConsensusError> => {\n if (!matchesEvidence(staleClaimant, observer, nowMs, evidence)) {\n return Effect.succeed(rejected(\"evidence_invalid\"))\n }\n return write(Effect.gen(function*() {\n const rows = yield* sql<{ readonly run_id: string }>`\n UPDATE flows_consensus_leases\n SET claim_host_id = NULL, claim_pid = NULL, claim_nonce = NULL, claimed_at_ms = NULL\n WHERE run_id = ${runId}\n AND claim_host_id = ${staleClaimant.hostId}\n AND claim_pid = ${staleClaimant.pid}\n AND claim_nonce = ${staleClaimant.nonce}\n AND claimed_at_ms = ${grantedAtMs}\n AND claimed_at_ms < ${nowMs - staleAfterMs}\n RETURNING run_id\n `\n if (rows.length > 0) {\n yield* prune(runId)\n return recovered\n }\n const matches = yield* sql<{ readonly run_id: string }>`\n SELECT run_id FROM flows_consensus_leases\n WHERE run_id = ${runId}\n AND claim_host_id = ${staleClaimant.hostId}\n AND claim_pid = ${staleClaimant.pid}\n AND claim_nonce = ${staleClaimant.nonce}\n AND claimed_at_ms = ${grantedAtMs}\n `\n // The exact claim survived the compare-and-swap only because it is\n // not yet stale; anything else means the claim moved on.\n return matches.length > 0 ? rejected(\"claim_fresh\") : rejected(\"claim_changed\")\n }))\n })\n )\n\n const guard: Service[\"guard\"] = Effect.fn(\"Consensus.guard\")((runId: string, owner: OwnerId) =>\n write(Effect.gen(function*() {\n const held = yield* sql<{ readonly ok: number }>`\n SELECT 1 AS ok FROM flows_consensus_leases\n WHERE run_id = ${runId}\n AND owner_host_id = ${owner.hostId}\n AND owner_pid = ${owner.pid}\n AND owner_nonce = ${owner.nonce}\n `\n if (held.length === 0) {\n return yield* Effect.fail(fenceLost(runId, owner))\n }\n }))\n )\n\n return Consensus.of({ claim, activate, heartbeat, reconfirm, release, steal, recover, guard })\n})\n\n/**\n * Provides the database-backed strategy.\n *\n * @since 1.0.0\n * @category layers\n */\nexport const layer: Layer.Layer<Consensus, never, DurableWriter | SqlClient.SqlClient> = Layer.effect(Consensus, make)\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed logical journal with durable and lossy channels.
|
|
3
|
+
*
|
|
4
|
+
* Lossy telemetry events remain optimistic until the single scoped writer
|
|
5
|
+
* commits them, so a process crash can lose accepted-but-unwritten telemetry.
|
|
6
|
+
* Lifecycle events use `emitDurable` and return after commit, except inside
|
|
7
|
+
* `transact`, where their savepoint completes before the outer commit.
|
|
8
|
+
*
|
|
9
|
+
* Governing design: `packages/smithers/flows/journal/docs/concepts/two-channels.md`.
|
|
10
|
+
* Prior-art decision: `packages/smithers/flows/sync/docs/concepts/replay-then-follow.md`.
|
|
11
|
+
*
|
|
12
|
+
* The replay-then-follow stream follows Effect's `EventJournal` and OpenCode's
|
|
13
|
+
* upstream event stream design. The bounded send queue deliberately deviates
|
|
14
|
+
* from their synchronous durable writes by reserving a provisional per-run
|
|
15
|
+
* sequence before admission. Both channels finalize canonical order at commit.
|
|
16
|
+
* SQLite retry and transaction behavior comes through `@smthrs/database`.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
import { DurableWriter } from "@smthrs/database/DurableWriter";
|
|
21
|
+
import * as Effect from "effect/Effect";
|
|
22
|
+
import * as Layer from "effect/Layer";
|
|
23
|
+
import * as Scope from "effect/Scope";
|
|
24
|
+
import * as SqlClient from "effect/unstable/sql/SqlClient";
|
|
25
|
+
import { Consensus } from "./Consensus.ts";
|
|
26
|
+
import { Journal, JournalError, type OverflowPolicy, type Service } from "./Journal.ts";
|
|
27
|
+
import { RunId, type Seq } from "./JournalEvent.ts";
|
|
28
|
+
import * as Redaction from "./Redaction.ts";
|
|
29
|
+
/**
|
|
30
|
+
* Automatic checkpoint-and-compact policy for the SQL journal.
|
|
31
|
+
*
|
|
32
|
+
* Disabled unless set on {@link SqlJournalOptions}. Once a run's committed
|
|
33
|
+
* entry count reaches `entryThreshold`, the journal asks `capture` for the
|
|
34
|
+
* caller's replay state at the run's durable tail, writes it as a checkpoint
|
|
35
|
+
* at that sequence, and compacts the entries strictly below it.
|
|
36
|
+
*
|
|
37
|
+
* Both channels run the policy after their allocation permit is free. Lossy
|
|
38
|
+
* commits fork scoped maintenance so the sole queue consumer keeps draining;
|
|
39
|
+
* durable emits await their attempt. `flush` awaits registered maintenance.
|
|
40
|
+
* `capture` may read or emit without blocking unrelated allocation. A capture is interrupted
|
|
41
|
+
* after 30 seconds so caller code cannot wedge journal admission indefinitely.
|
|
42
|
+
*
|
|
43
|
+
* A failed or refused attempt (a live stream behind the boundary, a capture
|
|
44
|
+
* failure) is logged at warning, damped for `entryThreshold`
|
|
45
|
+
* further committed entries, and never surfaced to the emit that triggered
|
|
46
|
+
* it.
|
|
47
|
+
*
|
|
48
|
+
* @category models
|
|
49
|
+
* @since 0.1.0
|
|
50
|
+
*/
|
|
51
|
+
export interface CompactionPolicy {
|
|
52
|
+
readonly entryThreshold: number;
|
|
53
|
+
readonly capture: (runId: RunId, upTo: Seq) => Effect.Effect<unknown, unknown>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* SQL journal queue and batching options.
|
|
57
|
+
*
|
|
58
|
+
* @category models
|
|
59
|
+
* @since 0.1.0
|
|
60
|
+
*/
|
|
61
|
+
export interface SqlJournalOptions {
|
|
62
|
+
/**
|
|
63
|
+
* Bound on the number of ENTRIES held in two places at once: the lossy
|
|
64
|
+
* admission queue, where `overflow` decides what happens when it is full,
|
|
65
|
+
* and the sliding `changes` buffer, where a slow subscriber silently loses
|
|
66
|
+
* the entries that fall out of it.
|
|
67
|
+
*
|
|
68
|
+
* It bounds entries, not bytes. Set {@link SqlJournalOptions.maxEntryBytes}
|
|
69
|
+
* to bound the size of one entry as well; with it unset a handful of very
|
|
70
|
+
* large payloads is still the memory bill.
|
|
71
|
+
*/
|
|
72
|
+
readonly capacity: number;
|
|
73
|
+
/** Policy applied when the lossy admission queue is full. */
|
|
74
|
+
readonly overflow: OverflowPolicy;
|
|
75
|
+
/** Entries the queued writer commits per transaction. */
|
|
76
|
+
readonly batchSize?: number | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Upper bound on the in-process source-event index, the map that answers
|
|
79
|
+
* producer idempotency from memory.
|
|
80
|
+
*
|
|
81
|
+
* The index is a cache, never the authority, and a MISS costs a receipt, not
|
|
82
|
+
* correctness. On a miss for an explicit producer sequence the entry is
|
|
83
|
+
* admitted optimistically without any read: `emitLossy` returns `Accepted`
|
|
84
|
+
* where a resident entry would have returned `Duplicate`, and the insert
|
|
85
|
+
* collapses onto the committed row through the unique index
|
|
86
|
+
* `(run_id, source_id, source_seq)` rather than doubling it. A CHANGED retry
|
|
87
|
+
* behind an evicted entry therefore surfaces `idempotency_conflict` from
|
|
88
|
+
* `flush`, not from the emit. See `admitFromIndex` for why the read is gone:
|
|
89
|
+
* `emitLossy` is called from inside other write transactions, and the
|
|
90
|
+
* pre-admission SELECT deadlocked `@smthrs/agent`'s exit flush against the
|
|
91
|
+
* engine's own writer, measured at over 120 s versus about half a second
|
|
92
|
+
* without it.
|
|
93
|
+
*
|
|
94
|
+
* Bounding the cache keeps startup decode and resident memory O(bound) rather
|
|
95
|
+
* than O(total events ever written), mirroring Temporal's refusal to hold
|
|
96
|
+
* unbounded history in a shard (`service/history`). The separate
|
|
97
|
+
* sequence-floor maps start empty and grow only with runs and producers this
|
|
98
|
+
* layer instance touches; they are lazy, not governed by this bound.
|
|
99
|
+
*
|
|
100
|
+
* Idempotency compares canonical persisted JSON after redaction. Two inputs
|
|
101
|
+
* that redact to the same value are therefore the same event, and JSON's
|
|
102
|
+
* encoding intentionally treats `NaN` and `null` as the same `null` value.
|
|
103
|
+
*/
|
|
104
|
+
readonly sourceEventCache?: number | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Largest single entry the journal admits, measured in UTF-8 bytes of the
|
|
107
|
+
* encoded `payload` plus `meta`.
|
|
108
|
+
*
|
|
109
|
+
* Unset by default, which means unbounded: `capacity` bounds how MANY entries
|
|
110
|
+
* the admission queue and the `changes` buffer hold, never how large one is,
|
|
111
|
+
* so without this a handful of multi-megabyte payloads is the memory bill,
|
|
112
|
+
* and every one of them is replayed to each sync subscriber and time-travel
|
|
113
|
+
* consumer on every read. Set it where the journal is fed by untrusted or
|
|
114
|
+
* unbounded producers.
|
|
115
|
+
*
|
|
116
|
+
* The bound is checked after encoding and BEFORE any sequence is allocated or
|
|
117
|
+
* anything is queued, so a refused entry costs no sequence and leaves no gap.
|
|
118
|
+
* An entry over the bound fails `invalid_event`.
|
|
119
|
+
*/
|
|
120
|
+
readonly maxEntryBytes?: number | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* Scrub applied to every `payload` and `meta` before it is encoded for
|
|
123
|
+
* persistence.
|
|
124
|
+
*
|
|
125
|
+
* Journal rows are permanent and are replayed verbatim to sync subscribers
|
|
126
|
+
* and time-travel consumers, so a credential that reaches `payload_json` is
|
|
127
|
+
* a durable, broadly readable leak. Redaction therefore defaults to
|
|
128
|
+
* `Redaction.make()`; pass `Redaction.makeNoop()` to persist payloads
|
|
129
|
+
* verbatim by choice.
|
|
130
|
+
*/
|
|
131
|
+
readonly redact?: Redaction.Redactor | undefined;
|
|
132
|
+
/**
|
|
133
|
+
* Automatic checkpoint-and-compact policy. Off by default: without it the
|
|
134
|
+
* journal never deletes an entry, and checkpointing stays a caller-driven
|
|
135
|
+
* `checkpoint` / `compact` call.
|
|
136
|
+
*/
|
|
137
|
+
readonly compaction?: CompactionPolicy | undefined;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Constructs the SQL journal over the context's SQL client, durable writer,
|
|
141
|
+
* and consensus strategy.
|
|
142
|
+
*
|
|
143
|
+
* `emitLossy` validates and admits telemetry to the non-blocking queue;
|
|
144
|
+
* `emitDurable` allocates and commits inside the database transaction, fenced
|
|
145
|
+
* through `Consensus.guard` in that same transaction.
|
|
146
|
+
*
|
|
147
|
+
* @category constructors
|
|
148
|
+
* @since 1.0.0
|
|
149
|
+
*/
|
|
150
|
+
export declare const make: (options: SqlJournalOptions) => Effect.Effect<Service, JournalError, Consensus | DurableWriter | SqlClient.SqlClient | Scope.Scope>;
|
|
151
|
+
/**
|
|
152
|
+
* Provides the SQL journal over an explicitly injected consensus strategy.
|
|
153
|
+
*
|
|
154
|
+
* The strategy in context arbitrates the owner fence: `emitDurable`,
|
|
155
|
+
* `checkpoint`, and `compact` join its `guard` inside their write
|
|
156
|
+
* transaction. Provide the SAME strategy instance to every service that must
|
|
157
|
+
* agree on ownership — `RunStore.layerWith` in particular — because
|
|
158
|
+
* `Consensus.layerLocal` keeps its leases per layer build.
|
|
159
|
+
*
|
|
160
|
+
* @category layers
|
|
161
|
+
* @since 1.0.0
|
|
162
|
+
*/
|
|
163
|
+
export declare const layerWith: (options: SqlJournalOptions) => Layer.Layer<Journal, JournalError, Consensus | DurableWriter | SqlClient.SqlClient>;
|
|
164
|
+
/**
|
|
165
|
+
* Provides the SQL journal fenced by the database-backed strategy,
|
|
166
|
+
* `SqlConsensus`, over the same client. Use {@link layerWith} to inject a
|
|
167
|
+
* different strategy.
|
|
168
|
+
*
|
|
169
|
+
* @category layers
|
|
170
|
+
* @since 0.1.0
|
|
171
|
+
*/
|
|
172
|
+
export declare const layer: (options: SqlJournalOptions) => Layer.Layer<Journal, JournalError, DurableWriter | SqlClient.SqlClient>;
|
|
173
|
+
//# sourceMappingURL=SqlJournal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SqlJournal.d.ts","sourceRoot":"","sources":["../../src/SqlJournal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAA8B,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAI1F,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAOrC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAGrC,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAA;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,EASL,OAAO,EACP,YAAY,EAGZ,KAAK,cAAc,EACnB,KAAK,OAAO,EAEb,MAAM,cAAc,CAAA;AACrB,OAAO,EAKL,KAAK,EACL,KAAK,GAAG,EAGT,MAAM,mBAAmB,CAAA;AAK1B,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAM3C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;CAC/E;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,yDAAyD;IACzD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9C;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3C;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAA;IAChD;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACnD;AA+WD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,IAAI,GACf,SAAS,iBAAiB,KACzB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAqlEjG,CAAA;AAEJ;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,GACpB,SAAS,iBAAiB,KACzB,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,GAAG,aAAa,GAAG,SAAS,CAAC,SAAS,CAC/C,CAAA;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,GAChB,SAAS,iBAAiB,KACzB,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC,SAAS,CACb,CAAA"}
|