@smthrs/journal 0.0.0-stage → 1.0.0-rc.4
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,617 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logical journal contract with durable lifecycle and lossy telemetry channels.
|
|
3
|
+
*
|
|
4
|
+
* The ownership fence and the lossless `emitDurable` / lossy `emitLossy`
|
|
5
|
+
* split are described at https://journal.smithers.sh/concepts/owner-fence/
|
|
6
|
+
* and https://journal.smithers.sh/concepts/two-channels/.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.1.0
|
|
9
|
+
*/
|
|
10
|
+
import * as Context from "effect/Context";
|
|
11
|
+
import * as Effect from "effect/Effect";
|
|
12
|
+
import * as Layer from "effect/Layer";
|
|
13
|
+
import type * as Option from "effect/Option";
|
|
14
|
+
import * as PubSub from "effect/PubSub";
|
|
15
|
+
import * as Schema from "effect/Schema";
|
|
16
|
+
import type * as Scope from "effect/Scope";
|
|
17
|
+
import * as Stream from "effect/Stream";
|
|
18
|
+
import { Entry, RunId } from "./JournalEvent.ts";
|
|
19
|
+
import type { Input } from "./JournalEvent.ts";
|
|
20
|
+
import type { OwnerId } from "./OwnerId.ts";
|
|
21
|
+
import type { Projection } from "./Projection.ts";
|
|
22
|
+
/**
|
|
23
|
+
* Defers a fold/cache update until the outermost durable write commits.
|
|
24
|
+
* Returns false without running it when no managed commit is available.
|
|
25
|
+
* Failed savepoints and retried transaction attempts never publish the update.
|
|
26
|
+
*
|
|
27
|
+
* @category transactions
|
|
28
|
+
* @since 1.0.0
|
|
29
|
+
*/
|
|
30
|
+
export { afterCommit } from "@smthrs/database/DurableWriter";
|
|
31
|
+
/**
|
|
32
|
+
* Stable error codes returned by journal operations.
|
|
33
|
+
*
|
|
34
|
+
* `read_failed` identifies a database failure on a durable read path. Callers
|
|
35
|
+
* can distinguish that retryable storage condition from an unclassified
|
|
36
|
+
* `unknown` journal defect.
|
|
37
|
+
*
|
|
38
|
+
* @category models
|
|
39
|
+
* @since 0.1.0
|
|
40
|
+
*/
|
|
41
|
+
export declare const JournalErrorCode: Schema.Literals<readonly ["invalid_event", "idempotency_conflict", "sequence_conflict", "fence_lost", "queue_overflow", "journal_closed", "sink_failed", "read_failed", "decode_failed", "projection_failed", "checkpoint_invalid", "reader_behind", "compacted", "unknown"]>;
|
|
42
|
+
/**
|
|
43
|
+
* Stable error codes returned by journal operations.
|
|
44
|
+
*
|
|
45
|
+
* @category models
|
|
46
|
+
* @since 0.1.0
|
|
47
|
+
*/
|
|
48
|
+
export type JournalErrorCode = typeof JournalErrorCode.Type;
|
|
49
|
+
declare const JournalError_base: Schema.Class<JournalError, Schema.TaggedStruct<"@smthrs/journal/JournalError", {
|
|
50
|
+
readonly code: Schema.Literals<readonly ["invalid_event", "idempotency_conflict", "sequence_conflict", "fence_lost", "queue_overflow", "journal_closed", "sink_failed", "read_failed", "decode_failed", "projection_failed", "checkpoint_invalid", "reader_behind", "compacted", "unknown"]>;
|
|
51
|
+
readonly message: Schema.String;
|
|
52
|
+
readonly cause: Schema.optional<Schema.Unknown>;
|
|
53
|
+
readonly checkpointSeq: Schema.optional<Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">>;
|
|
54
|
+
}>, import("effect/Cause").YieldableError>;
|
|
55
|
+
/**
|
|
56
|
+
* Error raised by journal admission, persistence, replay, or projection.
|
|
57
|
+
*
|
|
58
|
+
* `checkpointSeq` is set on the compaction-aware codes: on `compacted` it is
|
|
59
|
+
* the run's compaction floor, the checkpoint sequence a reader must resync
|
|
60
|
+
* from, and on `reader_behind` it is the checkpoint a compaction refused to
|
|
61
|
+
* truncate below.
|
|
62
|
+
*
|
|
63
|
+
* @category errors
|
|
64
|
+
* @since 0.1.0
|
|
65
|
+
*/
|
|
66
|
+
export declare class JournalError extends JournalError_base {
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Policy applied when the non-blocking admission queue is full.
|
|
70
|
+
*
|
|
71
|
+
* @category models
|
|
72
|
+
* @since 0.1.0
|
|
73
|
+
*/
|
|
74
|
+
export declare const OverflowPolicy: Schema.Literals<readonly ["reject", "drop-newest", "drop-oldest"]>;
|
|
75
|
+
/**
|
|
76
|
+
* Policy applied when the non-blocking admission queue is full.
|
|
77
|
+
*
|
|
78
|
+
* @category models
|
|
79
|
+
* @since 0.1.0
|
|
80
|
+
*/
|
|
81
|
+
export type OverflowPolicy = typeof OverflowPolicy.Type;
|
|
82
|
+
/**
|
|
83
|
+
* Receipt for a newly admitted event.
|
|
84
|
+
*
|
|
85
|
+
* On the lossy channel, `seq` and `sourceSeq` are allocated synchronously and
|
|
86
|
+
* returned before SQL commits. This `seq` is provisional: the SQL writer
|
|
87
|
+
* moves it above the committed tail if another commit overtakes its reservation.
|
|
88
|
+
* Use committed entries for durable cursors. On the durable channel, the same
|
|
89
|
+
* receipt shape is returned only after the entry commits. `seq` orders the run;
|
|
90
|
+
* `sourceSeq` identifies producer retries and does not change at commit.
|
|
91
|
+
*
|
|
92
|
+
* @category models
|
|
93
|
+
* @since 0.1.0
|
|
94
|
+
*/
|
|
95
|
+
export declare const Accepted: Schema.TaggedStruct<"Accepted", {
|
|
96
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
97
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
98
|
+
readonly evicted: Schema.optionalKey<Schema.Struct<{
|
|
99
|
+
readonly policy: Schema.Literal<"drop-oldest">;
|
|
100
|
+
readonly count: Schema.Int;
|
|
101
|
+
}>>;
|
|
102
|
+
}>;
|
|
103
|
+
/**
|
|
104
|
+
* Receipt for a newly admitted event.
|
|
105
|
+
*
|
|
106
|
+
* @category models
|
|
107
|
+
* @since 0.1.0
|
|
108
|
+
*/
|
|
109
|
+
export type Accepted = typeof Accepted.Type;
|
|
110
|
+
/**
|
|
111
|
+
* Receipt for an exact retry of an already pending or committed source event.
|
|
112
|
+
*
|
|
113
|
+
* `seq` is the original event's sequence, provisional while pending and
|
|
114
|
+
* canonical after commit. A duplicate does not allocate another sequence or
|
|
115
|
+
* enqueue another write. `status` distinguishes
|
|
116
|
+
* an optimistic retry from one whose original event is already durable.
|
|
117
|
+
*
|
|
118
|
+
* @category models
|
|
119
|
+
* @since 0.1.0
|
|
120
|
+
*/
|
|
121
|
+
export declare const Duplicate: Schema.TaggedStruct<"Duplicate", {
|
|
122
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
123
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
124
|
+
readonly status: Schema.Literals<readonly ["pending", "committed"]>;
|
|
125
|
+
}>;
|
|
126
|
+
/**
|
|
127
|
+
* Receipt for an exact producer retry.
|
|
128
|
+
*
|
|
129
|
+
* @category models
|
|
130
|
+
* @since 0.1.0
|
|
131
|
+
*/
|
|
132
|
+
export type Duplicate = typeof Duplicate.Type;
|
|
133
|
+
/**
|
|
134
|
+
* Receipt for an event discarded by an explicit dropping policy.
|
|
135
|
+
*
|
|
136
|
+
* A dropped admission still consumes its synchronously allocated `seq` and
|
|
137
|
+
* `sourceSeq`, so sequence gaps are expected.
|
|
138
|
+
*
|
|
139
|
+
* @category models
|
|
140
|
+
* @since 0.1.0
|
|
141
|
+
*/
|
|
142
|
+
export declare const Dropped: Schema.TaggedStruct<"Dropped", {
|
|
143
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
144
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
145
|
+
readonly policy: Schema.Literal<"drop-newest">;
|
|
146
|
+
}>;
|
|
147
|
+
/**
|
|
148
|
+
* Receipt for an event discarded by policy.
|
|
149
|
+
*
|
|
150
|
+
* @category models
|
|
151
|
+
* @since 0.1.0
|
|
152
|
+
*/
|
|
153
|
+
export type Dropped = typeof Dropped.Type;
|
|
154
|
+
/**
|
|
155
|
+
* Receipt union for admission that may use the lossy queue.
|
|
156
|
+
*
|
|
157
|
+
* @category models
|
|
158
|
+
* @since 0.1.0
|
|
159
|
+
*/
|
|
160
|
+
export declare const EmitReceipt: Schema.Union<readonly [Schema.TaggedStruct<"Accepted", {
|
|
161
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
162
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
163
|
+
readonly evicted: Schema.optionalKey<Schema.Struct<{
|
|
164
|
+
readonly policy: Schema.Literal<"drop-oldest">;
|
|
165
|
+
readonly count: Schema.Int;
|
|
166
|
+
}>>;
|
|
167
|
+
}>, Schema.TaggedStruct<"Duplicate", {
|
|
168
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
169
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
170
|
+
readonly status: Schema.Literals<readonly ["pending", "committed"]>;
|
|
171
|
+
}>, Schema.TaggedStruct<"Dropped", {
|
|
172
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
173
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
174
|
+
readonly policy: Schema.Literal<"drop-newest">;
|
|
175
|
+
}>]>;
|
|
176
|
+
/**
|
|
177
|
+
* Receipt union for the lossy channel.
|
|
178
|
+
*
|
|
179
|
+
* @category models
|
|
180
|
+
* @since 0.1.0
|
|
181
|
+
*/
|
|
182
|
+
export type EmitReceipt = typeof EmitReceipt.Type;
|
|
183
|
+
/**
|
|
184
|
+
* Result of a synchronously durable journal admission.
|
|
185
|
+
*
|
|
186
|
+
* A durable admission is never dropped: it either commits, returns the
|
|
187
|
+
* committed sequence of an exact producer retry, or fails.
|
|
188
|
+
*
|
|
189
|
+
* @category models
|
|
190
|
+
* @since 0.1.0
|
|
191
|
+
*/
|
|
192
|
+
export declare const DurableReceipt: Schema.Union<readonly [Schema.TaggedStruct<"Accepted", {
|
|
193
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
194
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
195
|
+
readonly evicted: Schema.optionalKey<Schema.Struct<{
|
|
196
|
+
readonly policy: Schema.Literal<"drop-oldest">;
|
|
197
|
+
readonly count: Schema.Int;
|
|
198
|
+
}>>;
|
|
199
|
+
}>, Schema.TaggedStruct<"Duplicate", {
|
|
200
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
201
|
+
readonly sourceSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/SourceSeq">;
|
|
202
|
+
readonly status: Schema.Literals<readonly ["pending", "committed"]>;
|
|
203
|
+
}>]>;
|
|
204
|
+
/**
|
|
205
|
+
* Receipt union for the durable channel.
|
|
206
|
+
*
|
|
207
|
+
* @category models
|
|
208
|
+
* @since 0.1.0
|
|
209
|
+
*/
|
|
210
|
+
export type DurableReceipt = typeof DurableReceipt.Type;
|
|
211
|
+
/**
|
|
212
|
+
* Cursor used to replay a run and then follow its committed tail.
|
|
213
|
+
*
|
|
214
|
+
* @category models
|
|
215
|
+
* @since 0.1.0
|
|
216
|
+
*/
|
|
217
|
+
export declare const StreamOptions: Schema.Struct<{
|
|
218
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
219
|
+
readonly afterSequence: Schema.optionalKey<Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">>;
|
|
220
|
+
}>;
|
|
221
|
+
/**
|
|
222
|
+
* Cursor used to replay a run and follow its committed tail.
|
|
223
|
+
*
|
|
224
|
+
* @category models
|
|
225
|
+
* @since 0.1.0
|
|
226
|
+
*/
|
|
227
|
+
export type StreamOptions = typeof StreamOptions.Type;
|
|
228
|
+
/**
|
|
229
|
+
* Largest page `entries` will read.
|
|
230
|
+
*
|
|
231
|
+
* A page is decoded into memory in full before the caller sees its first
|
|
232
|
+
* entry, so an unbounded limit lets one call materialize a whole run. The
|
|
233
|
+
* largest page any caller in this repository asks for is 512, so this
|
|
234
|
+
* ceiling refuses only a limit that was going to be a memory incident.
|
|
235
|
+
*
|
|
236
|
+
* @since 1.0.0
|
|
237
|
+
* @category constants
|
|
238
|
+
*/
|
|
239
|
+
export declare const maxEntriesLimit = 10000;
|
|
240
|
+
/**
|
|
241
|
+
* Cursor and page size for durable journal reads.
|
|
242
|
+
*
|
|
243
|
+
* `limit` is at most `maxEntriesLimit` (10,000 entries). Optional `eventTypes`
|
|
244
|
+
* selects a nonempty list of at most 64 exact types before pagination; cursors remain canonical run
|
|
245
|
+
* sequences and `hasMore` describes matching entries. Omit it for the full run.
|
|
246
|
+
* Filtering does not bypass the run's compaction floor.
|
|
247
|
+
*
|
|
248
|
+
* @category models
|
|
249
|
+
* @since 0.1.0
|
|
250
|
+
*/
|
|
251
|
+
export declare const EntriesOptions: Schema.Struct<{
|
|
252
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
253
|
+
readonly after: Schema.optionalKey<Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">>;
|
|
254
|
+
readonly eventTypes: Schema.optionalKey<Schema.$Array<Schema.String>>;
|
|
255
|
+
readonly limit: Schema.Int;
|
|
256
|
+
}>;
|
|
257
|
+
/**
|
|
258
|
+
* Cursor and page size for durable journal reads.
|
|
259
|
+
*
|
|
260
|
+
* @category models
|
|
261
|
+
* @since 0.1.0
|
|
262
|
+
*/
|
|
263
|
+
export type EntriesOptions = typeof EntriesOptions.Type;
|
|
264
|
+
/**
|
|
265
|
+
* One page of canonical durable journal entries.
|
|
266
|
+
*
|
|
267
|
+
* @category models
|
|
268
|
+
* @since 0.1.0
|
|
269
|
+
*/
|
|
270
|
+
export declare const EntriesPage: Schema.Struct<{
|
|
271
|
+
readonly entries: Schema.$Array<typeof Entry>;
|
|
272
|
+
readonly hasMore: Schema.Boolean;
|
|
273
|
+
}>;
|
|
274
|
+
/**
|
|
275
|
+
* One page of durable journal entries.
|
|
276
|
+
*
|
|
277
|
+
* @category models
|
|
278
|
+
* @since 0.1.0
|
|
279
|
+
*/
|
|
280
|
+
export type EntriesPage = typeof EntriesPage.Type;
|
|
281
|
+
declare const Checkpoint_base: Schema.Class<Checkpoint, Schema.Struct<{
|
|
282
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
283
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
284
|
+
readonly state: Schema.Unknown;
|
|
285
|
+
readonly createdAtMs: Schema.Int;
|
|
286
|
+
readonly compactedAtMs: Schema.NullOr<Schema.Int>;
|
|
287
|
+
}>, {}>;
|
|
288
|
+
/**
|
|
289
|
+
* A durable checkpoint: the caller-captured state that replays a run from
|
|
290
|
+
* `seq` without the entries before it.
|
|
291
|
+
*
|
|
292
|
+
* `state` is the caller's own replay snapshot and round-trips verbatim: the
|
|
293
|
+
* journal never interprets it, and redaction deliberately does not apply,
|
|
294
|
+
* exactly as it does not apply to executable state. A checkpoint at `seq`
|
|
295
|
+
* must subsume every entry with a sequence at or below `seq`: replay is
|
|
296
|
+
* `state` plus `stream({ runId, afterSequence: seq })`.
|
|
297
|
+
*
|
|
298
|
+
* `compactedAtMs` is `null` until a compaction has truncated the entries
|
|
299
|
+
* strictly below `seq`. The largest compacted `seq` for a run is its
|
|
300
|
+
* compaction floor.
|
|
301
|
+
*
|
|
302
|
+
* Prior art: Temporal's mutable state, a durable snapshot pinned to a
|
|
303
|
+
* history offset, with history below it never replayed
|
|
304
|
+
* (`reference/temporal/common/persistence/data_interfaces.go`,
|
|
305
|
+
* `WorkflowSnapshot`).
|
|
306
|
+
*
|
|
307
|
+
* @category models
|
|
308
|
+
* @since 0.1.0
|
|
309
|
+
*/
|
|
310
|
+
export declare class Checkpoint extends Checkpoint_base {
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Arguments for writing a checkpoint.
|
|
314
|
+
*
|
|
315
|
+
* `seq` must name a committed entry of the run: the surviving row is what
|
|
316
|
+
* keeps the run's durable `MAX(seq)` allocation floor at or above the
|
|
317
|
+
* compaction boundary, so a process restarted after compaction can never
|
|
318
|
+
* re-allocate a truncated sequence.
|
|
319
|
+
*
|
|
320
|
+
* @category models
|
|
321
|
+
* @since 0.1.0
|
|
322
|
+
*/
|
|
323
|
+
export declare const CheckpointOptions: Schema.Struct<{
|
|
324
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
325
|
+
readonly seq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
326
|
+
readonly state: Schema.Unknown;
|
|
327
|
+
}>;
|
|
328
|
+
/**
|
|
329
|
+
* Arguments for writing a checkpoint.
|
|
330
|
+
*
|
|
331
|
+
* @category models
|
|
332
|
+
* @since 0.1.0
|
|
333
|
+
*/
|
|
334
|
+
export type CheckpointOptions = typeof CheckpointOptions.Type;
|
|
335
|
+
/**
|
|
336
|
+
* Arguments for compacting a run.
|
|
337
|
+
*
|
|
338
|
+
* `upTo` selects the checkpoint to truncate below; omitted, the run's latest
|
|
339
|
+
* checkpoint is used.
|
|
340
|
+
*
|
|
341
|
+
* @category models
|
|
342
|
+
* @since 0.1.0
|
|
343
|
+
*/
|
|
344
|
+
export declare const CompactOptions: Schema.Struct<{
|
|
345
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
346
|
+
readonly upTo: Schema.optionalKey<Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">>;
|
|
347
|
+
}>;
|
|
348
|
+
/**
|
|
349
|
+
* Arguments for compacting a run.
|
|
350
|
+
*
|
|
351
|
+
* @category models
|
|
352
|
+
* @since 0.1.0
|
|
353
|
+
*/
|
|
354
|
+
export type CompactOptions = typeof CompactOptions.Type;
|
|
355
|
+
/**
|
|
356
|
+
* Receipt for a completed compaction.
|
|
357
|
+
*
|
|
358
|
+
* `deleted` is `0` when the checkpoint was already the compaction floor, a
|
|
359
|
+
* retried compaction is idempotent.
|
|
360
|
+
*
|
|
361
|
+
* @category models
|
|
362
|
+
* @since 0.1.0
|
|
363
|
+
*/
|
|
364
|
+
export declare const Compacted: Schema.Struct<{
|
|
365
|
+
readonly runId: Schema.brand<Schema.String, "@smthrs/journal/JournalEvent/RunId">;
|
|
366
|
+
readonly checkpointSeq: Schema.brand<Schema.Int, "@smthrs/journal/JournalEvent/Seq">;
|
|
367
|
+
readonly deleted: Schema.Int;
|
|
368
|
+
}>;
|
|
369
|
+
/**
|
|
370
|
+
* Receipt for a completed compaction.
|
|
371
|
+
*
|
|
372
|
+
* @category models
|
|
373
|
+
* @since 0.1.0
|
|
374
|
+
*/
|
|
375
|
+
export type Compacted = typeof Compacted.Type;
|
|
376
|
+
/**
|
|
377
|
+
* Journal operations.
|
|
378
|
+
*
|
|
379
|
+
* There are two sequence domains:
|
|
380
|
+
*
|
|
381
|
+
* - `seq` is reserved synchronously per run. A lossy reservation is provisional;
|
|
382
|
+
* the SQL writer moves it above the committed tail if overtaken. The committed
|
|
383
|
+
* sequence is the canonical order for replay, paging, streams, and projections.
|
|
384
|
+
* - `sourceSeq` is assigned synchronously per `(runId, sourceId)`, or supplied
|
|
385
|
+
* by the producer, and is the idempotency key for producer retries.
|
|
386
|
+
*
|
|
387
|
+
* Rejected or dropped admissions consume both allocations, so gaps are valid.
|
|
388
|
+
* A retry the in-process index still holds returns `Duplicate` with the
|
|
389
|
+
* original `seq` (provisional while pending) and consumes neither allocation.
|
|
390
|
+
*
|
|
391
|
+
* A retry it no longer holds is admitted optimistically and settled by
|
|
392
|
+
* `UNIQUE (run_id, source_id, source_seq)` at the insert: admission issues no
|
|
393
|
+
* dedup read, so the receipt is `Accepted`, the entry collapses onto the
|
|
394
|
+
* committed row instead of doubling it, and a reused identity carrying
|
|
395
|
+
* different bytes surfaces its `idempotency_conflict` through `flush` rather
|
|
396
|
+
* than through the emit. The read is deliberately absent. `emitLossy` exists
|
|
397
|
+
* to be callable from inside somebody else's open write transaction, and a
|
|
398
|
+
* SELECT there waits on the writer that is waiting on the caller: the agent
|
|
399
|
+
* executor's exit flush deadlocked exactly so. What a producer keeps in
|
|
400
|
+
* exchange is the choice of what a collision means, through `Input.dedupe`.
|
|
401
|
+
*
|
|
402
|
+
* This table is Smithers' logical (domain) write-ahead log and is intended to
|
|
403
|
+
* become the authoritative state history. The storage engine's own WAL
|
|
404
|
+
* underneath it is a durability substrate only and is never consumed as the
|
|
405
|
+
* application event API. A durable boundary must not advance a run or expose
|
|
406
|
+
* its result until its lifecycle entry is committed. No local commit makes a
|
|
407
|
+
* remote effect atomic, so external effects still need idempotency keys,
|
|
408
|
+
* fencing tokens, or compensation.
|
|
409
|
+
*
|
|
410
|
+
* `emitDurable` allocates `seq` inside the writer's SQL transaction, so the
|
|
411
|
+
* returned sequence is already committed and independent writers never fork
|
|
412
|
+
* the per-run clock.
|
|
413
|
+
*
|
|
414
|
+
* Caveat on scope: the stores above this log (`RunStore`, `AttemptStore`,
|
|
415
|
+
* `CacheStore`, and engine-store's `DurableEngineState`) hold the executable
|
|
416
|
+
* authoritative state, and no state is derived from these entries today.
|
|
417
|
+
* `transact` is what keeps the two halves consistent anyway: a state
|
|
418
|
+
* transition and the lifecycle entry describing it are appended in ONE write
|
|
419
|
+
* transaction, so a crash can never leave durable state the journal does not
|
|
420
|
+
* explain (or an entry for a transition that never landed).
|
|
421
|
+
*
|
|
422
|
+
* The surface is split into two channels:
|
|
423
|
+
*
|
|
424
|
+
* - The lifecycle channel, `emitDurable`, returns `DurableReceipt`, so a
|
|
425
|
+
* dropped lifecycle event is unrepresentable: the write commits, dedupes, or
|
|
426
|
+
* fails with a typed error.
|
|
427
|
+
* - The lossy channel, `emitLossy`, keeps the optimistic queue and its
|
|
428
|
+
* overflow policies for telemetry, where `Dropped` receipts and
|
|
429
|
+
* `drop-oldest` evictions are acceptable.
|
|
430
|
+
*
|
|
431
|
+
* `emitDurable` is fenced on the run's ownership as arbitrated by the
|
|
432
|
+
* injected `Consensus` strategy: the caller hands over its `OwnerId`, the
|
|
433
|
+
* durable insert only commits while that strategy still records the owner as
|
|
434
|
+
* holding the run, and a reclaimed run fails the write with a `fence_lost`
|
|
435
|
+
* error. The fence is mandatory on the lifecycle channel: a lifecycle write is
|
|
436
|
+
* what advances a run, and a zombie owner must not advance anything. The one
|
|
437
|
+
* escape is {@link Service.emitDurableUnfenced}, for the rare admission that
|
|
438
|
+
* is genuinely ownerless.
|
|
439
|
+
*
|
|
440
|
+
* @category models
|
|
441
|
+
* @since 0.1.0
|
|
442
|
+
*/
|
|
443
|
+
export interface Service {
|
|
444
|
+
/**
|
|
445
|
+
* The durable rewind generation and its archive boundary. An append-only
|
|
446
|
+
* adapter may omit this operation, which means generation zero forever.
|
|
447
|
+
* Rewinding adapters must advance the generation atomically with truncation.
|
|
448
|
+
*/
|
|
449
|
+
readonly generation?: ((runId: RunId) => Effect.Effect<{
|
|
450
|
+
readonly generation: number;
|
|
451
|
+
readonly afterSeq: number;
|
|
452
|
+
}, JournalError>) | undefined;
|
|
453
|
+
readonly emitLossy: (input: Input) => Effect.Effect<EmitReceipt, JournalError>;
|
|
454
|
+
readonly emitDurable: (input: Input, owner: OwnerId) => Effect.Effect<DurableReceipt, JournalError>;
|
|
455
|
+
/**
|
|
456
|
+
* The unfenced durable write: same durability and receipt contract as
|
|
457
|
+
* {@link Service.emitDurable}, with no ownership fence.
|
|
458
|
+
*
|
|
459
|
+
* This exists ONLY for admissions that are genuinely ownerless: writes
|
|
460
|
+
* whose correctness does not depend on who currently owns the run because
|
|
461
|
+
* they are first-writer-wins by design. The canonical case is the
|
|
462
|
+
* external-trigger admission: a deferred completion or clock-schedule
|
|
463
|
+
* record delivered by a sweeper that owns nothing, where the dedup index,
|
|
464
|
+
* not the fence, is the idempotency mechanism. A caller that holds an
|
|
465
|
+
* `OwnerId` must use `emitDurable`; reaching for this channel to dodge a
|
|
466
|
+
* `fence_lost` is exactly the zombie write the fence exists to reject.
|
|
467
|
+
*/
|
|
468
|
+
readonly emitDurableUnfenced: (input: Input) => Effect.Effect<DurableReceipt, JournalError>;
|
|
469
|
+
/**
|
|
470
|
+
* Runs `effect`, a state projection plus the `emitDurable` calls describing
|
|
471
|
+
* it, inside ONE write transaction.
|
|
472
|
+
*
|
|
473
|
+
* This is the seam that makes the logical WAL crash-consistent with
|
|
474
|
+
* executable state. The stores above the journal (`RunStore`,
|
|
475
|
+
* `AttemptStore`, `CacheStore`, `DurableEngineState`) write through the same
|
|
476
|
+
* `DurableWriter`, so their writes join this transaction as savepoints: either
|
|
477
|
+
* the transition and its lifecycle entry both commit, or neither does. It is
|
|
478
|
+
* the local analogue of Temporal closing mutable state into a mutation plus
|
|
479
|
+
* event batches and submitting them as one persistence request
|
|
480
|
+
* (`reference/temporal/service/history/workflow/transaction_impl.go`).
|
|
481
|
+
*
|
|
482
|
+
* A `Duplicate` receipt is unaffected: an exact producer retry still
|
|
483
|
+
* collapses onto the already-committed sequence.
|
|
484
|
+
*
|
|
485
|
+
* Two consequences a caller must plan for:
|
|
486
|
+
*
|
|
487
|
+
* - Publication (`changes`, `stream`, and the in-process source-event index)
|
|
488
|
+
* is deferred until the transaction commits, so a subscriber never
|
|
489
|
+
* observes an entry that later rolls back, and a rolled-back producer
|
|
490
|
+
* identity stays re-emittable rather than deduplicating against a
|
|
491
|
+
* sequence that does not exist.
|
|
492
|
+
* - Everything inside runs while a write transaction is open. Keep it to
|
|
493
|
+
* storage work: no flow bodies, no host calls, no waits.
|
|
494
|
+
*
|
|
495
|
+
* Nesting is safe: an inner `transact` becomes a savepoint of the outer
|
|
496
|
+
* one and defers its publication to the outermost commit.
|
|
497
|
+
*/
|
|
498
|
+
readonly transact: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E | JournalError, R>;
|
|
499
|
+
/**
|
|
500
|
+
* Publishes a short, non-failing process-local update after the current
|
|
501
|
+
* transaction commits, or immediately when no transaction is open.
|
|
502
|
+
*
|
|
503
|
+
* Returns false without publishing inside a raw SQL transaction whose
|
|
504
|
+
* commit this journal cannot observe. A true result can mean deferred, not
|
|
505
|
+
* already run. Failed savepoints and retries discard their registrations.
|
|
506
|
+
* Test doubles that implement transactions must preserve this contract.
|
|
507
|
+
*/
|
|
508
|
+
readonly whenCommitted: (update: Effect.Effect<void>) => Effect.Effect<boolean>;
|
|
509
|
+
/**
|
|
510
|
+
* Replays the run's durable history from `afterSequence`, then follows it.
|
|
511
|
+
*
|
|
512
|
+
* This is the lossless follower. It pages the history rather than
|
|
513
|
+
* materializing it, so the first entry arrives after one page rather than
|
|
514
|
+
* after the whole run; it reports a sink loss that happens while it is
|
|
515
|
+
* following; and a cursor below the run's compaction floor fails with
|
|
516
|
+
* `compacted` and the sequence to resync from, never a silently shortened
|
|
517
|
+
* history.
|
|
518
|
+
*/
|
|
519
|
+
readonly stream: (options: StreamOptions) => Stream.Stream<Entry, JournalError>;
|
|
520
|
+
/**
|
|
521
|
+
* Reads one page of the run's durable history in sequence order.
|
|
522
|
+
*
|
|
523
|
+
* `hasMore` reports whether another page follows. A cursor below the run's
|
|
524
|
+
* compaction floor fails with `compacted`, exactly as `stream` does, so a
|
|
525
|
+
* poller and a follower cannot disagree about what history exists.
|
|
526
|
+
*/
|
|
527
|
+
readonly entries: (options: EntriesOptions) => Effect.Effect<EntriesPage, JournalError>;
|
|
528
|
+
/**
|
|
529
|
+
* Subscribes to entries this process commits, across every run.
|
|
530
|
+
*
|
|
531
|
+
* This is a bounded SLIDING buffer sized by the layer's `capacity`: a slow
|
|
532
|
+
* consumer silently loses entries, with no error and no gap signal. Use it
|
|
533
|
+
* for a local tail or a UI feed, and use `stream` wherever a missing entry
|
|
534
|
+
* would be a correctness bug, because that is the lossless path and the one
|
|
535
|
+
* that reports sink losses.
|
|
536
|
+
*
|
|
537
|
+
* Only this process's commits arrive here. Another writer on the same
|
|
538
|
+
* database publishes into its own buffer, which is the second reason
|
|
539
|
+
* `stream` exists: it rechecks the durable tail.
|
|
540
|
+
*
|
|
541
|
+
* Published entries are deeply frozen, so one subscriber cannot mutate the
|
|
542
|
+
* value another subscriber is about to read.
|
|
543
|
+
*/
|
|
544
|
+
readonly changes: Effect.Effect<PubSub.Subscription<Entry>, never, Scope.Scope>;
|
|
545
|
+
readonly project: <S, E, R>(projection: Projection<S, E, R>, options: StreamOptions) => Stream.Stream<S, JournalError, R>;
|
|
546
|
+
readonly flush: Effect.Effect<void, JournalError>;
|
|
547
|
+
/**
|
|
548
|
+
* Durably records the state that replays the run from `options.seq`.
|
|
549
|
+
*
|
|
550
|
+
* The write shares `transact`'s discipline: it runs through the same
|
|
551
|
+
* `DurableWriter`, so inside an open `transact` it joins the caller's
|
|
552
|
+
* transaction as a savepoint and rolls back with it. `options.seq` must
|
|
553
|
+
* name a committed entry and must lie above the run's compaction floor;
|
|
554
|
+
* otherwise the write fails with `checkpoint_invalid`. Re-checkpointing an
|
|
555
|
+
* uncompacted `seq` replaces its state: last writer wins.
|
|
556
|
+
*
|
|
557
|
+
* The write is fenced on the run's ownership through the consensus
|
|
558
|
+
* strategy, exactly as `emitDurable` is: a reclaimed run fails with
|
|
559
|
+
* `fence_lost`. The fence is mandatory: a zombie owner must not replace
|
|
560
|
+
* replay state behind a live successor.
|
|
561
|
+
*/
|
|
562
|
+
readonly checkpoint: (options: CheckpointOptions, owner: OwnerId) => Effect.Effect<Checkpoint, JournalError>;
|
|
563
|
+
/**
|
|
564
|
+
* Reads the run's most recent checkpoint, compacted or not.
|
|
565
|
+
*
|
|
566
|
+
* A reader that fails with `compacted` resyncs here: apply
|
|
567
|
+
* `checkpoint.state`, then continue from
|
|
568
|
+
* `stream({ runId, afterSequence: checkpoint.seq })`.
|
|
569
|
+
*/
|
|
570
|
+
readonly latestCheckpoint: (runId: RunId) => Effect.Effect<Option.Option<Checkpoint>, JournalError>;
|
|
571
|
+
/**
|
|
572
|
+
* Deletes the run's entries strictly below a checkpoint, atomically with
|
|
573
|
+
* advancing the run's compaction floor.
|
|
574
|
+
*
|
|
575
|
+
* Refusals are typed: `checkpoint_invalid` when the run has no checkpoint
|
|
576
|
+
* to truncate below, `reader_behind` when a live in-process stream still
|
|
577
|
+
* needs a sequence the truncation would delete, and `fence_lost` when the
|
|
578
|
+
* supplied `owner` no longer holds the run. The fence is mandatory, so a
|
|
579
|
+
* zombie owner can never truncate history behind a live successor. Readers
|
|
580
|
+
* this process cannot see (pollers of `entries` and followers in other
|
|
581
|
+
* processes) are protected by the read-side guard instead: any read whose cursor starts
|
|
582
|
+
* below the floor fails with `compacted` and the floor to resync from,
|
|
583
|
+
* never a silently shortened history.
|
|
584
|
+
*/
|
|
585
|
+
readonly compact: (options: CompactOptions, owner: OwnerId) => Effect.Effect<Compacted, JournalError>;
|
|
586
|
+
}
|
|
587
|
+
declare const Journal_base: Context.ServiceClass<Journal, "@smthrs/journal/Journal", Service>;
|
|
588
|
+
/**
|
|
589
|
+
* Context service for durable lifecycle evidence and lossy telemetry.
|
|
590
|
+
*
|
|
591
|
+
* @category services
|
|
592
|
+
* @since 0.1.0
|
|
593
|
+
*/
|
|
594
|
+
export declare class Journal extends Journal_base {
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Constructs a journal service from an implementation.
|
|
598
|
+
*
|
|
599
|
+
* @category constructors
|
|
600
|
+
* @since 0.1.0
|
|
601
|
+
*/
|
|
602
|
+
export declare const make: (implementation: Service) => Service;
|
|
603
|
+
/**
|
|
604
|
+
* Constructs a closed journal stub, optionally overriding individual methods.
|
|
605
|
+
*
|
|
606
|
+
* @category constructors
|
|
607
|
+
* @since 0.1.0
|
|
608
|
+
*/
|
|
609
|
+
export declare const makeNoop: (overrides?: Partial<Service>) => Service;
|
|
610
|
+
/**
|
|
611
|
+
* Provides a closed journal stub.
|
|
612
|
+
*
|
|
613
|
+
* @category layers
|
|
614
|
+
* @since 0.1.0
|
|
615
|
+
*/
|
|
616
|
+
export declare const layerNoop: (overrides?: Partial<Service>) => Layer.Layer<Journal>;
|
|
617
|
+
//# sourceMappingURL=Journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Journal.d.ts","sourceRoot":"","sources":["../../src/Journal.ts"],"names":[],"mappings":"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"}
|