@loomwork/ui-lineage 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.
Files changed (88) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +471 -2
  4. package/dist/conformance.d.ts +4 -0
  5. package/dist/conformance.d.ts.map +1 -0
  6. package/dist/conformance.js +143 -0
  7. package/dist/conformance.js.map +1 -0
  8. package/dist/derive.d.ts +15 -0
  9. package/dist/derive.d.ts.map +1 -0
  10. package/dist/derive.js +35 -0
  11. package/dist/derive.js.map +1 -0
  12. package/dist/esm/conformance.js +140 -0
  13. package/dist/esm/conformance.js.map +1 -0
  14. package/dist/esm/derive.js +29 -0
  15. package/dist/esm/derive.js.map +1 -0
  16. package/dist/esm/events.js +101 -0
  17. package/dist/esm/events.js.map +1 -0
  18. package/dist/esm/index.js +12 -0
  19. package/dist/esm/index.js.map +1 -0
  20. package/dist/esm/lineage.js +1376 -0
  21. package/dist/esm/lineage.js.map +1 -0
  22. package/dist/esm/retention.js +73 -0
  23. package/dist/esm/retention.js.map +1 -0
  24. package/dist/esm/rootsFor.js +49 -0
  25. package/dist/esm/rootsFor.js.map +1 -0
  26. package/dist/esm/seen.js +733 -0
  27. package/dist/esm/seen.js.map +1 -0
  28. package/dist/esm/seenCrypto.js +197 -0
  29. package/dist/esm/seenCrypto.js.map +1 -0
  30. package/dist/esm/seenGc.js +122 -0
  31. package/dist/esm/seenGc.js.map +1 -0
  32. package/dist/esm/state.js +185 -0
  33. package/dist/esm/state.js.map +1 -0
  34. package/dist/esm/store.js +172 -0
  35. package/dist/esm/store.js.map +1 -0
  36. package/dist/events.d.ts +781 -0
  37. package/dist/events.d.ts.map +1 -0
  38. package/dist/events.js +106 -0
  39. package/dist/events.js.map +1 -0
  40. package/dist/index.d.ts +23 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +60 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/lineage.d.ts +394 -0
  45. package/dist/lineage.d.ts.map +1 -0
  46. package/dist/lineage.js +1383 -0
  47. package/dist/lineage.js.map +1 -0
  48. package/dist/retention.d.ts +45 -0
  49. package/dist/retention.d.ts.map +1 -0
  50. package/dist/retention.js +78 -0
  51. package/dist/retention.js.map +1 -0
  52. package/dist/rootsFor.d.ts +33 -0
  53. package/dist/rootsFor.d.ts.map +1 -0
  54. package/dist/rootsFor.js +52 -0
  55. package/dist/rootsFor.js.map +1 -0
  56. package/dist/seen.d.ts +375 -0
  57. package/dist/seen.d.ts.map +1 -0
  58. package/dist/seen.js +739 -0
  59. package/dist/seen.js.map +1 -0
  60. package/dist/seenCrypto.d.ts +72 -0
  61. package/dist/seenCrypto.d.ts.map +1 -0
  62. package/dist/seenCrypto.js +210 -0
  63. package/dist/seenCrypto.js.map +1 -0
  64. package/dist/seenGc.d.ts +73 -0
  65. package/dist/seenGc.d.ts.map +1 -0
  66. package/dist/seenGc.js +126 -0
  67. package/dist/seenGc.js.map +1 -0
  68. package/dist/state.d.ts +66 -0
  69. package/dist/state.d.ts.map +1 -0
  70. package/dist/state.js +190 -0
  71. package/dist/state.js.map +1 -0
  72. package/dist/store.d.ts +93 -0
  73. package/dist/store.d.ts.map +1 -0
  74. package/dist/store.js +177 -0
  75. package/dist/store.js.map +1 -0
  76. package/package.json +60 -3
  77. package/src/conformance.ts +148 -0
  78. package/src/derive.ts +57 -0
  79. package/src/events.ts +125 -0
  80. package/src/index.ts +79 -0
  81. package/src/lineage.ts +1655 -0
  82. package/src/retention.ts +118 -0
  83. package/src/rootsFor.ts +75 -0
  84. package/src/seen.ts +965 -0
  85. package/src/seenCrypto.ts +271 -0
  86. package/src/seenGc.ts +233 -0
  87. package/src/state.ts +268 -0
  88. package/src/store.ts +274 -0
