@arki/journal 0.0.0-stage → 0.1.0

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.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +541 -2
  3. package/dist/api.d.ts +336 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +2 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/command.d.ts +27 -0
  8. package/dist/command.d.ts.map +1 -0
  9. package/dist/command.js +157 -0
  10. package/dist/command.js.map +1 -0
  11. package/dist/debug.d.ts +7 -0
  12. package/dist/debug.d.ts.map +1 -0
  13. package/dist/debug.js +8 -0
  14. package/dist/debug.js.map +1 -0
  15. package/dist/dot.d.ts +102 -0
  16. package/dist/dot.d.ts.map +1 -0
  17. package/dist/dot.js +159 -0
  18. package/dist/dot.js.map +1 -0
  19. package/dist/entity.d.ts +56 -0
  20. package/dist/entity.d.ts.map +1 -0
  21. package/dist/entity.js +174 -0
  22. package/dist/entity.js.map +1 -0
  23. package/dist/errors.d.ts +47 -0
  24. package/dist/errors.d.ts.map +1 -0
  25. package/dist/errors.js +112 -0
  26. package/dist/errors.js.map +1 -0
  27. package/dist/event.d.ts +9 -0
  28. package/dist/event.d.ts.map +1 -0
  29. package/dist/event.js +19 -0
  30. package/dist/event.js.map +1 -0
  31. package/dist/fold.d.ts +29 -0
  32. package/dist/fold.d.ts.map +1 -0
  33. package/dist/fold.js +49 -0
  34. package/dist/fold.js.map +1 -0
  35. package/dist/handlers.d.ts +26 -0
  36. package/dist/handlers.d.ts.map +1 -0
  37. package/dist/handlers.js +130 -0
  38. package/dist/handlers.js.map +1 -0
  39. package/dist/history.d.ts +49 -0
  40. package/dist/history.d.ts.map +1 -0
  41. package/dist/history.js +259 -0
  42. package/dist/history.js.map +1 -0
  43. package/dist/hooks.d.ts +14 -0
  44. package/dist/hooks.d.ts.map +1 -0
  45. package/dist/hooks.js +67 -0
  46. package/dist/hooks.js.map +1 -0
  47. package/dist/id.d.ts +18 -0
  48. package/dist/id.d.ts.map +1 -0
  49. package/dist/id.js +41 -0
  50. package/dist/id.js.map +1 -0
  51. package/dist/index.d.ts +12 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +5 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/journal.d.ts +51 -0
  56. package/dist/journal.d.ts.map +1 -0
  57. package/dist/journal.js +181 -0
  58. package/dist/journal.js.map +1 -0
  59. package/dist/listen.d.ts +37 -0
  60. package/dist/listen.d.ts.map +1 -0
  61. package/dist/listen.js +90 -0
  62. package/dist/listen.js.map +1 -0
  63. package/dist/orpc.d.ts +21 -0
  64. package/dist/orpc.d.ts.map +1 -0
  65. package/dist/orpc.js +57 -0
  66. package/dist/orpc.js.map +1 -0
  67. package/dist/pg.d.ts +537 -0
  68. package/dist/pg.d.ts.map +1 -0
  69. package/dist/pg.js +80 -0
  70. package/dist/pg.js.map +1 -0
  71. package/dist/storage.d.ts +52 -0
  72. package/dist/storage.d.ts.map +1 -0
  73. package/dist/storage.js +221 -0
  74. package/dist/storage.js.map +1 -0
  75. package/dist/testing.d.ts +19 -0
  76. package/dist/testing.d.ts.map +1 -0
  77. package/dist/testing.js +23 -0
  78. package/dist/testing.js.map +1 -0
  79. package/dist/transaction-guard.d.ts +2 -0
  80. package/dist/transaction-guard.d.ts.map +1 -0
  81. package/dist/transaction-guard.js +39 -0
  82. package/dist/transaction-guard.js.map +1 -0
  83. package/dist/types.d.ts +414 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +2 -0
  86. package/dist/types.js.map +1 -0
  87. package/dist/worker.d.ts +109 -0
  88. package/dist/worker.d.ts.map +1 -0
  89. package/dist/worker.js +459 -0
  90. package/dist/worker.js.map +1 -0
  91. package/dist/write.d.ts +39 -0
  92. package/dist/write.d.ts.map +1 -0
  93. package/dist/write.js +287 -0
  94. package/dist/write.js.map +1 -0
  95. package/docs/agent-guide.md +324 -0
  96. package/llms.txt +40 -0
  97. package/package.json +99 -4
  98. package/src/api.ts +465 -0
  99. package/src/command.ts +242 -0
  100. package/src/debug.ts +8 -0
  101. package/src/dot.ts +296 -0
  102. package/src/entity.ts +377 -0
  103. package/src/errors.ts +134 -0
  104. package/src/event.ts +26 -0
  105. package/src/fold.ts +97 -0
  106. package/src/handlers.ts +262 -0
  107. package/src/history.ts +390 -0
  108. package/src/hooks.ts +85 -0
  109. package/src/id.ts +54 -0
  110. package/src/index.ts +76 -0
  111. package/src/journal.ts +256 -0
  112. package/src/listen.ts +109 -0
  113. package/src/orpc.ts +59 -0
  114. package/src/pg.ts +107 -0
  115. package/src/storage.ts +277 -0
  116. package/src/test-support.ts +82 -0
  117. package/src/testing.ts +23 -0
  118. package/src/transaction-guard.ts +41 -0
  119. package/src/types.ts +439 -0
  120. package/src/worker.ts +610 -0
  121. package/src/write.ts +434 -0
