@arki/journal 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +541 -2
- package/dist/api.d.ts +336 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +2 -0
- package/dist/api.js.map +1 -0
- package/dist/command.d.ts +27 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +157 -0
- package/dist/command.js.map +1 -0
- package/dist/debug.d.ts +7 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +8 -0
- package/dist/debug.js.map +1 -0
- package/dist/dot.d.ts +102 -0
- package/dist/dot.d.ts.map +1 -0
- package/dist/dot.js +159 -0
- package/dist/dot.js.map +1 -0
- package/dist/entity.d.ts +56 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/entity.js +174 -0
- package/dist/entity.js.map +1 -0
- package/dist/errors.d.ts +47 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +112 -0
- package/dist/errors.js.map +1 -0
- package/dist/event.d.ts +9 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +19 -0
- package/dist/event.js.map +1 -0
- package/dist/fold.d.ts +29 -0
- package/dist/fold.d.ts.map +1 -0
- package/dist/fold.js +49 -0
- package/dist/fold.js.map +1 -0
- package/dist/handlers.d.ts +26 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +130 -0
- package/dist/handlers.js.map +1 -0
- package/dist/history.d.ts +49 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +259 -0
- package/dist/history.js.map +1 -0
- package/dist/hooks.d.ts +14 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +67 -0
- package/dist/hooks.js.map +1 -0
- package/dist/id.d.ts +18 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +41 -0
- package/dist/id.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/journal.d.ts +51 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +181 -0
- package/dist/journal.js.map +1 -0
- package/dist/listen.d.ts +37 -0
- package/dist/listen.d.ts.map +1 -0
- package/dist/listen.js +90 -0
- package/dist/listen.js.map +1 -0
- package/dist/orpc.d.ts +21 -0
- package/dist/orpc.d.ts.map +1 -0
- package/dist/orpc.js +57 -0
- package/dist/orpc.js.map +1 -0
- package/dist/pg.d.ts +537 -0
- package/dist/pg.d.ts.map +1 -0
- package/dist/pg.js +80 -0
- package/dist/pg.js.map +1 -0
- package/dist/storage.d.ts +52 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +221 -0
- package/dist/storage.js.map +1 -0
- package/dist/testing.d.ts +19 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +23 -0
- package/dist/testing.js.map +1 -0
- package/dist/transaction-guard.d.ts +2 -0
- package/dist/transaction-guard.d.ts.map +1 -0
- package/dist/transaction-guard.js +38 -0
- package/dist/transaction-guard.js.map +1 -0
- package/dist/types.d.ts +414 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +109 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +458 -0
- package/dist/worker.js.map +1 -0
- package/dist/write.d.ts +39 -0
- package/dist/write.d.ts.map +1 -0
- package/dist/write.js +287 -0
- package/dist/write.js.map +1 -0
- package/docs/agent-guide.md +324 -0
- package/llms.txt +40 -0
- package/package.json +99 -4
- package/src/api.ts +465 -0
- package/src/command.ts +242 -0
- package/src/debug.ts +8 -0
- package/src/dot.ts +296 -0
- package/src/entity.ts +377 -0
- package/src/errors.ts +134 -0
- package/src/event.ts +26 -0
- package/src/fold.ts +97 -0
- package/src/handlers.ts +262 -0
- package/src/history.ts +390 -0
- package/src/hooks.ts +85 -0
- package/src/id.ts +54 -0
- package/src/index.ts +76 -0
- package/src/journal.ts +256 -0
- package/src/listen.ts +109 -0
- package/src/orpc.ts +59 -0
- package/src/pg.ts +107 -0
- package/src/storage.ts +277 -0
- package/src/test-support.ts +82 -0
- package/src/testing.ts +23 -0
- package/src/transaction-guard.ts +40 -0
- package/src/types.ts +439 -0
- package/src/worker.ts +609 -0
- package/src/write.ts +434 -0
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The public declarations: the `Journal` object, commands and their context, the
|
|
3
|
+
* definition helpers `initJournal` returns, and the input, option and result types.
|
|
4
|
+
* Types only, no runtime code. May import `entity`, `types` and `pg`; nothing else.
|
|
5
|
+
*/
|
|
6
|
+
import type { z } from 'zod';
|
|
7
|
+
import type { EntityBuilder } from './entity.js';
|
|
8
|
+
import type { HookPoint } from './hooks.js';
|
|
9
|
+
import type { JournalTables } from './pg.js';
|
|
10
|
+
import type { AnyEntity, AnyEventDef, CommandHookContext, DbHandle, Effect, EffectHandlers, EffectHookContext, EntityDef, EntityId, EntityInfo, EntityTable, EventDef, EventOptions, IdTable, JournalWorker, KeyName, Needs, PendingOf, Projection, ProjectionHandlers, ProjectionOptions, RecordedOf, ReducerRow, RootDb, Row, Services, ServicesFor, SingleKey, StrandedJobs, Tap, TapHandlers, TransactionSource, WakeListener } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Looks at the locked row, checks the rules, and returns the events to append.
|
|
13
|
+
* Runs after the row is locked, inside the write's savepoint. `tx` is that
|
|
14
|
+
* savepoint: reads through it see the locked row's transaction.
|
|
15
|
+
*/
|
|
16
|
+
export type NextEvents<Tbl extends EntityTable, E extends AnyEventDef, Tx = DbHandle> = (row: Row<Tbl> | null, ctx: {
|
|
17
|
+
readonly tx: Tx;
|
|
18
|
+
}) => readonly PendingOf<E>[] | Promise<readonly PendingOf<E>[]>;
|
|
19
|
+
/** Options of a write, from `journal.write` or a command's `write`. */
|
|
20
|
+
export type WriteOptions = {
|
|
21
|
+
/**
|
|
22
|
+
* The row version the caller saw. If the stored version differs (0 for no row), the
|
|
23
|
+
* write is refused with `CONFLICT` before `events` runs, so a client that edited a
|
|
24
|
+
* stale copy learns it instead of overwriting a newer one.
|
|
25
|
+
*/
|
|
26
|
+
readonly expectedVersion?: number;
|
|
27
|
+
};
|
|
28
|
+
export type WriteInput<Tbl extends EntityTable, E extends AnyEventDef, Meta extends z.ZodObject, Tx = DbHandle> = WriteOptions & {
|
|
29
|
+
readonly meta: z.input<Meta>;
|
|
30
|
+
readonly events: NextEvents<Tbl, E, Tx>;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A command: a name, an input schema and a handler. `j.command` makes one;
|
|
34
|
+
* `journal.run` runs it. `name` and `input` are for the app (an oRPC procedure
|
|
35
|
+
* can reuse or `.pick` the schema). The handler is for `journal.run` only.
|
|
36
|
+
*/
|
|
37
|
+
export type Command<S extends z.ZodType, R, in MetaOut, in Tx extends TransactionSource<Tx> = DbHandle> = {
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly input: S;
|
|
40
|
+
readonly handler: (input: z.output<S>, context: CommandContext<MetaOut, Tx>) => R;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* What a command handler receives. `write` and `run` are bound to the command's
|
|
44
|
+
* transaction and metadata. The variance annotations here and on `Command` are
|
|
45
|
+
* needed: the two types refer to each other, and TypeScript cannot measure the
|
|
46
|
+
* variance of such a pair on its own.
|
|
47
|
+
*/
|
|
48
|
+
/** Options of one call: `journal.run`, a bound runner, a command's `run`, an effect's `ctx.run`. */
|
|
49
|
+
export type CallOptions = {
|
|
50
|
+
/**
|
|
51
|
+
* Makes the call idempotent. The first run with this key records its result in
|
|
52
|
+
* `journal_receipts`, in its own transaction. A later run with the same key and the same
|
|
53
|
+
* input returns that result without running the handler; the same key with another input
|
|
54
|
+
* or another command is `CONFLICT`. The result must survive JSON storage, or the first run
|
|
55
|
+
* fails with `UNSTABLE_SCHEMA`. Scope a key from outside to its caller: `${tenant}:${id}`.
|
|
56
|
+
*/
|
|
57
|
+
readonly idempotencyKey?: string;
|
|
58
|
+
};
|
|
59
|
+
/** Options of `journal.run` and `journal.bind`. */
|
|
60
|
+
export type RunOptions = CallOptions & {
|
|
61
|
+
/**
|
|
62
|
+
* Seeds the chain's correlation id, for example with the request id. Without it, a run
|
|
63
|
+
* from an effect continues the cause event's chain, and any other run starts a new one.
|
|
64
|
+
*/
|
|
65
|
+
readonly correlationId?: string;
|
|
66
|
+
};
|
|
67
|
+
export type CommandContext<out MetaOut, out Tx extends TransactionSource<Tx> = DbHandle> = {
|
|
68
|
+
/** The command's transaction. Use it for reads and for writes outside any entity. */
|
|
69
|
+
readonly tx: Tx;
|
|
70
|
+
/** The parsed metadata every `write` in this command records. */
|
|
71
|
+
readonly meta: MetaOut;
|
|
72
|
+
/** This run's `cmd_` id. Every event it writes carries it. */
|
|
73
|
+
readonly commandId: string;
|
|
74
|
+
/** The chain this run belongs to. Every event it writes carries it; a child run inherits it. */
|
|
75
|
+
readonly correlationId: string;
|
|
76
|
+
/** `journal.write` on this command's transaction with this command's metadata. Safe to destructure. */
|
|
77
|
+
readonly write: <K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(entity: EntityDef<K, Tbl, E, MetaOut, Key>, id: EntityId<Tbl, Key>, events: NextEvents<Tbl, E, Tx>, opts?: WriteOptions) => Promise<WriteResult<Tbl, E, MetaOut, Key>>;
|
|
78
|
+
/** Run another command in a savepoint of this transaction, with the same metadata. Safe to destructure. */
|
|
79
|
+
readonly run: <S extends z.ZodType, R>(command: Command<S, R, MetaOut, Tx>, input: NoInfer<z.input<S>>, opts?: CallOptions) => Promise<Awaited<R>>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* The type of `context.run`. Use it in app code that passes `run` on, so the
|
|
83
|
+
* generic signature is not repeated there.
|
|
84
|
+
*/
|
|
85
|
+
export type CommandRunner<MetaOut, Tx extends TransactionSource<Tx> = DbHandle> = CommandContext<MetaOut, Tx>['run'];
|
|
86
|
+
/**
|
|
87
|
+
* The type of an effect's `ctx.run`: `journal.run` without `source`. It runs on the
|
|
88
|
+
* root database the worker or `drain` was given, in its own transaction. `meta`
|
|
89
|
+
* is required, as in `journal.run`: the library never picks an actor.
|
|
90
|
+
*/
|
|
91
|
+
export type RootCommandRunner<Meta extends z.ZodObject, Tx extends TransactionSource<Tx> = DbHandle> = <S extends z.ZodType, R>(command: Command<S, R, z.output<Meta>, Tx>, input: NoInfer<z.input<S>>, meta: z.input<Meta>, opts?: CallOptions) => Promise<Awaited<R>>;
|
|
92
|
+
export type WriteResult<Tbl extends EntityTable, E extends AnyEventDef, MetaOut, Key extends string = 'id'> = {
|
|
93
|
+
readonly row: Row<Tbl> | null;
|
|
94
|
+
readonly events: RecordedOf<E, MetaOut, EntityId<Tbl, Key>>[];
|
|
95
|
+
};
|
|
96
|
+
export type ForgetResult<Tbl extends EntityTable> = {
|
|
97
|
+
/** How many events were rewritten in this call. Already-erased events count again: the rewrite is the same. */
|
|
98
|
+
readonly erased: number;
|
|
99
|
+
/** The row after repair from the erased log, or `null` if the log says the entity is gone. */
|
|
100
|
+
readonly row: Row<Tbl> | null;
|
|
101
|
+
};
|
|
102
|
+
export type ReplayResult<Tbl extends EntityTable, E extends AnyEventDef, MetaOut, Key extends string = 'id'> = {
|
|
103
|
+
readonly row: ReducerRow<Tbl, Key> | null;
|
|
104
|
+
readonly events: RecordedOf<E, MetaOut, EntityId<Tbl, Key>>[];
|
|
105
|
+
};
|
|
106
|
+
export type VerifyResult<Tbl extends EntityTable, Key extends string = 'id'> = {
|
|
107
|
+
readonly ok: true;
|
|
108
|
+
} | {
|
|
109
|
+
readonly ok: false;
|
|
110
|
+
readonly expected: ReducerRow<Tbl, Key> | null;
|
|
111
|
+
readonly actual: Row<Tbl> | null;
|
|
112
|
+
};
|
|
113
|
+
export type Journal<Meta extends z.ZodObject, Tx extends TransactionSource<Tx> = DbHandle, AppDb extends RootDb = RootDb> = {
|
|
114
|
+
/** Append events, run reducers, save the row, run projections, queue jobs. All inside `tx`. */
|
|
115
|
+
write<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(tx: Tx, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>, input: WriteInput<Tbl, E, Meta, Tx>): Promise<WriteResult<Tbl, E, z.output<Meta>, Key>>;
|
|
116
|
+
/**
|
|
117
|
+
* Parse `input` and `meta`, then call the command's handler inside one
|
|
118
|
+
* transaction of `source`. A root database opens a transaction; a transaction
|
|
119
|
+
* opens a savepoint. Returns what the handler returns. Errors pass through.
|
|
120
|
+
* On a root database, a run that queued a job calls `wake()` after the commit.
|
|
121
|
+
*/
|
|
122
|
+
run<S extends z.ZodType, R>(source: TransactionSource<Tx>, command: Command<S, R, z.output<Meta>, Tx>, input: NoInfer<z.input<S>>, meta: z.input<Meta>, opts?: RunOptions): Promise<Awaited<R>>;
|
|
123
|
+
/**
|
|
124
|
+
* The command door: `run` with `source` and `meta` fixed. It returns
|
|
125
|
+
* `(command, input) => journal.run(source, command, input, meta)`. A request
|
|
126
|
+
* context binds it once with the signed-in actor; a job binds it with a
|
|
127
|
+
* system actor. The caller still gives `meta`: the library never picks an actor.
|
|
128
|
+
* `source` follows the rules of `run`: a root database commits and wakes, a
|
|
129
|
+
* transaction joins and leaves the commit to the caller.
|
|
130
|
+
* `meta` is parsed on every call, not once here, so a bound runner is exactly
|
|
131
|
+
* `run`: a default in the meta schema gives each command its own value, and
|
|
132
|
+
* a bad `meta` rejects the call, inside the transaction guard, as `run` does.
|
|
133
|
+
*/
|
|
134
|
+
bind(source: TransactionSource<Tx>, meta: z.input<Meta>, opts?: RunOptions): CommandRunner<z.output<Meta>, Tx>;
|
|
135
|
+
/**
|
|
136
|
+
* Bring a row that existed before the journal into it. The row must be at version 0
|
|
137
|
+
* with no history, or `CONFLICT`. `events` builds exactly one create event from the
|
|
138
|
+
* stored row. Its `.create` reducer must rebuild that row exactly, column by column,
|
|
139
|
+
* or `VALUE_MISMATCH` and nothing changes: replay folds from nothing and must land on
|
|
140
|
+
* the row as it is. The event is recorded as version 1 and the row moves to version 1,
|
|
141
|
+
* so `replay`, `verify` and `repair` work from then on. Projections run and effects
|
|
142
|
+
* are queued as for any write, because the event is the app's own.
|
|
143
|
+
*/
|
|
144
|
+
adopt<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(tx: Tx, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>, input: WriteInput<Tbl, E, Meta, Tx>): Promise<WriteResult<Tbl, E, z.output<Meta>, Key>>;
|
|
145
|
+
/** Rebuild the row from the log in memory. `throughVersion` is the last version applied. */
|
|
146
|
+
replay<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(db: DbHandle, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>, opts?: {
|
|
147
|
+
readonly throughVersion?: number;
|
|
148
|
+
}): Promise<ReplayResult<Tbl, E, z.output<Meta>, Key>>;
|
|
149
|
+
/** Replay and compare with the stored row on the columns the reducers produce. */
|
|
150
|
+
verify<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(db: DbHandle, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>): Promise<VerifyResult<Tbl, Key>>;
|
|
151
|
+
/**
|
|
152
|
+
* Remove personal data from one entity's history. Every stored event whose definition
|
|
153
|
+
* has an `erased` form gets its `data` rewritten to that form and `erased_at` set; events
|
|
154
|
+
* without one are left alone. Then the row is repaired from the rewritten log, so the row
|
|
155
|
+
* and its history agree. All in one transaction: an erased form the schema rejects is
|
|
156
|
+
* `BAD_DEFINITION` and nothing changes; a history replay cannot rebuild (a legacy row that
|
|
157
|
+
* was never adopted) is `NO_HISTORY` and nothing changes. Projections are not rerun, and no
|
|
158
|
+
* job is queued: the app owns its read models. Running it twice is safe.
|
|
159
|
+
*/
|
|
160
|
+
forget<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(db: DbHandle, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>): Promise<ForgetResult<Tbl>>;
|
|
161
|
+
/**
|
|
162
|
+
* Delete receipts recorded before `before`. Receipts hold inputs and results, which may
|
|
163
|
+
* carry personal data; `forget` does not touch them, so an app that keys personal flows
|
|
164
|
+
* prunes on a schedule. Returns how many were deleted.
|
|
165
|
+
*/
|
|
166
|
+
pruneReceipts(db: DbHandle, opts: {
|
|
167
|
+
readonly before: Date;
|
|
168
|
+
}): Promise<number>;
|
|
169
|
+
/** Lock the row, replay, save the result. Writes no event, runs no projection, creates no job. */
|
|
170
|
+
repair<K extends string, Tbl extends EntityTable, E extends AnyEventDef, Key extends string>(db: DbHandle, entity: EntityDef<K, Tbl, E, z.output<Meta>, Key>, id: EntityId<Tbl, Key>): Promise<Row<Tbl> | null>;
|
|
171
|
+
/**
|
|
172
|
+
* The async lane of projections: one batch per async projection. Each batch locks the
|
|
173
|
+
* projection's cursor, scans the next `batchSize` events in commit order, applies the
|
|
174
|
+
* matching ones on that transaction, and moves the cursor to the last event scanned.
|
|
175
|
+
* The worker calls it after every drain; call it yourself in tests or one-off scripts.
|
|
176
|
+
* A projection whose batch throws is skipped this pass and tried again next pass.
|
|
177
|
+
*/
|
|
178
|
+
catchUp(db: RootDb & TransactionSource<Tx>, opts?: {
|
|
179
|
+
readonly batchSize?: number;
|
|
180
|
+
}): Promise<{
|
|
181
|
+
readonly scanned: number;
|
|
182
|
+
}>;
|
|
183
|
+
/**
|
|
184
|
+
* Rewind an async projection to the start. `clear` runs on the same transaction, after the
|
|
185
|
+
* cursor is locked and before it is rewound, so the read model is emptied and refilled with
|
|
186
|
+
* no batch landing in between. To rebuild without downtime, deploy the projection under a
|
|
187
|
+
* new name into a new table instead, wait for `cursors` to show lag 0, then switch reads.
|
|
188
|
+
*/
|
|
189
|
+
reset(db: RootDb & TransactionSource<Tx>, projection: Projection<z.output<Meta>, Tx>, clear?: (tx: Tx) => Promise<void>): Promise<void>;
|
|
190
|
+
/** Per async projection: its cursor and how far behind the newest event it is, in seqs. */
|
|
191
|
+
cursors(db: DbHandle): Promise<readonly {
|
|
192
|
+
readonly name: string;
|
|
193
|
+
readonly seq: number;
|
|
194
|
+
readonly lag: number;
|
|
195
|
+
}[]>;
|
|
196
|
+
/** Walk the log after sequence number `afterSeq` and call one inline projection's handlers, a batch per transaction. Async projections use `reset` and `catchUp`. */
|
|
197
|
+
rerun(db: TransactionSource<Tx>, projection: Projection<z.output<Meta>, Tx>, opts?: {
|
|
198
|
+
readonly afterSeq?: number;
|
|
199
|
+
readonly batchSize?: number;
|
|
200
|
+
}): Promise<{
|
|
201
|
+
readonly events: number;
|
|
202
|
+
}>;
|
|
203
|
+
/**
|
|
204
|
+
* Run up to `batchSize` due jobs. Returns how many jobs were claimed. Root database only.
|
|
205
|
+
* It must open the journal's transaction type: an effect runs commands on it.
|
|
206
|
+
* Each job is claimed right before it runs, so its lease (`leaseSeconds`, default 60)
|
|
207
|
+
* covers only its own work, and the lease is renewed every half lease while the effect
|
|
208
|
+
* runs. A lost lease aborts the effect's `ctx.signal`.
|
|
209
|
+
* Once `signal` is aborted no further job is claimed; the running one sees it as `ctx.signal`.
|
|
210
|
+
*/
|
|
211
|
+
drain(db: AppDb & RootDb & TransactionSource<Tx>, opts?: {
|
|
212
|
+
readonly batchSize?: number;
|
|
213
|
+
readonly signal?: AbortSignal;
|
|
214
|
+
readonly leaseSeconds?: number;
|
|
215
|
+
}): Promise<number>;
|
|
216
|
+
/**
|
|
217
|
+
* A loop around `drain`. The same database as `drain`. `stop()` aborts the running
|
|
218
|
+
* effect's `ctx.signal`, claims nothing more, and resolves when that effect returns.
|
|
219
|
+
*/
|
|
220
|
+
worker(db: AppDb & RootDb & TransactionSource<Tx>, opts?: {
|
|
221
|
+
readonly pollMs?: number;
|
|
222
|
+
readonly batchSize?: number;
|
|
223
|
+
readonly leaseSeconds?: number;
|
|
224
|
+
/**
|
|
225
|
+
* Hear the wake channel (`journal.wakeChannel`): a commit that recorded events wakes this
|
|
226
|
+
* worker at once, from any process, and the journal's taps fire here for those events.
|
|
227
|
+
* Required when the journal has taps, unless `taps: false` says this worker runs jobs only.
|
|
228
|
+
*/
|
|
229
|
+
readonly listen?: WakeListener;
|
|
230
|
+
/** `false`: a jobs-only worker in a journal that has taps. Another process must listen. */
|
|
231
|
+
readonly taps?: boolean;
|
|
232
|
+
}): JournalWorker;
|
|
233
|
+
/**
|
|
234
|
+
* The Postgres channel every commit that recorded events notifies, with the seq range as
|
|
235
|
+
* JSON `{ "from": n, "to": m }`. `journal_wake`, or `<schema>_journal_wake` for tables in a
|
|
236
|
+
* schema. Payloads are small and bounded; a listener loads what it needs by seq.
|
|
237
|
+
*/
|
|
238
|
+
readonly wakeChannel: string;
|
|
239
|
+
/**
|
|
240
|
+
* Wake every running worker this journal started in this process. Call it
|
|
241
|
+
* after committing a transaction of your own that ran commands. No worker: nothing happens.
|
|
242
|
+
*/
|
|
243
|
+
wake(): void;
|
|
244
|
+
/**
|
|
245
|
+
* Pending jobs whose effect this journal does not have, counted per effect name.
|
|
246
|
+
* `drain` leaves them alone, because during a rolling deploy an older worker may
|
|
247
|
+
* still have that effect. After the deploy, a non-empty list means an effect was
|
|
248
|
+
* renamed or removed while it had jobs: bring it back under its old name until
|
|
249
|
+
* the count is zero, or delete those job rows on purpose.
|
|
250
|
+
*/
|
|
251
|
+
strandedJobs(db: DbHandle): Promise<readonly StrandedJobs[]>;
|
|
252
|
+
/**
|
|
253
|
+
* List job rows. `pending` (the default) is everything not dead: due, delayed and leased
|
|
254
|
+
* alike. `dead` is what the worker gave up on. Oldest due first, `limit` 100.
|
|
255
|
+
*/
|
|
256
|
+
jobs(db: DbHandle, opts?: {
|
|
257
|
+
readonly status?: 'pending' | 'dead' | 'all';
|
|
258
|
+
readonly effect?: string;
|
|
259
|
+
readonly limit?: number;
|
|
260
|
+
}): Promise<JournalTables['jobs']['$inferSelect'][]>;
|
|
261
|
+
/** A dead job back to pending: attempts and lease cleared, due now, workers woken. A job that is not dead throws. */
|
|
262
|
+
retry(db: DbHandle, jobId: string): Promise<void>;
|
|
263
|
+
/** Delete a dead job. A job that is not dead throws: deleting a live one would not stop its work. */
|
|
264
|
+
discard(db: DbHandle, jobId: string): Promise<void>;
|
|
265
|
+
/**
|
|
266
|
+
* The one way to extend a run from outside: a wrapper that receives the context and
|
|
267
|
+
* `next`. Command hooks run inside the transaction, around the handler; effect hooks run
|
|
268
|
+
* inside the lease, around the handler. Rules: call `next` exactly once, or throw before
|
|
269
|
+
* it to stop; a rejection of `next` is the hook's rejection too; the context is frozen
|
|
270
|
+
* and the result cannot be changed; hooks run in registration order, the first outermost.
|
|
271
|
+
* Register at boot: once the journal has run a command, a drain or a worker, `around`
|
|
272
|
+
* throws `BAD_DEFINITION`.
|
|
273
|
+
*/
|
|
274
|
+
readonly hooks: {
|
|
275
|
+
readonly command: HookPoint<CommandHookContext<z.output<Meta>>>;
|
|
276
|
+
readonly effect: HookPoint<EffectHookContext<z.output<Meta>>>;
|
|
277
|
+
};
|
|
278
|
+
readonly catalog: {
|
|
279
|
+
/**
|
|
280
|
+
* Only the entities that a projection or an effect of this journal names. An
|
|
281
|
+
* entity that no handler names is not listed, even when the app writes to it.
|
|
282
|
+
*/
|
|
283
|
+
readonly entities: readonly EntityInfo[];
|
|
284
|
+
readonly projections: readonly string[];
|
|
285
|
+
readonly effects: readonly string[];
|
|
286
|
+
readonly taps: readonly string[];
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
export type JournalDefinitions<Meta extends z.ZodObject, Tx extends TransactionSource<Tx> = DbHandle, AppDb extends RootDb = RootDb> = {
|
|
290
|
+
event<T extends string, S extends z.ZodType, const U extends readonly z.ZodType[] = readonly []>(type: T, schema: S, opts?: EventOptions<S, U>): EventDef<T, S>;
|
|
291
|
+
/** The key column is `id`. */
|
|
292
|
+
entity<K extends string, Tbl extends IdTable>(kind: K, table: Tbl): EntityBuilder<K, Tbl, never, z.output<Meta>, 'id'>;
|
|
293
|
+
/**
|
|
294
|
+
* The key column is the one `table` holds under the property name `options.key`:
|
|
295
|
+
* a non-null string column that is the primary key or unique.
|
|
296
|
+
*/
|
|
297
|
+
entity<K extends string, Tbl extends EntityTable, Key extends KeyName<Tbl>>(kind: K, table: Tbl, options: {
|
|
298
|
+
readonly key: Key & SingleKey<Key>;
|
|
299
|
+
}): EntityBuilder<K, Tbl, never, z.output<Meta>, Key>;
|
|
300
|
+
/**
|
|
301
|
+
* A command: `input` is parsed before the handler runs; the handler's
|
|
302
|
+
* `write` and `run` are bound to one transaction and one parsed `meta`.
|
|
303
|
+
* Needs only `j`, entities and events, never the finished journal.
|
|
304
|
+
*/
|
|
305
|
+
command<S extends z.ZodType, R>(name: string, input: S, handler: (input: z.output<S>, context: CommandContext<z.output<Meta>, Tx>) => R): Command<S, R, z.output<Meta>, Tx>;
|
|
306
|
+
/** `on` is `NoInfer` so `E` comes from `entity`; handlers are then contextually typed. */
|
|
307
|
+
projection<E extends AnyEntity<z.output<Meta>>>(name: string, entity: E | readonly E[], on: NoInfer<ProjectionHandlers<E, z.output<Meta>, Tx>>, opts?: ProjectionOptions): Projection<z.output<Meta>, Tx>;
|
|
308
|
+
effect<E extends AnyEntity<z.output<Meta>>>(name: string, entity: E | readonly E[], on: NoInfer<EffectHandlers<E, z.output<Meta>, AppDb, RootCommandRunner<Meta, Tx>>>): Effect<z.output<Meta>, AppDb, RootCommandRunner<Meta, Tx>>;
|
|
309
|
+
/**
|
|
310
|
+
* An effect that needs a service: `needs` is `{ mailer: need<Mailer>() }`, and each
|
|
311
|
+
* handler then gets `mailer` in its context, next to `jobId`, `signal`, `db` and `run`.
|
|
312
|
+
*/
|
|
313
|
+
effect<E extends AnyEntity<z.output<Meta>>, N extends Needs>(name: string, entity: E | readonly E[], needs: N, on: NoInfer<EffectHandlers<E, z.output<Meta>, AppDb, RootCommandRunner<Meta, Tx>, N>>): Effect<z.output<Meta>, AppDb, RootCommandRunner<Meta, Tx>, N>;
|
|
314
|
+
/**
|
|
315
|
+
* Build the runtime journal from the tables and the handlers. `services` holds one
|
|
316
|
+
* value for every need of every listed effect, by name. A need without a value throws here.
|
|
317
|
+
* `const`: the list is read as a tuple, so an effect with needs keeps them next to one without.
|
|
318
|
+
*/
|
|
319
|
+
/** A tap: in-process, after commit, lossy. See `Tap`. Same shapes as `effect`. */
|
|
320
|
+
tap<E extends AnyEntity<z.output<Meta>>>(name: string, entity: E | readonly E[], on: NoInfer<TapHandlers<E, z.output<Meta>, AppDb>>): Tap<z.output<Meta>, AppDb>;
|
|
321
|
+
tap<E extends AnyEntity<z.output<Meta>>, N extends Needs>(name: string, entity: E | readonly E[], needs: N, on: NoInfer<TapHandlers<E, z.output<Meta>, AppDb, N>>): Tap<z.output<Meta>, AppDb, N>;
|
|
322
|
+
compose<const E extends readonly Effect<z.output<Meta>, AppDb, RootCommandRunner<Meta, Tx>, Needs>[] = readonly [], const T extends readonly Tap<z.output<Meta>, AppDb, Needs>[] = readonly []>(config: {
|
|
323
|
+
readonly tables: JournalTables;
|
|
324
|
+
readonly projections?: readonly Projection<z.output<Meta>, Tx>[];
|
|
325
|
+
readonly effects?: E;
|
|
326
|
+
readonly taps?: T;
|
|
327
|
+
} & ServicesOption<ServicesFor<E> & ServicesFor<T>>): Journal<Meta, Tx, AppDb>;
|
|
328
|
+
};
|
|
329
|
+
/** `services` is required as soon as one listed effect has a need. */
|
|
330
|
+
type ServicesOption<S> = unknown extends S ? {
|
|
331
|
+
readonly services?: Services;
|
|
332
|
+
} : {
|
|
333
|
+
readonly services: S & Services;
|
|
334
|
+
};
|
|
335
|
+
export {};
|
|
336
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
ADDED
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command execution: parse the input, open the transaction, give the handler a
|
|
3
|
+
* context bound to it, and refuse to close while an operation is still running.
|
|
4
|
+
* May import `api`, `write` (types), `storage`, `transaction-guard` and leaf files.
|
|
5
|
+
* Must not import `journal`, `history` or `worker`.
|
|
6
|
+
*/
|
|
7
|
+
import type { z } from 'zod';
|
|
8
|
+
import type { Command, RunOptions } from './api.js';
|
|
9
|
+
import type { HookPointInternal } from './hooks.js';
|
|
10
|
+
import type { JournalTables } from './pg.js';
|
|
11
|
+
import type { CommandHookContext, TransactionSource } from './types.js';
|
|
12
|
+
import type { Writer } from './write.js';
|
|
13
|
+
/** What command execution needs from the journal. */
|
|
14
|
+
export type CommandDeps<Meta extends z.ZodObject, Tx extends TransactionSource<Tx>> = {
|
|
15
|
+
readonly metaSchema: Meta;
|
|
16
|
+
readonly writeWithValidatedMeta: Writer<Meta, Tx>['writeWithValidatedMeta'];
|
|
17
|
+
/** Wakes this journal's workers. Called after a root-database run that queued a job. */
|
|
18
|
+
readonly wake: () => void;
|
|
19
|
+
/** The command hooks. Frozen by the first run. */
|
|
20
|
+
readonly hooks: HookPointInternal<CommandHookContext<z.output<Meta>>>;
|
|
21
|
+
readonly tables: Pick<JournalTables, 'receipts'>;
|
|
22
|
+
};
|
|
23
|
+
export declare function createCommandRunner<Meta extends z.ZodObject, Tx extends TransactionSource<Tx>>(deps: CommandDeps<Meta, Tx>): <S extends z.ZodType, R>(source: TransactionSource<Tx>, command: Command<S, R, z.output<Meta>, Tx>, input: NoInfer<z.input<S>>, meta: z.input<Meta>, opts?: RunOptions, cause?: {
|
|
24
|
+
readonly seq: number;
|
|
25
|
+
readonly correlationId: string | null;
|
|
26
|
+
}) => Promise<Awaited<R>>;
|
|
27
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAI7B,OAAO,KAAK,EAAE,OAAO,EAAkB,UAAU,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAmB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAYzC,qDAAqD;AACrD,MAAM,MAAM,WAAW,CAAC,IAAI,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,SAAS,iBAAiB,CAAC,EAAE,CAAC,IAAI;IACpF,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,wBAAwB,CAAC,CAAC;IAC5E,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;CAClD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,SAAS,iBAAiB,CAAC,EAAE,CAAC,EAC5F,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,IAuKd,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,UACzB,iBAAiB,CAAC,EAAE,CAAC,WACpB,OAAO,CAAC,CAAC,EAAE,CAAC,kBAAW,EAAE,CAAC,SAC5B,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QACpB,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SACZ,UAAU,UACT;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,KACtE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA6BvB"}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { eq, is } from 'drizzle-orm';
|
|
2
|
+
import { PgAsyncTransaction } from 'drizzle-orm/pg-core';
|
|
3
|
+
import { debugCommand } from './debug.js';
|
|
4
|
+
import { JournalError } from './errors.js';
|
|
5
|
+
import { commandId, correlationId } from './id.js';
|
|
6
|
+
import { assertRoundTrips, sameValue } from './storage.js';
|
|
7
|
+
import { oneAtATime } from './transaction-guard.js';
|
|
8
|
+
/** What JSON storage keeps of `value`. `undefined` has no JSON form, so it comes back as `undefined` here too. */
|
|
9
|
+
const throughJson = (value) =>
|
|
10
|
+
// eslint-disable-next-line unicorn/prefer-structured-clone -- JSON semantics on purpose: this is what the column stores
|
|
11
|
+
value === undefined ? undefined : JSON.parse(JSON.stringify(value));
|
|
12
|
+
export function createCommandRunner(deps) {
|
|
13
|
+
const { metaSchema, writeWithValidatedMeta, hooks } = deps;
|
|
14
|
+
const receipts = deps.tables.receipts;
|
|
15
|
+
/**
|
|
16
|
+
* Take the key for this run, or find the run that holds it. Returns `{ replay }` with the
|
|
17
|
+
* stored result when a finished run holds the key with the same command and input. The
|
|
18
|
+
* insert waits on an uncommitted holder, so a concurrent repeat sees its outcome.
|
|
19
|
+
*/
|
|
20
|
+
const claimReceipt = async (tx, key, name, input, own) => {
|
|
21
|
+
const inserted = await tx
|
|
22
|
+
.insert(receipts)
|
|
23
|
+
.values({ key, command: name, input: throughJson(input) ?? null, commandId: own })
|
|
24
|
+
.onConflictDoNothing()
|
|
25
|
+
.returning({ key: receipts.key });
|
|
26
|
+
if (inserted.length > 0)
|
|
27
|
+
return undefined;
|
|
28
|
+
const [held] = await tx.select().from(receipts).where(eq(receipts.key, key));
|
|
29
|
+
if (held === undefined)
|
|
30
|
+
throw new Error(`journal: idempotency key ${JSON.stringify(key)} vanished while it was being claimed`);
|
|
31
|
+
// Only a run inside this transaction can see an unfinished receipt: a concurrent one waited on the insert.
|
|
32
|
+
if (held.result === null)
|
|
33
|
+
throw new Error(`journal: idempotency key ${JSON.stringify(key)} is held by a run of "${held.command}" that has not finished; a key cannot be reused inside its own transaction`);
|
|
34
|
+
if (held.command !== name)
|
|
35
|
+
throw new JournalError('CONFLICT', 'receipt', key, `the idempotency key is held by command "${held.command}", not "${name}"`);
|
|
36
|
+
if (!sameValue(held.input, throughJson(input) ?? null))
|
|
37
|
+
throw new JournalError('CONFLICT', 'receipt', key, `the idempotency key was used by command "${name}" with a different input`);
|
|
38
|
+
return { replay: 'value' in held.result ? held.result.value : undefined };
|
|
39
|
+
};
|
|
40
|
+
/** Store the result under the key. It must survive JSON, because the replay returns the stored form. */
|
|
41
|
+
const storeReceipt = async (tx, key, name, value) => {
|
|
42
|
+
const stored = throughJson(value);
|
|
43
|
+
if (!sameValue(stored, value))
|
|
44
|
+
throw new JournalError('UNSTABLE_SCHEMA', 'command', name, `the result of command "${name}" does not survive JSON storage; a command run with an idempotency key must return plain data, because a repeat returns the stored result`);
|
|
45
|
+
await tx
|
|
46
|
+
.update(receipts)
|
|
47
|
+
.set({ result: stored === undefined ? {} : { value: stored } })
|
|
48
|
+
.where(eq(receipts.key, key));
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* `journal.run` and `context.run` share this. `getValidatedMeta` gives the parsed meta:
|
|
52
|
+
* the root call parses it, a child inherits it. It runs inside the one-at-a-time
|
|
53
|
+
* guard, so a bad meta on a busy transaction waits like any other rejection.
|
|
54
|
+
* `onJobs` hears how many jobs each write queued, in this command and its children.
|
|
55
|
+
* `parent` is the trace this run continues: the chain's correlation id and cause are
|
|
56
|
+
* inherited, the command id is this run's own.
|
|
57
|
+
*/
|
|
58
|
+
const runCommand = (source, command, input, getValidatedMeta, onJobs, parent, key) => oneAtATime(source, `command "${command.name}"`, async () => {
|
|
59
|
+
hooks.freeze();
|
|
60
|
+
const meta = await getValidatedMeta();
|
|
61
|
+
const parsed = await command.input.parseAsync(input);
|
|
62
|
+
const own = commandId();
|
|
63
|
+
const trace = { ...parent, commandId: own };
|
|
64
|
+
debugCommand.debug('{commandName}: input ok ({own}, {correlationId})', {
|
|
65
|
+
commandName: command.name,
|
|
66
|
+
own,
|
|
67
|
+
correlationId: trace.correlationId,
|
|
68
|
+
});
|
|
69
|
+
return source.transaction(async (tx) => {
|
|
70
|
+
// Every operation the handler starts through this context. The transaction
|
|
71
|
+
// must not close while one is still running: its work would land outside.
|
|
72
|
+
const started = [];
|
|
73
|
+
let unfinished = 0;
|
|
74
|
+
const track = (operation) => {
|
|
75
|
+
started.push(operation);
|
|
76
|
+
unfinished += 1;
|
|
77
|
+
const done = () => {
|
|
78
|
+
unfinished -= 1;
|
|
79
|
+
};
|
|
80
|
+
void operation.then(done, done);
|
|
81
|
+
return operation;
|
|
82
|
+
};
|
|
83
|
+
const context = {
|
|
84
|
+
tx,
|
|
85
|
+
meta,
|
|
86
|
+
commandId: own,
|
|
87
|
+
correlationId: trace.correlationId,
|
|
88
|
+
write: (entity, id, events, opts) => track(writeWithValidatedMeta(tx, entity, id, () => meta, events, trace, onJobs, opts)),
|
|
89
|
+
run: (child, childInput, childOpts) => track(runCommand(tx, child, childInput, () => Promise.resolve(meta), onJobs, trace, childOpts?.idempotencyKey)),
|
|
90
|
+
};
|
|
91
|
+
let result;
|
|
92
|
+
try {
|
|
93
|
+
// Inside the transaction: a hook that throws rolls the command back cleanly.
|
|
94
|
+
result = await hooks.run({
|
|
95
|
+
name: command.name,
|
|
96
|
+
input: parsed,
|
|
97
|
+
meta,
|
|
98
|
+
commandId: own,
|
|
99
|
+
correlationId: trace.correlationId,
|
|
100
|
+
idempotencyKey: key ?? null,
|
|
101
|
+
}, async () => {
|
|
102
|
+
if (key === undefined)
|
|
103
|
+
return await command.handler(parsed, context);
|
|
104
|
+
const held = await claimReceipt(tx, key, command.name, parsed, own);
|
|
105
|
+
if (held !== undefined) {
|
|
106
|
+
debugCommand.debug('{commandName}: replayed from receipt {key}', { commandName: command.name, key });
|
|
107
|
+
// The receipt holds what this same command returned earlier, in the JSON form
|
|
108
|
+
// `storeReceipt` checked against the live value. This is the one cast in the library.
|
|
109
|
+
return held.replay;
|
|
110
|
+
}
|
|
111
|
+
const value = await command.handler(parsed, context);
|
|
112
|
+
await storeReceipt(tx, key, command.name, value);
|
|
113
|
+
return value;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
// The handler's own error is the one to report; the rollback undoes the rest.
|
|
118
|
+
await Promise.allSettled(started);
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
121
|
+
if (unfinished > 0) {
|
|
122
|
+
const count = unfinished;
|
|
123
|
+
await Promise.allSettled(started);
|
|
124
|
+
throw new Error(`journal: command "${command.name}" returned with ${count} journal operation${count === 1 ? '' : 's'} still running; await every write and run before the handler returns`);
|
|
125
|
+
}
|
|
126
|
+
debugCommand.debug('{commandName}: done', { commandName: command.name });
|
|
127
|
+
return result;
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* `journal.run`: parses `meta` once for the whole command. `cause` is set only by an
|
|
132
|
+
* effect's `ctx.run`: the event the job was for. Its correlation id carries over unless
|
|
133
|
+
* `opts.correlationId` says otherwise; with neither, the run starts a new chain.
|
|
134
|
+
*/
|
|
135
|
+
const run = (source, command, input, meta, opts, cause) => {
|
|
136
|
+
let queued = 0;
|
|
137
|
+
return runCommand(source, command, input, async () => {
|
|
138
|
+
const parsed = await metaSchema.parseAsync(meta);
|
|
139
|
+
// No entity yet: the error names the command instead.
|
|
140
|
+
assertRoundTrips(metaSchema, parsed, 'command', command.name, 'meta');
|
|
141
|
+
return parsed;
|
|
142
|
+
}, count => {
|
|
143
|
+
queued += count;
|
|
144
|
+
}, {
|
|
145
|
+
causeSeq: cause?.seq ?? null,
|
|
146
|
+
correlationId: opts?.correlationId ?? cause?.correlationId ?? correlationId(),
|
|
147
|
+
}, opts?.idempotencyKey).then(result => {
|
|
148
|
+
// The root database has committed by now. Inside a caller's transaction
|
|
149
|
+
// only the caller knows when the commit happens, so the caller wakes.
|
|
150
|
+
if (queued > 0 && !is(source, PgAsyncTransaction))
|
|
151
|
+
deps.wake();
|
|
152
|
+
return result;
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
return run;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAOzD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,kHAAkH;AAClH,MAAM,WAAW,GAAG,CAAC,KAAc,EAAW,EAAE;AAC9C,wHAAwH;AACxH,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAatE,MAAM,UAAU,mBAAmB,CACjC,IAA2B;IAG3B,MAAM,EAAE,UAAU,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;IAEtC;;;;OAIG;IACH,MAAM,YAAY,GAAG,KAAK,EACxB,EAAY,EACZ,GAAW,EACX,IAAY,EACZ,KAAc,EACd,GAAW,EACwC,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,EAAE;aACtB,MAAM,CAAC,QAAQ,CAAC;aAChB,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;aACjF,mBAAmB,EAAE;aACrB,SAAS,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7E,IAAI,IAAI,KAAK,SAAS;YACpB,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACzG,2GAA2G;QAC3G,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YACtB,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,OAAO,4EAA4E,CACjK,CAAC;QACJ,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI;YACvB,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,SAAS,EACT,GAAG,EACH,2CAA2C,IAAI,CAAC,OAAO,WAAW,IAAI,GAAG,CAC1E,CAAC;QACJ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;YACpD,MAAM,IAAI,YAAY,CACpB,UAAU,EACV,SAAS,EACT,GAAG,EACH,4CAA4C,IAAI,0BAA0B,CAC3E,CAAC;QACJ,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IAC5E,CAAC,CAAC;IAEF,wGAAwG;IACxG,MAAM,YAAY,GAAG,KAAK,EAAE,EAAY,EAAE,GAAW,EAAE,IAAY,EAAE,KAAc,EAAiB,EAAE;QACpG,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;YAC3B,MAAM,IAAI,YAAY,CACpB,iBAAiB,EACjB,SAAS,EACT,IAAI,EACJ,0BAA0B,IAAI,2IAA2I,CAC1K,CAAC;QACJ,MAAM,EAAE;aACL,MAAM,CAAC,QAAQ,CAAC;aAChB,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;aAC9D,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC;IAEF;;;;;;;OAOG;IACH,MAAM,UAAU,GAAG,CACjB,MAA6B,EAC7B,OAAmC,EACnC,KAAiB,EACjB,gBAAwC,EACxC,MAA+B,EAC/B,MAAgC,EAChC,GAAuB,EACF,EAAE,CACvB,UAAU,CAAC,MAAM,EAAE,YAAY,OAAO,CAAC,IAAI,GAAG,EAAE,KAAK,IAAyB,EAAE;QAC9E,KAAK,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,gBAAgB,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;QACxB,MAAM,KAAK,GAAU,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QACnD,YAAY,CAAC,KAAK,CAAC,kDAAkD,EAAE;YACrE,WAAW,EAAE,OAAO,CAAC,IAAI;YACzB,GAAG;YACH,aAAa,EAAE,KAAK,CAAC,aAAa;SACnC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,EAAuB,EAAE;YAC1D,2EAA2E;YAC3E,0EAA0E;YAC1E,MAAM,OAAO,GAAuB,EAAE,CAAC;YACvC,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,MAAM,KAAK,GAAG,CAAI,SAAqB,EAAc,EAAE;gBACrD,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,UAAU,IAAI,CAAC,CAAC;gBAChB,MAAM,IAAI,GAAG,GAAG,EAAE;oBAChB,UAAU,IAAI,CAAC,CAAC;gBAClB,CAAC,CAAC;gBACF,KAAK,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAChC,OAAO,SAAS,CAAC;YACnB,CAAC,CAAC;YACF,MAAM,OAAO,GAAgC;gBAC3C,EAAE;gBACF,IAAI;gBACJ,SAAS,EAAE,GAAG;gBACd,aAAa,EAAE,KAAK,CAAC,aAAa;gBAClC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAClC,KAAK,CAAC,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBACxF,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CACpC,KAAK,CACH,UAAU,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,CACzG;aACJ,CAAC;YACF,IAAI,MAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,6EAA6E;gBAC7E,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CACtB;oBACE,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK,EAAE,MAAM;oBACb,IAAI;oBACJ,SAAS,EAAE,GAAG;oBACd,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,cAAc,EAAE,GAAG,IAAI,IAAI;iBAC5B,EACD,KAAK,IAAyB,EAAE;oBAC9B,IAAI,GAAG,KAAK,SAAS;wBAAE,OAAO,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBACrE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;oBACpE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;wBACvB,YAAY,CAAC,KAAK,CAAC,4CAA4C,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;wBACrG,8EAA8E;wBAC9E,sFAAsF;wBACtF,OAAO,IAAI,CAAC,MAAoB,CAAC;oBACnC,CAAC;oBACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBACrD,MAAM,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBACjD,OAAO,KAAK,CAAC;gBACf,CAAC,CACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,8EAA8E;gBAC9E,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAClC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;gBACnB,MAAM,KAAK,GAAG,UAAU,CAAC;gBACzB,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAClC,MAAM,IAAI,KAAK,CACb,qBAAqB,OAAO,CAAC,IAAI,mBAAmB,KAAK,qBAAqB,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,sEAAsE,CAC3K,CAAC;YACJ,CAAC;YACD,YAAY,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACzE,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL;;;;OAIG;IACH,MAAM,GAAG,GAAG,CACV,MAA6B,EAC7B,OAAmC,EACnC,KAA0B,EAC1B,IAAmB,EACnB,IAAiB,EACjB,KAAuE,EAClD,EAAE;QACvB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,UAAU,CACf,MAAM,EACN,OAAO,EACP,KAAK,EACL,KAAK,IAAI,EAAE;YACT,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACjD,sDAAsD;YACtD,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtE,OAAO,MAAM,CAAC;QAChB,CAAC,EACD,KAAK,CAAC,EAAE;YACN,MAAM,IAAI,KAAK,CAAC;QAClB,CAAC,EACD;YACE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,IAAI;YAC5B,aAAa,EAAE,IAAI,EAAE,aAAa,IAAI,KAAK,EAAE,aAAa,IAAI,aAAa,EAAE;SAC9E,EACD,IAAI,EAAE,cAAc,CACrB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACd,wEAAwE;YACxE,sEAAsE;YACtE,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC;gBAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/D,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Enable with `DEBUG=arki:journal:*`. */
|
|
2
|
+
export declare const debugWrite: import("@arki/log").Logger;
|
|
3
|
+
export declare const debugCommand: import("@arki/log").Logger;
|
|
4
|
+
export declare const debugReplay: import("@arki/log").Logger;
|
|
5
|
+
export declare const debugDrain: import("@arki/log").Logger;
|
|
6
|
+
export declare const debugWorker: import("@arki/log").Logger;
|
|
7
|
+
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAEA,0CAA0C;AAC1C,eAAO,MAAM,UAAU,4BAAkC,CAAC;AAC1D,eAAO,MAAM,YAAY,4BAAoC,CAAC;AAC9D,eAAO,MAAM,WAAW,4BAAmC,CAAC;AAC5D,eAAO,MAAM,UAAU,4BAAkC,CAAC;AAC1D,eAAO,MAAM,WAAW,4BAAmC,CAAC"}
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getLogger } from '@arki/log';
|
|
2
|
+
/** Enable with `DEBUG=arki:journal:*`. */
|
|
3
|
+
export const debugWrite = getLogger('arki:journal:write');
|
|
4
|
+
export const debugCommand = getLogger('arki:journal:command');
|
|
5
|
+
export const debugReplay = getLogger('arki:journal:replay');
|
|
6
|
+
export const debugDrain = getLogger('arki:journal:drain');
|
|
7
|
+
export const debugWorker = getLogger('arki:journal:worker');
|
|
8
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,oBAAoB,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC,sBAAsB,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC,oBAAoB,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC"}
|