@@ -0,0 +1,172 @@
1
+ import { DuplicateEnvelopeIdError, DuplicateSequenceError, headOf, } from "@loomwork/event-runtime";
2
+ /**
3
+ * A lost slot, by class OR name (a store decorator or a second copy of the package throws an error
4
+ * that is not `instanceof` ours); mirrors the kernel's `isWriteConflict`.
5
+ */
6
+ function isWriteConflict(err) {
7
+ if (err instanceof DuplicateSequenceError || err instanceof DuplicateEnvelopeIdError)
8
+ return true;
9
+ const name = err?.name;
10
+ return name === "DuplicateSequenceError" || name === "DuplicateEnvelopeIdError";
11
+ }
12
+ const clone = (v) => structuredClone(v);
13
+ /** Reference in-memory store. Copies on the way in and out, so no caller can mutate the log. */
14
+ export class InMemoryLineageStore {
15
+ lines = new Map();
16
+ async append(experienceId, expectedSequence, record) {
17
+ const line = this.lines.get(experienceId) ?? [];
18
+ if (line.length !== expectedSequence)
19
+ return { ok: false, tip: line.length };
20
+ const sequence = line.length + 1;
21
+ line.push(clone({ ...record, sequence }));
22
+ this.lines.set(experienceId, line);
23
+ return { ok: true, sequence };
24
+ }
25
+ async read(experienceId) {
26
+ return clone(this.lines.get(experienceId) ?? []);
27
+ }
28
+ async readTail(experienceId, limit) {
29
+ const line = this.lines.get(experienceId) ?? [];
30
+ return clone(limit >= line.length ? line : line.slice(line.length - Math.max(0, limit)));
31
+ }
32
+ async readAfter(experienceId, afterSequence, limit = Number.POSITIVE_INFINITY) {
33
+ // dense 1..n: the records after `a` start at index `a`
34
+ const line = this.lines.get(experienceId) ?? [];
35
+ const from = Math.max(0, afterSequence);
36
+ return clone(line.slice(from, Number.isFinite(limit) ? from + Math.max(0, limit) : undefined));
37
+ }
38
+ async *listStreams() {
39
+ for (const id of [...this.lines.keys()])
40
+ yield id;
41
+ }
42
+ }
43
+ /** The reserved-stream namespace a lineage's events live under in an `EventStore`. */
44
+ export const LINEAGE_STREAM_PREFIX = "__loom_ui_lineage__:";
45
+ /** The `workflowId` a lineage event is written under unless `eventStoreLineageStore` is given another. */
46
+ export const LINEAGE_WORKFLOW_ID = "loom-ui.lineage";
47
+ const WORKFLOW_ID = LINEAGE_WORKFLOW_ID;
48
+ /** Every stream prefix this package may write under; the kernel's own reserved prefixes are not ours. */
49
+ export const LOOM_UI_STREAM_NAMESPACE = "__loom_ui_";
50
+ const WORKFLOW_ID_SHAPE = /^[A-Za-z0-9._:-]{1,128}$/;
51
+ /**
52
+ * A `LineageStore` over loom's `EventStore`. One stream per experience
53
+ * (`__loom_ui_lineage__:<experienceId>`, a RESERVED stream so enumerators of real executions skip
54
+ * it; see the README for what a reserved stream costs); the lineage sequence IS the envelope sequence, so the CAS is the log's own
55
+ * `(executionId, sequence)` uniqueness. The adapter checks the tip first (a store enforces a
56
+ * taken slot, not a skipped one) and treats a `DuplicateSequenceError` from a racing writer as a
57
+ * lost CAS. Fencing, tenancy and sharding decorators wrap `store` as usual.
58
+ *
59
+ * `streamPrefix` must start with `__loom_ui_` (and say more): it is the namespace this package owns
60
+ * inside loom's reserved `__loom_` space, so a configuration can never write into the kernel's own
61
+ * control streams (`__loom_lifecycle__`, `__loom_erasure__`) or an execution's id space. `workflowId`
62
+ * is a short identifier. A bad value THROWS at construction (a misconfiguration, found at startup).
63
+ */
64
+ export function eventStoreLineageStore(store, opts = {}) {
65
+ const prefix = opts.streamPrefix ?? LINEAGE_STREAM_PREFIX;
66
+ const workflowId = opts.workflowId ?? WORKFLOW_ID;
67
+ if (typeof prefix !== "string" ||
68
+ !prefix.startsWith(LOOM_UI_STREAM_NAMESPACE) ||
69
+ prefix.length <= LOOM_UI_STREAM_NAMESPACE.length ||
70
+ prefix.length > 128)
71
+ throw new Error(`streamPrefix must start with "${LOOM_UI_STREAM_NAMESPACE}" and name its stream (got ${JSON.stringify(String(prefix).slice(0, 40))})`);
72
+ if (typeof workflowId !== "string" || !WORKFLOW_ID_SHAPE.test(workflowId))
73
+ throw new Error("workflowId must be 1-128 characters of [A-Za-z0-9._:-]");
74
+ const streamOf = (experienceId) => `${prefix}${experienceId}`;
75
+ return {
76
+ streamPrefix: prefix,
77
+ workflowId,
78
+ async append(experienceId, expectedSequence, record) {
79
+ const executionId = streamOf(experienceId);
80
+ const tip = (await headOf(store, executionId)) ?? 0;
81
+ if (tip !== expectedSequence)
82
+ return { ok: false, tip };
83
+ const sequence = expectedSequence + 1;
84
+ try {
85
+ await store.append({
86
+ id: `${executionId}#${sequence}`,
87
+ workflowId,
88
+ executionId,
89
+ eventType: record.type,
90
+ sequence,
91
+ timestamp: Date.parse(record.at) || 0,
92
+ payload: clone(record.payload),
93
+ metadata: { at: record.at },
94
+ });
95
+ }
96
+ catch (err) {
97
+ if (isWriteConflict(err))
98
+ return { ok: false, tip: (await headOf(store, executionId)) ?? sequence };
99
+ throw err;
100
+ }
101
+ return { ok: true, sequence };
102
+ },
103
+ async read(experienceId) {
104
+ return toRecords(await store.read(streamOf(experienceId)));
105
+ },
106
+ async readTail(experienceId, limit) {
107
+ const id = streamOf(experienceId);
108
+ const tip = (await headOf(store, id)) ?? 0;
109
+ if (tip === 0 || limit <= 0)
110
+ return [];
111
+ return toRecords(await readWindow(store, id, Math.max(1, tip - limit + 1), tip));
112
+ },
113
+ async readAfter(experienceId, afterSequence, limit = Number.POSITIVE_INFINITY) {
114
+ const id = streamOf(experienceId);
115
+ const tip = (await headOf(store, id)) ?? 0;
116
+ const from = Math.max(1, afterSequence + 1);
117
+ const to = Number.isFinite(limit) ? Math.min(tip, from + Math.max(0, limit) - 1) : tip;
118
+ if (to < from)
119
+ return [];
120
+ return toRecords(await readWindow(store, id, from, to));
121
+ },
122
+ ...(store.listExecutionsPage !== undefined || store.listExecutions !== undefined
123
+ ? {
124
+ async *listStreams() {
125
+ // Reserved streams ARE surfaced by the SPI's enumeration (`__loom_*`), so ours are found
126
+ // by prefix. Pages are keyset-ordered by code point, so with pages the scan starts just
127
+ // before our prefix and stops once past it; the unpaged fallback filters the full list.
128
+ if (store.listExecutionsPage === undefined) {
129
+ for (const id of (await store.listExecutions?.()) ?? [])
130
+ if (id.startsWith(prefix))
131
+ yield id.slice(prefix.length);
132
+ return;
133
+ }
134
+ let cursor = prefix.slice(0, -1);
135
+ for (;;) {
136
+ const page = await store.listExecutionsPage({
137
+ ...(cursor !== undefined && { cursor }),
138
+ limit: 500,
139
+ });
140
+ for (const id of page.executionIds) {
141
+ if (id.startsWith(prefix))
142
+ yield id.slice(prefix.length);
143
+ else if (id > prefix)
144
+ return;
145
+ }
146
+ if (page.nextCursor === undefined || page.nextCursor === cursor)
147
+ return;
148
+ cursor = page.nextCursor;
149
+ }
150
+ },
151
+ }
152
+ : {}),
153
+ };
154
+ }
155
+ function toRecords(events) {
156
+ return events
157
+ .slice()
158
+ .sort((a, b) => a.sequence - b.sequence)
159
+ .map((e) => ({
160
+ sequence: e.sequence,
161
+ type: e.eventType,
162
+ payload: clone(e.payload),
163
+ at: typeof e.metadata?.at === "string" ? e.metadata.at : new Date(e.timestamp).toISOString(),
164
+ }));
165
+ }
166
+ /** Sequences `from..to` (inclusive) of a stream: the store's `readRange`, else `readFrom`/`read` filtered. */
167
+ async function readWindow(store, id, from, to) {
168
+ if (store.readRange !== undefined)
169
+ return store.readRange(id, from, to);
170
+ return (await store.read(id)).filter((e) => e.sequence >= from && e.sequence <= to);
171
+ }
172
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/store.ts"],"names":[],"mappings":"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"}