@@ -0,0 +1,259 @@
1
+ import { and, asc, eq, gt, inArray, max, sql } from 'drizzle-orm';
2
+ import { debugReplay } from './debug.js';
3
+ import { JournalError } from './errors.js';
4
+ import { findEventDefinition, fold, hasDeclaredEventType } from './fold.js';
5
+ import { assertExactId, assertStoredId, assertStoredValues, deepFreeze, isRowOf, loadRow, sameValue, saveReplayed, toRecord, } from './storage.js';
6
+ /**
7
+ * Every version from 1 to the top must be stored. A hole means an event was lost
8
+ * after it was written. Folding around it would build a row the real history never
9
+ * produced, and `repair` would save it. The rows come ordered by version, and the
10
+ * unique index allows one row per version, so position and version must agree.
11
+ */
12
+ function assertNoHoles(kind, id, rows) {
13
+ for (const [index, row] of rows.entries()) {
14
+ if (row.version !== index + 1) {
15
+ throw new JournalError('HISTORY_GAP', kind, id, `version ${index + 1} is missing from the log; the next stored version is ${row.version}`);
16
+ }
17
+ }
18
+ }
19
+ /**
20
+ * A stored row newer than a log that says the entity is alive lost its last events.
21
+ * Repair would quietly roll the row back, so replay refuses instead. When the log
22
+ * says the entity is gone, a row at any version was placed outside the journal and
23
+ * repair removes it: see `assertLogSaysGone`.
24
+ */
25
+ function assertRowNotAhead(kind, id, folded, top, current) {
26
+ if (folded === null || current === null)
27
+ return;
28
+ if ('version' in current && typeof current.version === 'number' && current.version > top) {
29
+ throw new JournalError('HISTORY_GAP', kind, id, `the row is at version ${current.version} but the log ends at version ${top}`);
30
+ }
31
+ }
32
+ export function createHistory(deps) {
33
+ const { metaSchema } = deps;
34
+ const eventsTable = deps.tables.events;
35
+ /**
36
+ * Turn a stored log row into a recorded event, parsing data and meta with
37
+ * their current schemas. `id` is the row's entity id as the caller types it.
38
+ */
39
+ /**
40
+ * Lift a row's data from the schema version it was written at to the event's current
41
+ * one, one step at a time. Each step parses with its own `from` schema first, so a bad
42
+ * row names the version it failed at. Data already at the current version is returned as is.
43
+ */
44
+ const upcast = (row, def, at) => {
45
+ const fail = (why) => {
46
+ throw new JournalError('REPLAY_FAILED', row.kind, row.entityId, `${at}: ${why}`);
47
+ };
48
+ if (row.schemaVersion > def.version) {
49
+ return fail(`written at schema version ${row.schemaVersion}, but the event declares version ${def.version}`);
50
+ }
51
+ let value = row.data;
52
+ for (let version = row.schemaVersion; version < def.version; version += 1) {
53
+ const step = def.upcasters[version - 1];
54
+ if (step === undefined)
55
+ return fail(`no upcaster for schema version ${version}`);
56
+ const old = step.from.safeParse(value);
57
+ if (!old.success)
58
+ return fail(`the data does not fit schema version ${version}: ${old.error.message}`);
59
+ try {
60
+ value = step.up(old.data);
61
+ }
62
+ catch (error) {
63
+ return fail(`the upcaster from version ${version} threw: ${error instanceof Error ? error.message : String(error)}`);
64
+ }
65
+ }
66
+ return value;
67
+ };
68
+ const decodeStoredEvent = (row, def, id) => {
69
+ const at = `event ${row.id} ("${row.type}" at version ${row.version})`;
70
+ if (def === undefined) {
71
+ throw new JournalError('REPLAY_FAILED', row.kind, row.entityId, `${at}: the entity declares no event of this type`);
72
+ }
73
+ const data = def.schema.safeParse(upcast(row, def, at));
74
+ if (!data.success) {
75
+ const after = row.schemaVersion < def.version ? ` after upcasting from version ${row.schemaVersion}` : '';
76
+ throw new JournalError('REPLAY_FAILED', row.kind, row.entityId, `${at}: the data does not fit the current schema${after}: ${data.error.message}`);
77
+ }
78
+ const meta = metaSchema.safeParse(row.meta);
79
+ if (!meta.success) {
80
+ throw new JournalError('REPLAY_FAILED', row.kind, row.entityId, `${at}: the meta does not fit the current meta schema: ${meta.error.message}`);
81
+ }
82
+ // Events are recorded facts: read-only for every reducer, projection, effect and caller.
83
+ return deepFreeze({
84
+ type: row.type,
85
+ data: data.data,
86
+ seq: row.seq,
87
+ id: row.id,
88
+ kind: row.kind,
89
+ entityId: id,
90
+ version: row.version,
91
+ meta: meta.data,
92
+ recordedAt: row.recordedAt,
93
+ commandId: row.commandId,
94
+ causeSeq: row.causeSeq,
95
+ correlationId: row.correlationId,
96
+ erasedAt: row.erasedAt,
97
+ });
98
+ };
99
+ const loadHistory = async (db, kind, id) => db
100
+ .select()
101
+ .from(eventsTable)
102
+ .where(and(eq(eventsTable.kind, kind), eq(eventsTable.entityId, id)))
103
+ .orderBy(asc(eventsTable.version));
104
+ const highestVersion = async (db, kind, id) => {
105
+ const [top] = await db
106
+ .select({ version: max(eventsTable.version) })
107
+ .from(eventsTable)
108
+ .where(and(eq(eventsTable.kind, kind), eq(eventsTable.entityId, id)));
109
+ return top?.version ?? 0;
110
+ };
111
+ const replayFrom = async (db, entity, id, current, throughVersion) => {
112
+ // The whole log, so `throughVersion` cannot hide an incomplete history behind an empty result.
113
+ const rows = await loadHistory(db, entity.kind, id);
114
+ const first = rows[0];
115
+ if (first === undefined && current !== null) {
116
+ throw new JournalError('NO_HISTORY', entity.kind, id, 'the row exists but the log holds no event for it');
117
+ }
118
+ // Version 1 is only ever written by a create from no row. A history that starts
119
+ // later belongs to a row that existed before the journal; folding it from nothing
120
+ // would pick the wrong reducers.
121
+ if (first !== undefined && first.version !== 1) {
122
+ throw new JournalError('NO_HISTORY', entity.kind, id, `the first stored version is ${first.version}`);
123
+ }
124
+ assertNoHoles(entity.kind, id, rows);
125
+ const all = decodeHistory(entity, id, rows);
126
+ // The whole history decides whether the entity is alive, whatever `throughVersion` says.
127
+ const full = fold(entity, null, id, all, 'replay').row;
128
+ assertRowNotAhead(entity.kind, id, full, rows.at(-1)?.version ?? 0, current);
129
+ const events = throughVersion === undefined ? all : all.filter(event => event.version <= throughVersion);
130
+ debugReplay.debug('{kind} {id}: {eventsLength} events', { kind: entity.kind, id, eventsLength: events.length });
131
+ return { row: throughVersion === undefined ? full : fold(entity, null, id, events, 'replay').row, events };
132
+ };
133
+ /** Decodes every row. The filter only narrows the type and drops nothing: see `hasDeclaredEventType`. */
134
+ const decodeHistory = (entity, id, rows) => rows
135
+ .map(row => decodeStoredEvent(row, entity.events.get(row.type), id))
136
+ .filter(event => hasDeclaredEventType(entity, event));
137
+ /**
138
+ * No row, but a log. Either a create follows a delete, or the row was removed
139
+ * outside the journal. The log decides: a history that starts at 1 is complete,
140
+ * and if it folds to a row, that row should be there. Creating over it would make
141
+ * write and replay pick different reducers for the same event. A history that
142
+ * starts later belongs to a pre-journal row and cannot be replayed, so it passes.
143
+ */
144
+ const assertLogSaysGone = async (db, entity, id, latestLogVersion) => {
145
+ const rows = await loadHistory(db, entity.kind, id);
146
+ if (rows[0]?.version !== 1)
147
+ return;
148
+ if (fold(entity, null, id, decodeHistory(entity, id, rows), 'replay').row !== null) {
149
+ throw new JournalError('CONFLICT', entity.kind, id, `the row is missing but its history says it exists at version ${latestLogVersion}; it was removed outside the journal, and repair restores it`);
150
+ }
151
+ };
152
+ const replay = async (db, entity, id, opts) => {
153
+ assertExactId(entity, id);
154
+ const current = await loadRow(db, entity, id, false);
155
+ return replayFrom(db, entity, id, current, opts?.throughVersion);
156
+ };
157
+ const verify = async (db, entity, id) => {
158
+ assertExactId(entity, id);
159
+ const loaded = await loadRow(db, entity, id, false);
160
+ assertStoredId(entity, loaded, id);
161
+ if (loaded !== null && !isRowOf(entity.table, loaded)) {
162
+ throw new Error(`journal: ${entity.kind} ${id} row is missing columns`);
163
+ }
164
+ const actual = loaded;
165
+ const { row: expected } = await replayFrom(db, entity, id, actual);
166
+ if (expected === null && actual === null)
167
+ return { ok: true };
168
+ if (expected === null || actual === null)
169
+ return { ok: false, expected, actual };
170
+ const want = toRecord(expected);
171
+ const have = toRecord(actual);
172
+ const ok = Object.keys(want).every(key => sameValue(want[key], have[key]));
173
+ return ok ? { ok: true } : { ok: false, expected, actual };
174
+ };
175
+ const repair = async (db, entity, id) => {
176
+ assertExactId(entity, id);
177
+ return db.transaction(async (tx) => {
178
+ const current = await loadRow(tx, entity, id, true);
179
+ assertStoredId(entity, current, id);
180
+ const { row: expected } = await replayFrom(tx, entity, id, current);
181
+ debugReplay.debug('{kind} {id}: repair -> {value3}', {
182
+ kind: entity.kind,
183
+ id,
184
+ value3: expected === null ? 'delete' : `v${expected.version}`,
185
+ });
186
+ const saved = await saveReplayed(tx, entity, id, current, expected);
187
+ // Throwing rolls the transaction back, so the row stays as it was.
188
+ if (saved !== null && expected !== null)
189
+ assertStoredValues(entity, id, expected, saved, Object.keys(expected));
190
+ return saved;
191
+ });
192
+ };
193
+ const forget = async (db, entity, id) => {
194
+ assertExactId(entity, id);
195
+ return db.transaction(async (tx) => {
196
+ // The row lock first, so no write lands between the rewrite and the repair. Then every
197
+ // async cursor, so no projection batch in flight commits the data after it was erased.
198
+ await loadRow(tx, entity, id, true);
199
+ await tx.select({ name: deps.tables.cursors.name }).from(deps.tables.cursors).for('update');
200
+ const rows = await loadHistory(tx, entity.kind, id);
201
+ let erased = 0;
202
+ for (const row of rows) {
203
+ const def = entity.events.get(row.type);
204
+ if (def?.erased === undefined)
205
+ continue;
206
+ // Decode as replay does, so the erased form starts from data the schema accepts.
207
+ const event = decodeStoredEvent(row, def, id);
208
+ const form = def.schema.safeParse(def.erased(event.data));
209
+ if (!form.success) {
210
+ throw new JournalError('BAD_DEFINITION', entity.kind, id, `event "${row.type}": its erased form does not fit its own schema: ${form.error.message}`);
211
+ }
212
+ await tx
213
+ .update(eventsTable)
214
+ .set({
215
+ data: form.data,
216
+ schemaVersion: def.version,
217
+ erasedAt: sql `coalesce(${eventsTable.erasedAt}, now())`,
218
+ })
219
+ .where(eq(eventsTable.seq, row.seq));
220
+ erased += 1;
221
+ }
222
+ // The row must match the history it now has. Repair on `tx` is a savepoint.
223
+ const row = await repair(tx, entity, id);
224
+ debugReplay.debug('{kind} {id}: forget -> {erased} events erased', { kind: entity.kind, id, erased });
225
+ return { erased, row };
226
+ });
227
+ };
228
+ const rerun = async (db, projection, opts) => {
229
+ const batchSize = opts?.batchSize ?? 100;
230
+ const kinds = projection.entities.map(entity => entity.kind);
231
+ let cursor = opts?.afterSeq ?? 0;
232
+ let count = 0;
233
+ if (kinds.length === 0 || projection.types.size === 0)
234
+ return { events: 0 };
235
+ for (;;) {
236
+ const rows = await db
237
+ .select()
238
+ .from(eventsTable)
239
+ .where(and(gt(eventsTable.seq, cursor), inArray(eventsTable.kind, kinds), inArray(eventsTable.type, [...projection.types])))
240
+ .orderBy(asc(eventsTable.seq))
241
+ .limit(batchSize);
242
+ if (rows.length === 0)
243
+ break;
244
+ await db.transaction(async (tx) => {
245
+ for (const row of rows) {
246
+ await projection.run(tx, decodeStoredEvent(row, findEventDefinition(projection.entities, row.kind, row.type), row.entityId));
247
+ }
248
+ });
249
+ count += rows.length;
250
+ cursor = rows.at(-1)?.seq ?? cursor;
251
+ if (rows.length < batchSize)
252
+ break;
253
+ }
254
+ debugReplay.debug('rerun {projectionName}: {count} events', { projectionName: projection.name, count });
255
+ return { events: count };
256
+ };
257
+ return { decodeStoredEvent, highestVersion, assertLogSaysGone, replay, verify, repair, forget, rerun };
258
+ }
259
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../src/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /** A hook. `next` runs the rest of the chain and the work itself. It gives no result and takes no input. */
2
+ export type Around<Ctx> = (ctx: Ctx, next: () => Promise<void>) => Promise<void>;
3
+ /** What the app sees: register only. */
4
+ export type HookPoint<Ctx> = {
5
+ /** Wrap every run. Throws `BAD_DEFINITION` once the journal has run a command, a drain or a worker. */
6
+ around(hook: Around<Ctx>): void;
7
+ };
8
+ export declare function createHookPoint<Ctx extends object>(what: 'command' | 'effect'): {
9
+ point: HookPoint<Ctx>;
10
+ freeze: () => void;
11
+ run: <T>(ctx: Ctx, work: () => Promise<T>) => Promise<T>;
12
+ };
13
+ export type HookPointInternal<Ctx extends object> = ReturnType<typeof createHookPoint<Ctx>>;
14
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAWA,4GAA4G;AAC5G,MAAM,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEjF,wCAAwC;AACxC,MAAM,MAAM,SAAS,CAAC,GAAG,IAAI;IAC3B,uGAAuG;IACvG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;CACjC,CAAC;AAEF,wBAAgB,eAAe,CAAC,GAAG,SAAS,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ;;kBAmBzD,IAAI;UAKJ,CAAC,OAAO,GAAG,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC;EAsCpE;AAED,MAAM,MAAM,iBAAiB,CAAC,GAAG,SAAS,MAAM,IAAI,UAAU,CAAC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC"}
package/dist/hooks.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Around-hooks: the one way to extend a command run or an effect run from the
3
+ * outside. A hook receives the context and `next`, and runs inside the same
4
+ * transaction (commands) or lease (effects). The rules, all enforced here:
5
+ * `next` exactly once, or throw before it to stop; a rejection of `next` is the
6
+ * hook's rejection too; the context is frozen; hooks run in registration order,
7
+ * the first one outermost; registration is frozen once the journal has done work.
8
+ * Leaf file: may import `errors` only.
9
+ */
10
+ import { JournalError } from './errors.js';
11
+ export function createHookPoint(what) {
12
+ const hooks = [];
13
+ let frozen = false;
14
+ const point = {
15
+ around(hook) {
16
+ if (frozen) {
17
+ throw new JournalError('BAD_DEFINITION', 'hook', what, `journal: ${what} hooks are frozen once the journal has run a command, a drain or a worker; register hooks at boot, before any work`);
18
+ }
19
+ hooks.push(hook);
20
+ },
21
+ };
22
+ /** From now on, `around` throws. Called by the first `run` or `drain`. */
23
+ const freeze = () => {
24
+ frozen = true;
25
+ };
26
+ /** Run `work` inside every registered hook. The result is the work's own; no hook can change it. */
27
+ const run = async (ctx, work) => {
28
+ if (hooks.length === 0)
29
+ return work();
30
+ const frozenCtx = Object.freeze(ctx);
31
+ let result;
32
+ const layer = async (index) => {
33
+ const hook = hooks[index];
34
+ if (hook === undefined) {
35
+ result = { value: await work() };
36
+ return;
37
+ }
38
+ let calls = 0;
39
+ let failure;
40
+ const next = async () => {
41
+ calls += 1;
42
+ if (calls > 1)
43
+ throw new Error(`journal: a ${what} hook called next twice; next runs the ${what} and may run once`);
44
+ try {
45
+ await layer(index + 1);
46
+ }
47
+ catch (error) {
48
+ failure = { error };
49
+ throw error;
50
+ }
51
+ };
52
+ await hook(frozenCtx, next);
53
+ // A hook that swallowed the failure would turn a rolled-back command into a success for the caller.
54
+ if (failure !== undefined)
55
+ throw failure.error;
56
+ if (calls === 0) {
57
+ throw new Error(`journal: a ${what} hook returned without calling next; call next to run the ${what}, or throw to stop it`);
58
+ }
59
+ };
60
+ await layer(0);
61
+ if (result === undefined)
62
+ throw new Error(`journal: the ${what} did not run`);
63
+ return result.value;
64
+ };
65
+ return { point, freeze, run };
66
+ }
67
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C,MAAM,UAAU,eAAe,CAAqB,IAA0B;IAC5E,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,KAAK,GAAmB;QAC5B,MAAM,CAAC,IAAI;YACT,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,YAAY,CACpB,gBAAgB,EAChB,MAAM,EACN,IAAI,EACJ,YAAY,IAAI,oHAAoH,CACrI,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;KACF,CAAC;IAEF,0EAA0E;IAC1E,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC,CAAC;IAEF,oGAAoG;IACpG,MAAM,GAAG,GAAG,KAAK,EAAK,GAAQ,EAAE,IAAsB,EAAc,EAAE;QACpE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,EAAE,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,MAAyC,CAAC;QAC9C,MAAM,KAAK,GAAG,KAAK,EAAE,KAAa,EAAiB,EAAE;YACnD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;gBACjC,OAAO;YACT,CAAC;YACD,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,OAAgD,CAAC;YACrD,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;gBACrC,KAAK,IAAI,CAAC,CAAC;gBACX,IAAI,KAAK,GAAG,CAAC;oBACX,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,0CAA0C,IAAI,mBAAmB,CAAC,CAAC;gBACvG,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACzB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;oBACpB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC,CAAC;YACF,MAAM,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC5B,oGAAoG;YACpG,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM,OAAO,CAAC,KAAK,CAAC;YAC/C,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,6DAA6D,IAAI,uBAAuB,CAC3G,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;QACF,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;QACf,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,cAAc,CAAC,CAAC;QAC9E,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAChC,CAAC"}
package/dist/id.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export declare const eventId: () => `evt_${string}`;
2
+ export declare const jobId: () => `job_${string}`;
3
+ export declare const commandId: () => `cmd_${string}`;
4
+ export declare const correlationId: () => `cor_${string}`;
5
+ export declare const leaseToken: () => string;
6
+ declare const NAME_KINDS: {
7
+ readonly 'entity kind': 64;
8
+ readonly 'event type': 128;
9
+ readonly 'effect name': 128;
10
+ };
11
+ /**
12
+ * Throws unless `name` fits the `varchar` column the journal stores it in: non-empty,
13
+ * well-formed UTF-16 (a lone surrogate would be stored as U+FFFD and alias another name),
14
+ * and at most the column length in code points. Hermes-safe: no `isWellFormed`, no lookbehind.
15
+ */
16
+ export declare function assertStoredName(what: keyof typeof NAME_KINDS, name: string): void;
17
+ export {};
18
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,OAAO,uBAAyB,CAAC;AAC9C,eAAO,MAAM,KAAK,uBAAyB,CAAC;AAC5C,eAAO,MAAM,SAAS,uBAAyB,CAAC;AAChD,eAAO,MAAM,aAAa,uBAAyB,CAAC;AACpD,eAAO,MAAM,UAAU,cAAmB,CAAC;AAE3C,QAAA,MAAM,UAAU;aACd,aAAa,EAAE,EAAE;aACjB,YAAY,EAAE,GAAG;aACjB,aAAa,EAAE,GAAG;CACV,CAAC;AAEX;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,OAAO,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAyBlF"}
package/dist/id.js ADDED
@@ -0,0 +1,41 @@
1
+ import { createId } from '@paralleldrive/cuid2';
2
+ import { JournalError } from './errors.js';
3
+ /**
4
+ * Same shape as `createPrefixedId` in `@arki/db/id`. That module is not
5
+ * imported because its value export pulls `drizzle-orm/pg-core` and
6
+ * `@arki/contracts` into browser bundles.
7
+ */
8
+ const prefixed = (prefix) => `${prefix}${createId()}`;
9
+ export const eventId = () => prefixed('evt_');
10
+ export const jobId = () => prefixed('job_');
11
+ export const commandId = () => prefixed('cmd_');
12
+ export const correlationId = () => prefixed('cor_');
13
+ export const leaseToken = () => createId();
14
+ const NAME_KINDS = {
15
+ 'entity kind': 64,
16
+ 'event type': 128,
17
+ 'effect name': 128,
18
+ };
19
+ /**
20
+ * Throws unless `name` fits the `varchar` column the journal stores it in: non-empty,
21
+ * well-formed UTF-16 (a lone surrogate would be stored as U+FFFD and alias another name),
22
+ * and at most the column length in code points. Hermes-safe: no `isWellFormed`, no lookbehind.
23
+ */
24
+ export function assertStoredName(what, name) {
25
+ const limit = NAME_KINDS[what];
26
+ const shown = JSON.stringify(name);
27
+ if (name === '')
28
+ throw new JournalError('BAD_DEFINITION', what, shown, `journal: ${what} must not be empty`);
29
+ let length = 0;
30
+ for (const ch of name) {
31
+ const point = ch.codePointAt(0);
32
+ if (point !== undefined && point >= 55_296 && point <= 57_343) {
33
+ throw new JournalError('BAD_DEFINITION', what, shown, `journal: ${what} ${shown} has an unpaired surrogate; the database would store it as U+FFFD`);
34
+ }
35
+ length++;
36
+ }
37
+ if (length > limit) {
38
+ throw new JournalError('BAD_DEFINITION', what, shown, `journal: ${what} ${shown} is ${length} characters; the limit is ${limit}`);
39
+ }
40
+ }
41
+ //# sourceMappingURL=id.js.map
package/dist/id.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;GAIG;AACH,MAAM,QAAQ,GAAG,CAAmB,MAAS,EAAmB,EAAE,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,EAAE,CAAC;AAE5F,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9C,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC5C,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AAE3C,MAAM,UAAU,GAAG;IACjB,aAAa,EAAE,EAAE;IACjB,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;CACV,CAAC;AAEX;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA6B,EAAE,IAAY;IAC1E,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,IAAI,KAAK,EAAE;QAAE,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,IAAI,oBAAoB,CAAC,CAAC;IAC7G,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;YAC9D,MAAM,IAAI,YAAY,CACpB,gBAAgB,EAChB,IAAI,EACJ,KAAK,EACL,YAAY,IAAI,IAAI,KAAK,mEAAmE,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,EAAE,CAAC;IACX,CAAC;IACD,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,YAAY,CACpB,gBAAgB,EAChB,IAAI,EACJ,KAAK,EACL,YAAY,IAAI,IAAI,KAAK,OAAO,MAAM,6BAA6B,KAAK,EAAE,CAC3E,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ export { initJournal } from './journal.js';
2
+ export { need } from './handlers.js';
3
+ export type { Command, CommandContext, CommandRunner, Journal, JournalDefinitions, ReplayResult, RootCommandRunner, RunOptions, CallOptions, VerifyResult, ForgetResult, NextEvents, WriteInput, WriteOptions, WriteResult, } from './api.js';
4
+ export { CommandError, JournalError, isCommandError, isJournalError } from './errors.js';
5
+ export type { CommandErrorCode, JournalErrorCode } from './errors.js';
6
+ export type { GuaranteedCreateKeys, EntityBuilder, OnReducerRow, OnOnlyEntityBuilder } from './entity.js';
7
+ export type { AnyEntity, AnyEventDef, CreateReducer, DbHandle, Effect, EffectContext, EffectHandlers, EntityDef, EntityId, EntityIdOf, EntityInfo, EntityTable, EventDef, EventOptions, Upcaster, UpcasterSteps, ProjectionOptions, Tap, TapContext, TapHandlers, Unlisten, WakeListener, CommandHookContext, EffectHookContext, EventsOf, IdTable, KeyColumn, Need, Needed, Needs, ReducerValues, OnReducer, Patch, Pending, PendingOf, Projection, ProjectionHandlers, Recorded, RecordedOf, Reducers, ReducerRow, RootDb, Row, Services, ServicesFor, TransactionSource, JournalWorker, StrandedJobs, } from './types.js';
8
+ export type { JournalTables } from './pg.js';
9
+ export type { Around, HookPoint } from './hooks.js';
10
+ export { listenOnPool } from './listen.js';
11
+ export type { ListenClient, ListenPool } from './listen.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,YAAY,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACtE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1G,YAAY,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,QAAQ,EACR,MAAM,EACN,aAAa,EACb,cAAc,EACd,SAAS,EACT,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,GAAG,EACH,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,SAAS,EACT,IAAI,EACJ,MAAM,EACN,KAAK,EACL,aAAa,EACb,SAAS,EACT,KAAK,EACL,OAAO,EACP,SAAS,EACT,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,MAAM,EACN,GAAG,EACH,QAAQ,EACR,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { initJournal } from './journal.js';
2
+ export { need } from './handlers.js';
3
+ export { CommandError, JournalError, isCommandError, isJournalError } from './errors.js';
4
+ export { listenOnPool } from './listen.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAkBrC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAuDzF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ import type { JournalDefinitions } from './api.js';
3
+ import type { DbHandle, RootDb, TransactionSource } from './types.js';
4
+ /**
5
+ * `initJournal({ meta })` types `write`'s `tx`, `events`' `{ tx }` and
6
+ * projection handlers with the structural `DbHandle`. `initJournal.tx<AppTx>()
7
+ * .create({ meta })` uses the app's own Drizzle transaction type instead, so
8
+ * repositories typed against it fit. `initJournal.db<AppDb>()` names the
9
+ * app's root database type: effects get it as `ctx.db`, and `drain` and
10
+ * `worker` then need it. Both are type-only steps and chain in either order.
11
+ */
12
+ export declare const initJournal: {
13
+ (): JournalDefinitions<z.ZodObject<{}, z.core.$strip>, DbHandle, RootDb>;
14
+ <Meta extends z.ZodObject>(options: {
15
+ readonly meta: Meta;
16
+ }): JournalDefinitions<Meta, DbHandle, RootDb>;
17
+ } & {
18
+ tx: <Tx extends TransactionSource<Tx>>() => {
19
+ create: {
20
+ (): JournalDefinitions<z.ZodObject<{}, z.core.$strip>, Tx, RootDb>;
21
+ <Meta extends z.ZodObject>(options: {
22
+ readonly meta: Meta;
23
+ }): JournalDefinitions<Meta, Tx, RootDb>;
24
+ };
25
+ db: <AppDb extends RootDb>() => {
26
+ create: {
27
+ (): JournalDefinitions<z.ZodObject<{}, z.core.$strip>, Tx, AppDb>;
28
+ <Meta extends z.ZodObject>(options: {
29
+ readonly meta: Meta;
30
+ }): JournalDefinitions<Meta, Tx, AppDb>;
31
+ };
32
+ };
33
+ };
34
+ db: <AppDb extends RootDb>() => {
35
+ create: {
36
+ (): JournalDefinitions<z.ZodObject<{}, z.core.$strip>, DbHandle, AppDb>;
37
+ <Meta extends z.ZodObject>(options: {
38
+ readonly meta: Meta;
39
+ }): JournalDefinitions<Meta, DbHandle, AppDb>;
40
+ };
41
+ tx: <Tx extends TransactionSource<Tx>>() => {
42
+ create: {
43
+ (): JournalDefinitions<z.ZodObject<{}, z.core.$strip>, Tx, AppDb>;
44
+ <Meta extends z.ZodObject>(options: {
45
+ readonly meta: Meta;
46
+ }): JournalDefinitions<Meta, Tx, AppDb>;
47
+ };
48
+ };
49
+ };
50
+ };
51
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAW,kBAAkB,EAAqB,MAAM,UAAU,CAAC;AAG/E,OAAO,KAAK,EAGV,QAAQ,EAOR,MAAM,EAGN,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAkCpB;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW;;KAnBR,IAAI,SAAS,CAAC,CAAC,SAAS;;;;SAoBjC,EAAE,SAAS,iBAAiB,CAAC,EAAE,CAAC;;;aApBvB,IAAI,SAAS,CAAC,CAAC,SAAS;;;;aAsB/B,KAAK,SAAS,MAAM;;;iBAtBb,IAAI,SAAS,CAAC,CAAC,SAAS;;;;;;SAwBjC,KAAK,SAAS,MAAM;;;aAxBX,IAAI,SAAS,CAAC,CAAC,SAAS;;;;aA0B/B,EAAE,SAAS,iBAAiB,CAAC,EAAE,CAAC;;;iBA1BzB,IAAI,SAAS,CAAC,CAAC,SAAS;;;;;;CA4BtC,CAAC"}