@graphrefly/ts 0.0.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.
- package/LICENSE +21 -0
- package/dist/adapters/index.cjs +9015 -0
- package/dist/adapters/index.cjs.map +1 -0
- package/dist/adapters/index.d.cts +678 -0
- package/dist/adapters/index.d.ts +678 -0
- package/dist/adapters/index.js +2894 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/observe-storage.cjs +260 -0
- package/dist/adapters/observe-storage.cjs.map +1 -0
- package/dist/adapters/observe-storage.d.cts +77 -0
- package/dist/adapters/observe-storage.d.ts +77 -0
- package/dist/adapters/observe-storage.js +161 -0
- package/dist/adapters/observe-storage.js.map +1 -0
- package/dist/append-log-DisvEReb.d.cts +189 -0
- package/dist/append-log-DzKMmjxx.d.ts +189 -0
- package/dist/chunk-2ILL7HQI.js +1189 -0
- package/dist/chunk-2ILL7HQI.js.map +1 -0
- package/dist/chunk-4VLAQHZI.js +330 -0
- package/dist/chunk-4VLAQHZI.js.map +1 -0
- package/dist/chunk-6PHB5CJS.js +229 -0
- package/dist/chunk-6PHB5CJS.js.map +1 -0
- package/dist/chunk-COHO25CZ.js +2449 -0
- package/dist/chunk-COHO25CZ.js.map +1 -0
- package/dist/chunk-D6BG7U6A.js +161 -0
- package/dist/chunk-D6BG7U6A.js.map +1 -0
- package/dist/chunk-DJC4CHLQ.js +818 -0
- package/dist/chunk-DJC4CHLQ.js.map +1 -0
- package/dist/chunk-DK554R7P.js +67 -0
- package/dist/chunk-DK554R7P.js.map +1 -0
- package/dist/chunk-DKP56CSW.js +322 -0
- package/dist/chunk-DKP56CSW.js.map +1 -0
- package/dist/chunk-G4M3NHRJ.js +688 -0
- package/dist/chunk-G4M3NHRJ.js.map +1 -0
- package/dist/chunk-GAJW5I5P.js +1 -0
- package/dist/chunk-GAJW5I5P.js.map +1 -0
- package/dist/chunk-GDL26N2T.js +282 -0
- package/dist/chunk-GDL26N2T.js.map +1 -0
- package/dist/chunk-GTPCOEOZ.js +741 -0
- package/dist/chunk-GTPCOEOZ.js.map +1 -0
- package/dist/chunk-H2HTHFVN.js +1 -0
- package/dist/chunk-H2HTHFVN.js.map +1 -0
- package/dist/chunk-HDRL4VQQ.js +218 -0
- package/dist/chunk-HDRL4VQQ.js.map +1 -0
- package/dist/chunk-I3IHOHCJ.js +2267 -0
- package/dist/chunk-I3IHOHCJ.js.map +1 -0
- package/dist/chunk-JIMUDQN3.js +965 -0
- package/dist/chunk-JIMUDQN3.js.map +1 -0
- package/dist/chunk-JR4IKCR2.js +462 -0
- package/dist/chunk-JR4IKCR2.js.map +1 -0
- package/dist/chunk-K3FXTC3I.js +165 -0
- package/dist/chunk-K3FXTC3I.js.map +1 -0
- package/dist/chunk-OOEN33FB.js +65 -0
- package/dist/chunk-OOEN33FB.js.map +1 -0
- package/dist/chunk-PKVBHGBM.js +554 -0
- package/dist/chunk-PKVBHGBM.js.map +1 -0
- package/dist/chunk-RIIOUTGM.js +1857 -0
- package/dist/chunk-RIIOUTGM.js.map +1 -0
- package/dist/chunk-SCRFRCGR.js +33 -0
- package/dist/chunk-SCRFRCGR.js.map +1 -0
- package/dist/chunk-SWTLEQL6.js +53 -0
- package/dist/chunk-SWTLEQL6.js.map +1 -0
- package/dist/chunk-SZAETNNA.js +1 -0
- package/dist/chunk-SZAETNNA.js.map +1 -0
- package/dist/chunk-TEW47IVR.js +49 -0
- package/dist/chunk-TEW47IVR.js.map +1 -0
- package/dist/chunk-Y3ZLRGHC.js +1482 -0
- package/dist/chunk-Y3ZLRGHC.js.map +1 -0
- package/dist/chunk-Z2ANQ6JW.js +149 -0
- package/dist/chunk-Z2ANQ6JW.js.map +1 -0
- package/dist/codec-BB7p8fJc.d.cts +38 -0
- package/dist/codec-BB7p8fJc.d.ts +38 -0
- package/dist/composition/index.cjs +2505 -0
- package/dist/composition/index.cjs.map +1 -0
- package/dist/composition/index.d.cts +95 -0
- package/dist/composition/index.d.ts +95 -0
- package/dist/composition/index.js +19 -0
- package/dist/composition/index.js.map +1 -0
- package/dist/core/index.cjs +2475 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +25 -0
- package/dist/core/index.d.ts +25 -0
- package/dist/core/index.js +74 -0
- package/dist/core/index.js.map +1 -0
- package/dist/cqrs/index.cjs +595 -0
- package/dist/cqrs/index.cjs.map +1 -0
- package/dist/cqrs/index.d.cts +200 -0
- package/dist/cqrs/index.d.ts +200 -0
- package/dist/cqrs/index.js +557 -0
- package/dist/cqrs/index.js.map +1 -0
- package/dist/data-structures/index.cjs +4277 -0
- package/dist/data-structures/index.cjs.map +1 -0
- package/dist/data-structures/index.d.cts +22 -0
- package/dist/data-structures/index.d.ts +22 -0
- package/dist/data-structures/index.js +31 -0
- package/dist/data-structures/index.js.map +1 -0
- package/dist/describe-BZb7AS2y.d.ts +57 -0
- package/dist/describe-Ciu8SUnN.d.cts +57 -0
- package/dist/graph/index.cjs +7832 -0
- package/dist/graph/index.cjs.map +1 -0
- package/dist/graph/index.d.cts +251 -0
- package/dist/graph/index.d.ts +251 -0
- package/dist/graph/index.js +131 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph-DfdF9zy4.d.ts +666 -0
- package/dist/graph-s23RbbFO.d.cts +666 -0
- package/dist/index-CAEmLCYF.d.cts +166 -0
- package/dist/index-SnzZu3x7.d.ts +166 -0
- package/dist/index.cjs +15409 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +582 -0
- package/dist/index.js.map +1 -0
- package/dist/messages-BZqrGGm1.d.cts +55 -0
- package/dist/messages-BZqrGGm1.d.ts +55 -0
- package/dist/messaging/index.cjs +818 -0
- package/dist/messaging/index.cjs.map +1 -0
- package/dist/messaging/index.d.cts +235 -0
- package/dist/messaging/index.d.ts +235 -0
- package/dist/messaging/index.js +767 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/observe-event-log-0SVsx7JG.d.cts +88 -0
- package/dist/observe-event-log-Dnm76owp.d.ts +88 -0
- package/dist/operators/index.cjs +3774 -0
- package/dist/operators/index.cjs.map +1 -0
- package/dist/operators/index.d.cts +308 -0
- package/dist/operators/index.d.ts +308 -0
- package/dist/operators/index.js +112 -0
- package/dist/operators/index.js.map +1 -0
- package/dist/orchestration/index.cjs +3541 -0
- package/dist/orchestration/index.cjs.map +1 -0
- package/dist/orchestration/index.d.cts +302 -0
- package/dist/orchestration/index.d.ts +302 -0
- package/dist/orchestration/index.js +1004 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/patterns/index.cjs +1045 -0
- package/dist/patterns/index.cjs.map +1 -0
- package/dist/patterns/index.d.cts +39 -0
- package/dist/patterns/index.d.ts +39 -0
- package/dist/patterns/index.js +33 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/reactive-collection-BxBqtIOE.d.cts +344 -0
- package/dist/reactive-collection-Cb1II1Fi.d.ts +344 -0
- package/dist/reactive-collection-storage-BNiEc-Gd.d.ts +217 -0
- package/dist/reactive-collection-storage-D-KmjE0J.d.cts +217 -0
- package/dist/reactive-map-BcB4KsQR.d.ts +256 -0
- package/dist/reactive-map-D-g3dv8I.d.cts +256 -0
- package/dist/read-through-B1CYPfq_.d.cts +82 -0
- package/dist/read-through-DwyJhGs1.d.ts +82 -0
- package/dist/render/index.cjs +250 -0
- package/dist/render/index.cjs.map +1 -0
- package/dist/render/index.d.cts +58 -0
- package/dist/render/index.d.ts +58 -0
- package/dist/render/index.js +20 -0
- package/dist/render/index.js.map +1 -0
- package/dist/resilience-Dig3Q7n0.d.cts +45 -0
- package/dist/resilience-Dig3Q7n0.d.ts +45 -0
- package/dist/semantic-memory-graph-BYoIlP35.d.cts +356 -0
- package/dist/semantic-memory-graph-CxyXLms3.d.ts +356 -0
- package/dist/solutions/index.cjs +3249 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +520 -0
- package/dist/solutions/index.d.ts +520 -0
- package/dist/solutions/index.js +31 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/sources/browser.cjs +3095 -0
- package/dist/sources/browser.cjs.map +1 -0
- package/dist/sources/browser.d.cts +39 -0
- package/dist/sources/browser.d.ts +39 -0
- package/dist/sources/browser.js +137 -0
- package/dist/sources/browser.js.map +1 -0
- package/dist/sources/index.cjs +3021 -0
- package/dist/sources/index.cjs.map +1 -0
- package/dist/sources/index.d.cts +7 -0
- package/dist/sources/index.d.ts +7 -0
- package/dist/sources/index.js +63 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/node.cjs +675 -0
- package/dist/sources/node.cjs.map +1 -0
- package/dist/sources/node.d.cts +109 -0
- package/dist/sources/node.d.ts +109 -0
- package/dist/sources/node.js +639 -0
- package/dist/sources/node.js.map +1 -0
- package/dist/storage/browser.cjs +777 -0
- package/dist/storage/browser.cjs.map +1 -0
- package/dist/storage/browser.d.cts +40 -0
- package/dist/storage/browser.d.ts +40 -0
- package/dist/storage/browser.js +275 -0
- package/dist/storage/browser.js.map +1 -0
- package/dist/storage/index.cjs +1989 -0
- package/dist/storage/index.cjs.map +1 -0
- package/dist/storage/index.d.cts +92 -0
- package/dist/storage/index.d.ts +92 -0
- package/dist/storage/index.js +161 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/node.cjs +898 -0
- package/dist/storage/node.cjs.map +1 -0
- package/dist/storage/node.d.cts +66 -0
- package/dist/storage/node.d.ts +66 -0
- package/dist/storage/node.js +402 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/testing/index.cjs +95 -0
- package/dist/testing/index.cjs.map +1 -0
- package/dist/testing/index.d.cts +20 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types-bNMSWKqF.d.cts +732 -0
- package/dist/types-h12mNYbq.d.ts +732 -0
- package/package.json +250 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/adapters/observe-storage.ts
|
|
21
|
+
var observe_storage_exports = {};
|
|
22
|
+
__export(observe_storage_exports, {
|
|
23
|
+
attachObserveEventLog: () => attachObserveEventLog,
|
|
24
|
+
attachObserveSink: () => attachObserveSink
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(observe_storage_exports);
|
|
27
|
+
|
|
28
|
+
// src/storage/scalar.ts
|
|
29
|
+
var NON_NEGATIVE_DECIMAL_INTEGER_RE = /^(0|[1-9]\d*)$/;
|
|
30
|
+
function isNonNegativeDecimalIntegerString(value) {
|
|
31
|
+
return typeof value === "string" && NON_NEGATIVE_DECIMAL_INTEGER_RE.test(value);
|
|
32
|
+
}
|
|
33
|
+
function assertNonNegativeDecimalIntegerString(value, label = "decimal integer") {
|
|
34
|
+
if (!isNonNegativeDecimalIntegerString(value)) {
|
|
35
|
+
throw new TypeError(`${label} must be a canonical non-negative decimal integer string`);
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
function bigIntToNonNegativeDecimalString(value) {
|
|
40
|
+
if (value < 0n) {
|
|
41
|
+
throw new TypeError("decimal integer must be non-negative");
|
|
42
|
+
}
|
|
43
|
+
return value.toString();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/storage/change.ts
|
|
47
|
+
function nowNs() {
|
|
48
|
+
return bigIntToNonNegativeDecimalString(BigInt(Date.now()) * 1000000n);
|
|
49
|
+
}
|
|
50
|
+
function envelopeChange(change, opts) {
|
|
51
|
+
const envelope = {
|
|
52
|
+
lifecycle: opts.lifecycle ?? "data",
|
|
53
|
+
structure: opts.structure,
|
|
54
|
+
version: opts.version ?? 1,
|
|
55
|
+
t_ns: opts.t_ns ?? nowNs(),
|
|
56
|
+
...opts.seq === void 0 ? {} : { seq: opts.seq },
|
|
57
|
+
change
|
|
58
|
+
};
|
|
59
|
+
return assertChangeEnvelope(envelope);
|
|
60
|
+
}
|
|
61
|
+
function isRecord(value) {
|
|
62
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
63
|
+
}
|
|
64
|
+
function isLifecycle(value) {
|
|
65
|
+
return value === "spec" || value === "data" || value === "ownership";
|
|
66
|
+
}
|
|
67
|
+
function assertChangeEnvelope(value) {
|
|
68
|
+
if (!isRecord(value)) throw new TypeError("changeEnvelopeCodec: frame must be an object");
|
|
69
|
+
if (!isLifecycle(value.lifecycle)) {
|
|
70
|
+
throw new TypeError("changeEnvelopeCodec: lifecycle must be spec, data, or ownership");
|
|
71
|
+
}
|
|
72
|
+
if (typeof value.structure !== "string" || value.structure.length === 0) {
|
|
73
|
+
throw new TypeError("changeEnvelopeCodec: structure must be a non-empty string");
|
|
74
|
+
}
|
|
75
|
+
if ((typeof value.version !== "number" || !Number.isFinite(value.version)) && typeof value.version !== "string") {
|
|
76
|
+
throw new TypeError("changeEnvelopeCodec: version must be a finite number or string");
|
|
77
|
+
}
|
|
78
|
+
assertNonNegativeDecimalIntegerString(value.t_ns, "changeEnvelopeCodec: t_ns");
|
|
79
|
+
if (value.seq !== void 0 && (!Number.isSafeInteger(value.seq) || value.seq < 0)) {
|
|
80
|
+
throw new TypeError(
|
|
81
|
+
"changeEnvelopeCodec: seq must be a non-negative safe integer when present"
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (!Object.hasOwn(value, "change")) {
|
|
85
|
+
throw new TypeError("changeEnvelopeCodec: change payload is required");
|
|
86
|
+
}
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/storage/observe-event-log.ts
|
|
91
|
+
function observeEventFrame(event, value, opts = {}) {
|
|
92
|
+
return {
|
|
93
|
+
...envelopeChange(value, {
|
|
94
|
+
lifecycle: "data",
|
|
95
|
+
structure: "observe-event",
|
|
96
|
+
version: 1,
|
|
97
|
+
seq: event.seq
|
|
98
|
+
}),
|
|
99
|
+
structure: "observe-event",
|
|
100
|
+
observeSeq: event.seq,
|
|
101
|
+
path: event.path,
|
|
102
|
+
...opts.stream === void 0 ? {} : { stream: opts.stream }
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/adapters/observe-storage.ts
|
|
107
|
+
function attachObserveSink(graph, sink, opts = {}) {
|
|
108
|
+
const { map, onError, path } = opts;
|
|
109
|
+
const queue = [];
|
|
110
|
+
const disposeDone = [];
|
|
111
|
+
let draining = false;
|
|
112
|
+
let disposeRequested = false;
|
|
113
|
+
let disposed = false;
|
|
114
|
+
function report(error, ctx) {
|
|
115
|
+
if (!onError) return;
|
|
116
|
+
try {
|
|
117
|
+
onError(error, ctx);
|
|
118
|
+
} catch {
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function callDone(done) {
|
|
122
|
+
try {
|
|
123
|
+
done?.();
|
|
124
|
+
} catch {
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function run(item) {
|
|
128
|
+
switch (item.kind) {
|
|
129
|
+
case "write":
|
|
130
|
+
return sink.write(item.value);
|
|
131
|
+
case "flush":
|
|
132
|
+
return sink.flush?.();
|
|
133
|
+
case "rollback":
|
|
134
|
+
return sink.rollback?.();
|
|
135
|
+
case "dispose":
|
|
136
|
+
return sink.dispose?.();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function finish(item) {
|
|
140
|
+
if (item.kind === "dispose") {
|
|
141
|
+
disposed = true;
|
|
142
|
+
for (const done of disposeDone.splice(0)) callDone(done);
|
|
143
|
+
} else if (item.kind !== "write") {
|
|
144
|
+
callDone(item.done);
|
|
145
|
+
}
|
|
146
|
+
draining = false;
|
|
147
|
+
drain();
|
|
148
|
+
}
|
|
149
|
+
function fail(item, error) {
|
|
150
|
+
if (item.kind === "write")
|
|
151
|
+
report(error, { phase: "write", event: item.event, value: item.value });
|
|
152
|
+
else report(error, { phase: item.kind });
|
|
153
|
+
finish(item);
|
|
154
|
+
}
|
|
155
|
+
function chainThenable(item, value) {
|
|
156
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) return false;
|
|
157
|
+
let then;
|
|
158
|
+
try {
|
|
159
|
+
then = value.then;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
fail(item, error);
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
if (typeof then !== "function") return false;
|
|
165
|
+
let settled = false;
|
|
166
|
+
const settle = (next) => {
|
|
167
|
+
if (settled) return;
|
|
168
|
+
settled = true;
|
|
169
|
+
next();
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
then.call(
|
|
173
|
+
value,
|
|
174
|
+
() => settle(() => finish(item)),
|
|
175
|
+
(error) => settle(() => fail(item, error))
|
|
176
|
+
);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
settle(() => fail(item, error));
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
function drain() {
|
|
183
|
+
if (draining) return;
|
|
184
|
+
const item = queue.shift();
|
|
185
|
+
if (!item) return;
|
|
186
|
+
draining = true;
|
|
187
|
+
let result;
|
|
188
|
+
try {
|
|
189
|
+
result = run(item);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
fail(item, error);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (chainThenable(item, result)) return;
|
|
195
|
+
finish(item);
|
|
196
|
+
}
|
|
197
|
+
function enqueueBarrier(kind, done) {
|
|
198
|
+
if (disposeRequested) {
|
|
199
|
+
callDone(done);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
queue.push({ kind, done });
|
|
203
|
+
drain();
|
|
204
|
+
}
|
|
205
|
+
const stop = graph.observe(path).subscribe((event) => {
|
|
206
|
+
if (disposeRequested) return;
|
|
207
|
+
let value;
|
|
208
|
+
try {
|
|
209
|
+
value = map ? map(event) : event;
|
|
210
|
+
} catch (error) {
|
|
211
|
+
report(error, { phase: "map", event });
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (value === void 0) return;
|
|
215
|
+
queue.push({ kind: "write", event, value });
|
|
216
|
+
drain();
|
|
217
|
+
});
|
|
218
|
+
return {
|
|
219
|
+
flush(done) {
|
|
220
|
+
enqueueBarrier("flush", done);
|
|
221
|
+
},
|
|
222
|
+
rollback(done) {
|
|
223
|
+
enqueueBarrier("rollback", done);
|
|
224
|
+
},
|
|
225
|
+
dispose(done) {
|
|
226
|
+
if (disposed) {
|
|
227
|
+
callDone(done);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (done) disposeDone.push(done);
|
|
231
|
+
if (disposeRequested) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
disposeRequested = true;
|
|
235
|
+
stop();
|
|
236
|
+
queue.push({ kind: "dispose" });
|
|
237
|
+
drain();
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
function attachObserveEventLog(graph, log, opts = {}) {
|
|
242
|
+
return attachObserveSink(
|
|
243
|
+
graph,
|
|
244
|
+
{ write: (frame) => log.append(frame).then(() => void 0) },
|
|
245
|
+
{
|
|
246
|
+
path: opts.path,
|
|
247
|
+
map: (event) => {
|
|
248
|
+
const value = opts.map ? opts.map(event) : event;
|
|
249
|
+
return value === void 0 ? void 0 : observeEventFrame(event, value, opts);
|
|
250
|
+
},
|
|
251
|
+
onError: opts.onError
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
256
|
+
0 && (module.exports = {
|
|
257
|
+
attachObserveEventLog,
|
|
258
|
+
attachObserveSink
|
|
259
|
+
});
|
|
260
|
+
//# sourceMappingURL=observe-storage.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/observe-storage.ts","../../src/storage/scalar.ts","../../src/storage/change.ts","../../src/storage/observe-event-log.ts"],"sourcesContent":["/**\n * Graph-bound observe storage adapters.\n *\n * Passive storage lives under ../storage. This subpath owns bridges that need\n * Graph.observe() and therefore sit above both graph and passive storage (D125).\n */\n\nimport type { Graph } from \"../graph/graph.js\";\nimport type { ObserveEvent } from \"../graph/inspect.js\";\nimport type { AppendLogStorageTier } from \"../storage/append-log.js\";\nimport {\n\ttype ObserveEventFrame,\n\ttype ObserveEventLogPage,\n\tobserveEventFrame,\n} from \"../storage/observe-event-log.js\";\n\n/** Adapter-owned sink for observed graph events (D57/D74/D125). */\nexport interface ObserveSink<T = ObserveEvent> {\n\t/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */\n\twrite(event: T): void | PromiseLike<void>;\n\t/** Optional adapter flush barrier. Runs after all earlier writes. */\n\tflush?(): void | PromiseLike<void>;\n\t/** Optional adapter rollback hook. Runs after all earlier writes. */\n\trollback?(): void | PromiseLike<void>;\n\t/** Optional adapter cleanup hook. Runs once after queued work drains. */\n\tdispose?(): void | PromiseLike<void>;\n}\n\n/** Error routing context for attachObserveSink lifecycle hooks. */\nexport interface ObserveSinkErrorContext<T = ObserveEvent> {\n\tphase: \"map\" | \"write\" | \"flush\" | \"rollback\" | \"dispose\";\n\tevent?: ObserveEvent;\n\tvalue?: T;\n}\n\n/** Queue-drain completion callback for observe-sink control calls (D75). */\nexport type ObserveSinkDone = () => void;\n\n/** Options for attaching a sink to the read-only observe egress (D74/D125). */\nexport interface AttachObserveSinkOptions<T = ObserveEvent> {\n\t/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */\n\tpath?: string;\n\t/** Optional projection/filter. Return `undefined` to drop an observed event. */\n\tmap?: (event: ObserveEvent) => T | undefined;\n\t/** Optional error hook for mapper, write, and lifecycle failures. */\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;\n}\n\n/** Done-only callback control handle for an attached observe sink (D75). */\nexport interface ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\ntype QueueItem<T> =\n\t| { kind: \"write\"; event: ObserveEvent; value: T }\n\t| { kind: \"flush\"; done?: ObserveSinkDone }\n\t| { kind: \"rollback\"; done?: ObserveSinkDone }\n\t| { kind: \"dispose\" };\n\n/** Options for persisting Graph.observe() events into an append log. */\nexport interface AttachObserveEventLogOptions<T = ObserveEvent> {\n\tpath?: string;\n\tstream?: string;\n\tmap?: (event: ObserveEvent) => T | undefined;\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;\n}\n\n/** Done-callback lifecycle handle for an attached observe-event log. */\nexport interface ObserveEventLogHandle extends ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\nexport type { ObserveEventFrame, ObserveEventLogPage };\n\n/**\n * Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are\n * serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.\n */\nexport function attachObserveSink<T = ObserveEvent>(\n\tgraph: Graph,\n\tsink: ObserveSink<T>,\n\topts: AttachObserveSinkOptions<T> = {},\n): ObserveSinkHandle {\n\tconst { map, onError, path } = opts;\n\tconst queue: QueueItem<T>[] = [];\n\tconst disposeDone: ObserveSinkDone[] = [];\n\tlet draining = false;\n\tlet disposeRequested = false;\n\tlet disposed = false;\n\n\tfunction report(error: unknown, ctx: ObserveSinkErrorContext<T>): void {\n\t\tif (!onError) return;\n\t\ttry {\n\t\t\tonError(error, ctx);\n\t\t} catch {\n\t\t\t// Error routing is best-effort; never let adapter logging wedge the queue.\n\t\t}\n\t}\n\n\tfunction callDone(done?: ObserveSinkDone): void {\n\t\ttry {\n\t\t\tdone?.();\n\t\t} catch {\n\t\t\t// Completion callbacks are advisory only; never wedge the queue on observer code.\n\t\t}\n\t}\n\n\tfunction run(item: QueueItem<T>): void | PromiseLike<void> {\n\t\tswitch (item.kind) {\n\t\t\tcase \"write\":\n\t\t\t\treturn sink.write(item.value);\n\t\t\tcase \"flush\":\n\t\t\t\treturn sink.flush?.();\n\t\t\tcase \"rollback\":\n\t\t\t\treturn sink.rollback?.();\n\t\t\tcase \"dispose\":\n\t\t\t\treturn sink.dispose?.();\n\t\t}\n\t}\n\n\tfunction finish(item: QueueItem<T>): void {\n\t\tif (item.kind === \"dispose\") {\n\t\t\tdisposed = true;\n\t\t\tfor (const done of disposeDone.splice(0)) callDone(done);\n\t\t} else if (item.kind !== \"write\") {\n\t\t\tcallDone(item.done);\n\t\t}\n\t\tdraining = false;\n\t\tdrain();\n\t}\n\n\tfunction fail(item: QueueItem<T>, error: unknown): void {\n\t\tif (item.kind === \"write\")\n\t\t\treport(error, { phase: \"write\", event: item.event, value: item.value });\n\t\telse report(error, { phase: item.kind });\n\t\tfinish(item);\n\t}\n\n\tfunction chainThenable(item: QueueItem<T>, value: unknown): boolean {\n\t\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return false;\n\n\t\tlet then: unknown;\n\t\ttry {\n\t\t\tthen = (value as { then?: unknown }).then;\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof then !== \"function\") return false;\n\n\t\tlet settled = false;\n\t\tconst settle = (next: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tnext();\n\t\t};\n\t\ttry {\n\t\t\t(then as (onFulfilled: () => void, onRejected: (error: unknown) => void) => unknown).call(\n\t\t\t\tvalue,\n\t\t\t\t() => settle(() => finish(item)),\n\t\t\t\t(error) => settle(() => fail(item, error)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsettle(() => fail(item, error));\n\t\t}\n\t\treturn true;\n\t}\n\n\tfunction drain(): void {\n\t\tif (draining) return;\n\t\tconst item = queue.shift();\n\t\tif (!item) return;\n\t\tdraining = true;\n\t\tlet result: void | PromiseLike<void>;\n\t\ttry {\n\t\t\tresult = run(item);\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn;\n\t\t}\n\t\tif (chainThenable(item, result)) return;\n\t\tfinish(item);\n\t}\n\n\tfunction enqueueBarrier(kind: \"flush\" | \"rollback\", done?: ObserveSinkDone): void {\n\t\tif (disposeRequested) {\n\t\t\tcallDone(done);\n\t\t\treturn;\n\t\t}\n\t\tqueue.push({ kind, done });\n\t\tdrain();\n\t}\n\n\tconst stop = graph.observe(path).subscribe((event) => {\n\t\tif (disposeRequested) return;\n\t\tlet value: T | undefined;\n\t\ttry {\n\t\t\tvalue = map ? map(event) : (event as unknown as T);\n\t\t} catch (error) {\n\t\t\treport(error, { phase: \"map\", event });\n\t\t\treturn;\n\t\t}\n\t\tif (value === undefined) return;\n\t\tqueue.push({ kind: \"write\", event, value });\n\t\tdrain();\n\t});\n\n\treturn {\n\t\tflush(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"flush\", done);\n\t\t},\n\t\trollback(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"rollback\", done);\n\t\t},\n\t\tdispose(done?: ObserveSinkDone): void {\n\t\t\tif (disposed) {\n\t\t\t\tcallDone(done);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (done) disposeDone.push(done);\n\t\t\tif (disposeRequested) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdisposeRequested = true;\n\t\t\tstop();\n\t\t\tqueue.push({ kind: \"dispose\" });\n\t\t\tdrain();\n\t\t},\n\t};\n}\n\n/**\n * Persist Graph.observe() events to an append log. This is a graph-bound\n * adapter over passive storage frames, not graph restore or projection.\n */\nexport function attachObserveEventLog<T = ObserveEvent>(\n\tgraph: Graph,\n\tlog: AppendLogStorageTier<ObserveEventFrame<T>>,\n\topts: AttachObserveEventLogOptions<T> = {},\n): ObserveEventLogHandle {\n\treturn attachObserveSink<ObserveEventFrame<T>>(\n\t\tgraph,\n\t\t{ write: (frame) => log.append(frame).then(() => undefined) },\n\t\t{\n\t\t\tpath: opts.path,\n\t\t\tmap: (event) => {\n\t\t\t\tconst value = opts.map ? opts.map(event) : (event as unknown as T);\n\t\t\t\treturn value === undefined ? undefined : observeEventFrame(event, value, opts);\n\t\t\t},\n\t\t\tonError: opts.onError,\n\t\t},\n\t);\n}\n","/**\n * Storage scalar helpers (D88): host BigInt in memory, canonical decimal strings on JSON/storage.\n */\n\n/** Canonical decimal integer string; no leading zeroes, and no negative zero. */\nexport type DecimalIntegerString = string;\n\n/** Canonical non-negative decimal integer string. */\nexport type NonNegativeDecimalIntegerString = DecimalIntegerString;\n\nconst DECIMAL_INTEGER_RE = /^(0|-?[1-9]\\d*)$/;\nconst NON_NEGATIVE_DECIMAL_INTEGER_RE = /^(0|[1-9]\\d*)$/;\n\n/** Test whether a value is a canonical decimal integer string. */\nexport function isDecimalIntegerString(value: unknown): value is DecimalIntegerString {\n\treturn typeof value === \"string\" && DECIMAL_INTEGER_RE.test(value);\n}\n\n/** Test whether a value is a canonical non-negative decimal integer string. */\nexport function isNonNegativeDecimalIntegerString(\n\tvalue: unknown,\n): value is NonNegativeDecimalIntegerString {\n\treturn typeof value === \"string\" && NON_NEGATIVE_DECIMAL_INTEGER_RE.test(value);\n}\n\n/** Assert a canonical decimal integer string and return it typed. */\nexport function assertDecimalIntegerString(\n\tvalue: unknown,\n\tlabel = \"decimal integer\",\n): DecimalIntegerString {\n\tif (!isDecimalIntegerString(value)) {\n\t\tthrow new TypeError(`${label} must be a canonical decimal integer string`);\n\t}\n\treturn value;\n}\n\n/** Assert a canonical non-negative decimal integer string and return it typed. */\nexport function assertNonNegativeDecimalIntegerString(\n\tvalue: unknown,\n\tlabel = \"decimal integer\",\n): NonNegativeDecimalIntegerString {\n\tif (!isNonNegativeDecimalIntegerString(value)) {\n\t\tthrow new TypeError(`${label} must be a canonical non-negative decimal integer string`);\n\t}\n\treturn value;\n}\n\n/** Convert a host BigInt to the canonical decimal storage scalar. */\nexport function bigIntToDecimalString(value: bigint): DecimalIntegerString {\n\treturn value.toString();\n}\n\n/** Convert a non-negative host BigInt to the canonical non-negative decimal storage scalar. */\nexport function bigIntToNonNegativeDecimalString(value: bigint): NonNegativeDecimalIntegerString {\n\tif (value < 0n) {\n\t\tthrow new TypeError(\"decimal integer must be non-negative\");\n\t}\n\treturn value.toString();\n}\n\n/** Parse a canonical decimal storage scalar into host BigInt. */\nexport function decimalStringToBigInt(value: DecimalIntegerString): bigint {\n\treturn BigInt(assertDecimalIntegerString(value));\n}\n\n/** Parse a canonical non-negative decimal storage scalar into host BigInt. */\nexport function nonNegativeDecimalStringToBigInt(value: NonNegativeDecimalIntegerString): bigint {\n\treturn BigInt(assertNonNegativeDecimalIntegerString(value));\n}\n","/**\n * Storage change envelopes (D82): persistence framing for raw graph/data-structure deltas.\n */\n\nimport type { Codec } from \"./codec.js\";\nimport { strictJsonCodecFor } from \"./codec.js\";\nimport {\n\tassertNonNegativeDecimalIntegerString,\n\tbigIntToNonNegativeDecimalString,\n\ttype NonNegativeDecimalIntegerString,\n} from \"./scalar.js\";\n\n/** Storage-side lifecycle namespace for change envelopes; presentation framing only. */\nexport type ChangeLifecycle = \"spec\" | \"data\" | \"ownership\";\n\n/** D84 cross-runtime wall-clock nanosecond metadata: canonical non-negative decimal string. */\nexport type StorageTimestampNs = NonNegativeDecimalIntegerString;\n\n/** Persistence envelope for raw graph/data-structure deltas (D82), not restore semantics. */\nexport interface ChangeEnvelope<T = unknown> {\n\treadonly lifecycle: ChangeLifecycle;\n\treadonly structure: string;\n\treadonly version: number | string;\n\treadonly t_ns: StorageTimestampNs;\n\treadonly seq?: number;\n\treadonly change: T;\n}\n\n/** Options for wrapping a raw change in a storage envelope. */\nexport interface ChangeEnvelopeOptions {\n\tlifecycle?: ChangeLifecycle;\n\tstructure: string;\n\tversion?: number | string;\n\tt_ns?: StorageTimestampNs;\n\tseq?: number;\n}\n\n/** Wall-clock nanoseconds for storage metadata. */\nexport function nowNs(): StorageTimestampNs {\n\treturn bigIntToNonNegativeDecimalString(BigInt(Date.now()) * 1_000_000n);\n}\n\n/** Wrap a raw change payload in a D82 storage envelope. */\nexport function envelopeChange<T>(change: T, opts: ChangeEnvelopeOptions): ChangeEnvelope<T> {\n\tconst envelope = {\n\t\tlifecycle: opts.lifecycle ?? \"data\",\n\t\tstructure: opts.structure,\n\t\tversion: opts.version ?? 1,\n\t\tt_ns: opts.t_ns ?? nowNs(),\n\t\t...(opts.seq === undefined ? {} : { seq: opts.seq }),\n\t\tchange,\n\t};\n\treturn assertChangeEnvelope<T>(envelope);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isLifecycle(value: unknown): value is ChangeLifecycle {\n\treturn value === \"spec\" || value === \"data\" || value === \"ownership\";\n}\n\n/** Validate a decoded D82 change envelope and return it with typed payload. */\nexport function assertChangeEnvelope<T = unknown>(value: unknown): ChangeEnvelope<T> {\n\tif (!isRecord(value)) throw new TypeError(\"changeEnvelopeCodec: frame must be an object\");\n\tif (!isLifecycle(value.lifecycle)) {\n\t\tthrow new TypeError(\"changeEnvelopeCodec: lifecycle must be spec, data, or ownership\");\n\t}\n\tif (typeof value.structure !== \"string\" || value.structure.length === 0) {\n\t\tthrow new TypeError(\"changeEnvelopeCodec: structure must be a non-empty string\");\n\t}\n\tif (\n\t\t(typeof value.version !== \"number\" || !Number.isFinite(value.version)) &&\n\t\ttypeof value.version !== \"string\"\n\t) {\n\t\tthrow new TypeError(\"changeEnvelopeCodec: version must be a finite number or string\");\n\t}\n\tassertNonNegativeDecimalIntegerString(value.t_ns, \"changeEnvelopeCodec: t_ns\");\n\tif (value.seq !== undefined && (!Number.isSafeInteger(value.seq) || (value.seq as number) < 0)) {\n\t\tthrow new TypeError(\n\t\t\t\"changeEnvelopeCodec: seq must be a non-negative safe integer when present\",\n\t\t);\n\t}\n\tif (!Object.hasOwn(value, \"change\")) {\n\t\tthrow new TypeError(\"changeEnvelopeCodec: change payload is required\");\n\t}\n\treturn value as unknown as ChangeEnvelope<T>;\n}\n\n/** Stable JSON codec for D82 change envelopes, with strict framing checks. */\nexport function changeEnvelopeCodec<T = unknown>(): Codec<ChangeEnvelope<T>> {\n\tconst codec = strictJsonCodecFor<unknown>();\n\treturn {\n\t\tencode(value) {\n\t\t\treturn codec.encode(assertChangeEnvelope(value));\n\t\t},\n\t\tdecode(bytes) {\n\t\t\treturn assertChangeEnvelope<T>(codec.decode(bytes));\n\t\t},\n\t};\n}\n","import type { AppendLogPage, AppendLogReadOptions, AppendLogStorageTier } from \"./append-log.js\";\nimport { readAppendLogPage } from \"./append-log.js\";\nimport { assertChangeEnvelope, type ChangeEnvelope, envelopeChange } from \"./change.js\";\nimport type { Codec } from \"./codec.js\";\nimport { strictJsonCodecFor } from \"./codec.js\";\n\nexport interface ObserveEventLike {\n\treadonly seq: number;\n\treadonly path: string;\n}\n\n/** Storage frame for one Graph.observe() event, preserving graph observe sequence. */\nexport interface ObserveEventFrame<T = unknown> extends ChangeEnvelope<T> {\n\treadonly structure: \"observe-event\";\n\treadonly observeSeq: number;\n\treadonly path: string;\n\treadonly stream?: string;\n}\n\n/** One ordered observe-event log page. It is not graph projection or restore replay. */\nexport type ObserveEventLogPage<T = unknown> = AppendLogPage<ObserveEventFrame<T>>;\n\n/** Create a storage frame from one observe event and mapped payload. */\nexport function observeEventFrame<T>(\n\tevent: ObserveEventLike,\n\tvalue: T,\n\topts: { stream?: string } = {},\n): ObserveEventFrame<T> {\n\treturn {\n\t\t...envelopeChange(value, {\n\t\t\tlifecycle: \"data\",\n\t\t\tstructure: \"observe-event\",\n\t\t\tversion: 1,\n\t\t\tseq: event.seq,\n\t\t}),\n\t\tstructure: \"observe-event\",\n\t\tobserveSeq: event.seq,\n\t\tpath: event.path,\n\t\t...(opts.stream === undefined ? {} : { stream: opts.stream }),\n\t};\n}\n\n/** Validate a decoded D82 observe-event storage frame. */\nexport function assertObserveEventFrame<T = unknown>(value: unknown): ObserveEventFrame<T> {\n\tconst frame = assertChangeEnvelope<T>(value);\n\tconst record = frame as unknown as Record<string, unknown>;\n\tif (frame.structure !== \"observe-event\") {\n\t\tthrow new TypeError(\"observeEventFrameCodec: structure must be observe-event\");\n\t}\n\tif (!Number.isSafeInteger(record.observeSeq) || (record.observeSeq as number) < 0) {\n\t\tthrow new TypeError(\"observeEventFrameCodec: observeSeq must be a non-negative safe integer\");\n\t}\n\tif (typeof record.path !== \"string\") {\n\t\tthrow new TypeError(\"observeEventFrameCodec: path must be a string\");\n\t}\n\tif (record.stream !== undefined && typeof record.stream !== \"string\") {\n\t\tthrow new TypeError(\"observeEventFrameCodec: stream must be a string when present\");\n\t}\n\treturn frame as ObserveEventFrame<T>;\n}\n\n/** Stable JSON codec for D82 observe-event frames, not restore records. */\nexport function observeEventFrameCodec<T = unknown>(): Codec<ObserveEventFrame<T>> {\n\tconst codec = strictJsonCodecFor<unknown>();\n\treturn {\n\t\tencode(value) {\n\t\t\treturn codec.encode(assertObserveEventFrame(value));\n\t\t},\n\t\tdecode(bytes) {\n\t\t\treturn assertObserveEventFrame<T>(codec.decode(bytes));\n\t\t},\n\t};\n}\n\n/**\n * Read one ordered observe-event log page without projecting it into graph state.\n */\nexport function readObserveEventLogPage<T = unknown>(\n\tlog: AppendLogStorageTier<ObserveEventFrame<T>>,\n\topts: AppendLogReadOptions = {},\n): Promise<ObserveEventLogPage<T>> {\n\treturn readAppendLogPage(log, opts);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { O as ObserveEvent, d as Graph } from '../graph-s23RbbFO.cjs';
|
|
2
|
+
import { d as AppendLogStorageTier } from '../append-log-DisvEReb.cjs';
|
|
3
|
+
import { O as ObserveEventFrame } from '../observe-event-log-0SVsx7JG.cjs';
|
|
4
|
+
export { c as ObserveEventLogPage } from '../observe-event-log-0SVsx7JG.cjs';
|
|
5
|
+
import '../core/index.cjs';
|
|
6
|
+
import '../types-bNMSWKqF.cjs';
|
|
7
|
+
import '../messages-BZqrGGm1.cjs';
|
|
8
|
+
import '../codec-BB7p8fJc.cjs';
|
|
9
|
+
import '../describe-Ciu8SUnN.cjs';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Graph-bound observe storage adapters.
|
|
13
|
+
*
|
|
14
|
+
* Passive storage lives under ../storage. This subpath owns bridges that need
|
|
15
|
+
* Graph.observe() and therefore sit above both graph and passive storage (D125).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Adapter-owned sink for observed graph events (D57/D74/D125). */
|
|
19
|
+
interface ObserveSink<T = ObserveEvent> {
|
|
20
|
+
/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */
|
|
21
|
+
write(event: T): void | PromiseLike<void>;
|
|
22
|
+
/** Optional adapter flush barrier. Runs after all earlier writes. */
|
|
23
|
+
flush?(): void | PromiseLike<void>;
|
|
24
|
+
/** Optional adapter rollback hook. Runs after all earlier writes. */
|
|
25
|
+
rollback?(): void | PromiseLike<void>;
|
|
26
|
+
/** Optional adapter cleanup hook. Runs once after queued work drains. */
|
|
27
|
+
dispose?(): void | PromiseLike<void>;
|
|
28
|
+
}
|
|
29
|
+
/** Error routing context for attachObserveSink lifecycle hooks. */
|
|
30
|
+
interface ObserveSinkErrorContext<T = ObserveEvent> {
|
|
31
|
+
phase: "map" | "write" | "flush" | "rollback" | "dispose";
|
|
32
|
+
event?: ObserveEvent;
|
|
33
|
+
value?: T;
|
|
34
|
+
}
|
|
35
|
+
/** Queue-drain completion callback for observe-sink control calls (D75). */
|
|
36
|
+
type ObserveSinkDone = () => void;
|
|
37
|
+
/** Options for attaching a sink to the read-only observe egress (D74/D125). */
|
|
38
|
+
interface AttachObserveSinkOptions<T = ObserveEvent> {
|
|
39
|
+
/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */
|
|
40
|
+
path?: string;
|
|
41
|
+
/** Optional projection/filter. Return `undefined` to drop an observed event. */
|
|
42
|
+
map?: (event: ObserveEvent) => T | undefined;
|
|
43
|
+
/** Optional error hook for mapper, write, and lifecycle failures. */
|
|
44
|
+
onError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;
|
|
45
|
+
}
|
|
46
|
+
/** Done-only callback control handle for an attached observe sink (D75). */
|
|
47
|
+
interface ObserveSinkHandle {
|
|
48
|
+
flush(done?: ObserveSinkDone): void;
|
|
49
|
+
rollback(done?: ObserveSinkDone): void;
|
|
50
|
+
dispose(done?: ObserveSinkDone): void;
|
|
51
|
+
}
|
|
52
|
+
/** Options for persisting Graph.observe() events into an append log. */
|
|
53
|
+
interface AttachObserveEventLogOptions<T = ObserveEvent> {
|
|
54
|
+
path?: string;
|
|
55
|
+
stream?: string;
|
|
56
|
+
map?: (event: ObserveEvent) => T | undefined;
|
|
57
|
+
onError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;
|
|
58
|
+
}
|
|
59
|
+
/** Done-callback lifecycle handle for an attached observe-event log. */
|
|
60
|
+
interface ObserveEventLogHandle extends ObserveSinkHandle {
|
|
61
|
+
flush(done?: ObserveSinkDone): void;
|
|
62
|
+
rollback(done?: ObserveSinkDone): void;
|
|
63
|
+
dispose(done?: ObserveSinkDone): void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are
|
|
68
|
+
* serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.
|
|
69
|
+
*/
|
|
70
|
+
declare function attachObserveSink<T = ObserveEvent>(graph: Graph, sink: ObserveSink<T>, opts?: AttachObserveSinkOptions<T>): ObserveSinkHandle;
|
|
71
|
+
/**
|
|
72
|
+
* Persist Graph.observe() events to an append log. This is a graph-bound
|
|
73
|
+
* adapter over passive storage frames, not graph restore or projection.
|
|
74
|
+
*/
|
|
75
|
+
declare function attachObserveEventLog<T = ObserveEvent>(graph: Graph, log: AppendLogStorageTier<ObserveEventFrame<T>>, opts?: AttachObserveEventLogOptions<T>): ObserveEventLogHandle;
|
|
76
|
+
|
|
77
|
+
export { type AttachObserveEventLogOptions, type AttachObserveSinkOptions, ObserveEventFrame, type ObserveEventLogHandle, type ObserveSink, type ObserveSinkDone, type ObserveSinkErrorContext, type ObserveSinkHandle, attachObserveEventLog, attachObserveSink };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { O as ObserveEvent, d as Graph } from '../graph-DfdF9zy4.js';
|
|
2
|
+
import { d as AppendLogStorageTier } from '../append-log-DzKMmjxx.js';
|
|
3
|
+
import { O as ObserveEventFrame } from '../observe-event-log-Dnm76owp.js';
|
|
4
|
+
export { c as ObserveEventLogPage } from '../observe-event-log-Dnm76owp.js';
|
|
5
|
+
import '../core/index.js';
|
|
6
|
+
import '../types-h12mNYbq.js';
|
|
7
|
+
import '../messages-BZqrGGm1.js';
|
|
8
|
+
import '../codec-BB7p8fJc.js';
|
|
9
|
+
import '../describe-BZb7AS2y.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Graph-bound observe storage adapters.
|
|
13
|
+
*
|
|
14
|
+
* Passive storage lives under ../storage. This subpath owns bridges that need
|
|
15
|
+
* Graph.observe() and therefore sit above both graph and passive storage (D125).
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** Adapter-owned sink for observed graph events (D57/D74/D125). */
|
|
19
|
+
interface ObserveSink<T = ObserveEvent> {
|
|
20
|
+
/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */
|
|
21
|
+
write(event: T): void | PromiseLike<void>;
|
|
22
|
+
/** Optional adapter flush barrier. Runs after all earlier writes. */
|
|
23
|
+
flush?(): void | PromiseLike<void>;
|
|
24
|
+
/** Optional adapter rollback hook. Runs after all earlier writes. */
|
|
25
|
+
rollback?(): void | PromiseLike<void>;
|
|
26
|
+
/** Optional adapter cleanup hook. Runs once after queued work drains. */
|
|
27
|
+
dispose?(): void | PromiseLike<void>;
|
|
28
|
+
}
|
|
29
|
+
/** Error routing context for attachObserveSink lifecycle hooks. */
|
|
30
|
+
interface ObserveSinkErrorContext<T = ObserveEvent> {
|
|
31
|
+
phase: "map" | "write" | "flush" | "rollback" | "dispose";
|
|
32
|
+
event?: ObserveEvent;
|
|
33
|
+
value?: T;
|
|
34
|
+
}
|
|
35
|
+
/** Queue-drain completion callback for observe-sink control calls (D75). */
|
|
36
|
+
type ObserveSinkDone = () => void;
|
|
37
|
+
/** Options for attaching a sink to the read-only observe egress (D74/D125). */
|
|
38
|
+
interface AttachObserveSinkOptions<T = ObserveEvent> {
|
|
39
|
+
/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */
|
|
40
|
+
path?: string;
|
|
41
|
+
/** Optional projection/filter. Return `undefined` to drop an observed event. */
|
|
42
|
+
map?: (event: ObserveEvent) => T | undefined;
|
|
43
|
+
/** Optional error hook for mapper, write, and lifecycle failures. */
|
|
44
|
+
onError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;
|
|
45
|
+
}
|
|
46
|
+
/** Done-only callback control handle for an attached observe sink (D75). */
|
|
47
|
+
interface ObserveSinkHandle {
|
|
48
|
+
flush(done?: ObserveSinkDone): void;
|
|
49
|
+
rollback(done?: ObserveSinkDone): void;
|
|
50
|
+
dispose(done?: ObserveSinkDone): void;
|
|
51
|
+
}
|
|
52
|
+
/** Options for persisting Graph.observe() events into an append log. */
|
|
53
|
+
interface AttachObserveEventLogOptions<T = ObserveEvent> {
|
|
54
|
+
path?: string;
|
|
55
|
+
stream?: string;
|
|
56
|
+
map?: (event: ObserveEvent) => T | undefined;
|
|
57
|
+
onError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;
|
|
58
|
+
}
|
|
59
|
+
/** Done-callback lifecycle handle for an attached observe-event log. */
|
|
60
|
+
interface ObserveEventLogHandle extends ObserveSinkHandle {
|
|
61
|
+
flush(done?: ObserveSinkDone): void;
|
|
62
|
+
rollback(done?: ObserveSinkDone): void;
|
|
63
|
+
dispose(done?: ObserveSinkDone): void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are
|
|
68
|
+
* serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.
|
|
69
|
+
*/
|
|
70
|
+
declare function attachObserveSink<T = ObserveEvent>(graph: Graph, sink: ObserveSink<T>, opts?: AttachObserveSinkOptions<T>): ObserveSinkHandle;
|
|
71
|
+
/**
|
|
72
|
+
* Persist Graph.observe() events to an append log. This is a graph-bound
|
|
73
|
+
* adapter over passive storage frames, not graph restore or projection.
|
|
74
|
+
*/
|
|
75
|
+
declare function attachObserveEventLog<T = ObserveEvent>(graph: Graph, log: AppendLogStorageTier<ObserveEventFrame<T>>, opts?: AttachObserveEventLogOptions<T>): ObserveEventLogHandle;
|
|
76
|
+
|
|
77
|
+
export { type AttachObserveEventLogOptions, type AttachObserveSinkOptions, ObserveEventFrame, type ObserveEventLogHandle, type ObserveSink, type ObserveSinkDone, type ObserveSinkErrorContext, type ObserveSinkHandle, attachObserveEventLog, attachObserveSink };
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
observeEventFrame
|
|
3
|
+
} from "../chunk-K3FXTC3I.js";
|
|
4
|
+
import "../chunk-6PHB5CJS.js";
|
|
5
|
+
import "../chunk-DKP56CSW.js";
|
|
6
|
+
import "../chunk-4VLAQHZI.js";
|
|
7
|
+
|
|
8
|
+
// src/adapters/observe-storage.ts
|
|
9
|
+
function attachObserveSink(graph, sink, opts = {}) {
|
|
10
|
+
const { map, onError, path } = opts;
|
|
11
|
+
const queue = [];
|
|
12
|
+
const disposeDone = [];
|
|
13
|
+
let draining = false;
|
|
14
|
+
let disposeRequested = false;
|
|
15
|
+
let disposed = false;
|
|
16
|
+
function report(error, ctx) {
|
|
17
|
+
if (!onError) return;
|
|
18
|
+
try {
|
|
19
|
+
onError(error, ctx);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function callDone(done) {
|
|
24
|
+
try {
|
|
25
|
+
done?.();
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function run(item) {
|
|
30
|
+
switch (item.kind) {
|
|
31
|
+
case "write":
|
|
32
|
+
return sink.write(item.value);
|
|
33
|
+
case "flush":
|
|
34
|
+
return sink.flush?.();
|
|
35
|
+
case "rollback":
|
|
36
|
+
return sink.rollback?.();
|
|
37
|
+
case "dispose":
|
|
38
|
+
return sink.dispose?.();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function finish(item) {
|
|
42
|
+
if (item.kind === "dispose") {
|
|
43
|
+
disposed = true;
|
|
44
|
+
for (const done of disposeDone.splice(0)) callDone(done);
|
|
45
|
+
} else if (item.kind !== "write") {
|
|
46
|
+
callDone(item.done);
|
|
47
|
+
}
|
|
48
|
+
draining = false;
|
|
49
|
+
drain();
|
|
50
|
+
}
|
|
51
|
+
function fail(item, error) {
|
|
52
|
+
if (item.kind === "write")
|
|
53
|
+
report(error, { phase: "write", event: item.event, value: item.value });
|
|
54
|
+
else report(error, { phase: item.kind });
|
|
55
|
+
finish(item);
|
|
56
|
+
}
|
|
57
|
+
function chainThenable(item, value) {
|
|
58
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) return false;
|
|
59
|
+
let then;
|
|
60
|
+
try {
|
|
61
|
+
then = value.then;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
fail(item, error);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (typeof then !== "function") return false;
|
|
67
|
+
let settled = false;
|
|
68
|
+
const settle = (next) => {
|
|
69
|
+
if (settled) return;
|
|
70
|
+
settled = true;
|
|
71
|
+
next();
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
then.call(
|
|
75
|
+
value,
|
|
76
|
+
() => settle(() => finish(item)),
|
|
77
|
+
(error) => settle(() => fail(item, error))
|
|
78
|
+
);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
settle(() => fail(item, error));
|
|
81
|
+
}
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
function drain() {
|
|
85
|
+
if (draining) return;
|
|
86
|
+
const item = queue.shift();
|
|
87
|
+
if (!item) return;
|
|
88
|
+
draining = true;
|
|
89
|
+
let result;
|
|
90
|
+
try {
|
|
91
|
+
result = run(item);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
fail(item, error);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (chainThenable(item, result)) return;
|
|
97
|
+
finish(item);
|
|
98
|
+
}
|
|
99
|
+
function enqueueBarrier(kind, done) {
|
|
100
|
+
if (disposeRequested) {
|
|
101
|
+
callDone(done);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
queue.push({ kind, done });
|
|
105
|
+
drain();
|
|
106
|
+
}
|
|
107
|
+
const stop = graph.observe(path).subscribe((event) => {
|
|
108
|
+
if (disposeRequested) return;
|
|
109
|
+
let value;
|
|
110
|
+
try {
|
|
111
|
+
value = map ? map(event) : event;
|
|
112
|
+
} catch (error) {
|
|
113
|
+
report(error, { phase: "map", event });
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (value === void 0) return;
|
|
117
|
+
queue.push({ kind: "write", event, value });
|
|
118
|
+
drain();
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
flush(done) {
|
|
122
|
+
enqueueBarrier("flush", done);
|
|
123
|
+
},
|
|
124
|
+
rollback(done) {
|
|
125
|
+
enqueueBarrier("rollback", done);
|
|
126
|
+
},
|
|
127
|
+
dispose(done) {
|
|
128
|
+
if (disposed) {
|
|
129
|
+
callDone(done);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (done) disposeDone.push(done);
|
|
133
|
+
if (disposeRequested) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
disposeRequested = true;
|
|
137
|
+
stop();
|
|
138
|
+
queue.push({ kind: "dispose" });
|
|
139
|
+
drain();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function attachObserveEventLog(graph, log, opts = {}) {
|
|
144
|
+
return attachObserveSink(
|
|
145
|
+
graph,
|
|
146
|
+
{ write: (frame) => log.append(frame).then(() => void 0) },
|
|
147
|
+
{
|
|
148
|
+
path: opts.path,
|
|
149
|
+
map: (event) => {
|
|
150
|
+
const value = opts.map ? opts.map(event) : event;
|
|
151
|
+
return value === void 0 ? void 0 : observeEventFrame(event, value, opts);
|
|
152
|
+
},
|
|
153
|
+
onError: opts.onError
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
export {
|
|
158
|
+
attachObserveEventLog,
|
|
159
|
+
attachObserveSink
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=observe-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/observe-storage.ts"],"sourcesContent":["/**\n * Graph-bound observe storage adapters.\n *\n * Passive storage lives under ../storage. This subpath owns bridges that need\n * Graph.observe() and therefore sit above both graph and passive storage (D125).\n */\n\nimport type { Graph } from \"../graph/graph.js\";\nimport type { ObserveEvent } from \"../graph/inspect.js\";\nimport type { AppendLogStorageTier } from \"../storage/append-log.js\";\nimport {\n\ttype ObserveEventFrame,\n\ttype ObserveEventLogPage,\n\tobserveEventFrame,\n} from \"../storage/observe-event-log.js\";\n\n/** Adapter-owned sink for observed graph events (D57/D74/D125). */\nexport interface ObserveSink<T = ObserveEvent> {\n\t/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */\n\twrite(event: T): void | PromiseLike<void>;\n\t/** Optional adapter flush barrier. Runs after all earlier writes. */\n\tflush?(): void | PromiseLike<void>;\n\t/** Optional adapter rollback hook. Runs after all earlier writes. */\n\trollback?(): void | PromiseLike<void>;\n\t/** Optional adapter cleanup hook. Runs once after queued work drains. */\n\tdispose?(): void | PromiseLike<void>;\n}\n\n/** Error routing context for attachObserveSink lifecycle hooks. */\nexport interface ObserveSinkErrorContext<T = ObserveEvent> {\n\tphase: \"map\" | \"write\" | \"flush\" | \"rollback\" | \"dispose\";\n\tevent?: ObserveEvent;\n\tvalue?: T;\n}\n\n/** Queue-drain completion callback for observe-sink control calls (D75). */\nexport type ObserveSinkDone = () => void;\n\n/** Options for attaching a sink to the read-only observe egress (D74/D125). */\nexport interface AttachObserveSinkOptions<T = ObserveEvent> {\n\t/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */\n\tpath?: string;\n\t/** Optional projection/filter. Return `undefined` to drop an observed event. */\n\tmap?: (event: ObserveEvent) => T | undefined;\n\t/** Optional error hook for mapper, write, and lifecycle failures. */\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;\n}\n\n/** Done-only callback control handle for an attached observe sink (D75). */\nexport interface ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\ntype QueueItem<T> =\n\t| { kind: \"write\"; event: ObserveEvent; value: T }\n\t| { kind: \"flush\"; done?: ObserveSinkDone }\n\t| { kind: \"rollback\"; done?: ObserveSinkDone }\n\t| { kind: \"dispose\" };\n\n/** Options for persisting Graph.observe() events into an append log. */\nexport interface AttachObserveEventLogOptions<T = ObserveEvent> {\n\tpath?: string;\n\tstream?: string;\n\tmap?: (event: ObserveEvent) => T | undefined;\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;\n}\n\n/** Done-callback lifecycle handle for an attached observe-event log. */\nexport interface ObserveEventLogHandle extends ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\nexport type { ObserveEventFrame, ObserveEventLogPage };\n\n/**\n * Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are\n * serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.\n */\nexport function attachObserveSink<T = ObserveEvent>(\n\tgraph: Graph,\n\tsink: ObserveSink<T>,\n\topts: AttachObserveSinkOptions<T> = {},\n): ObserveSinkHandle {\n\tconst { map, onError, path } = opts;\n\tconst queue: QueueItem<T>[] = [];\n\tconst disposeDone: ObserveSinkDone[] = [];\n\tlet draining = false;\n\tlet disposeRequested = false;\n\tlet disposed = false;\n\n\tfunction report(error: unknown, ctx: ObserveSinkErrorContext<T>): void {\n\t\tif (!onError) return;\n\t\ttry {\n\t\t\tonError(error, ctx);\n\t\t} catch {\n\t\t\t// Error routing is best-effort; never let adapter logging wedge the queue.\n\t\t}\n\t}\n\n\tfunction callDone(done?: ObserveSinkDone): void {\n\t\ttry {\n\t\t\tdone?.();\n\t\t} catch {\n\t\t\t// Completion callbacks are advisory only; never wedge the queue on observer code.\n\t\t}\n\t}\n\n\tfunction run(item: QueueItem<T>): void | PromiseLike<void> {\n\t\tswitch (item.kind) {\n\t\t\tcase \"write\":\n\t\t\t\treturn sink.write(item.value);\n\t\t\tcase \"flush\":\n\t\t\t\treturn sink.flush?.();\n\t\t\tcase \"rollback\":\n\t\t\t\treturn sink.rollback?.();\n\t\t\tcase \"dispose\":\n\t\t\t\treturn sink.dispose?.();\n\t\t}\n\t}\n\n\tfunction finish(item: QueueItem<T>): void {\n\t\tif (item.kind === \"dispose\") {\n\t\t\tdisposed = true;\n\t\t\tfor (const done of disposeDone.splice(0)) callDone(done);\n\t\t} else if (item.kind !== \"write\") {\n\t\t\tcallDone(item.done);\n\t\t}\n\t\tdraining = false;\n\t\tdrain();\n\t}\n\n\tfunction fail(item: QueueItem<T>, error: unknown): void {\n\t\tif (item.kind === \"write\")\n\t\t\treport(error, { phase: \"write\", event: item.event, value: item.value });\n\t\telse report(error, { phase: item.kind });\n\t\tfinish(item);\n\t}\n\n\tfunction chainThenable(item: QueueItem<T>, value: unknown): boolean {\n\t\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return false;\n\n\t\tlet then: unknown;\n\t\ttry {\n\t\t\tthen = (value as { then?: unknown }).then;\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof then !== \"function\") return false;\n\n\t\tlet settled = false;\n\t\tconst settle = (next: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tnext();\n\t\t};\n\t\ttry {\n\t\t\t(then as (onFulfilled: () => void, onRejected: (error: unknown) => void) => unknown).call(\n\t\t\t\tvalue,\n\t\t\t\t() => settle(() => finish(item)),\n\t\t\t\t(error) => settle(() => fail(item, error)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsettle(() => fail(item, error));\n\t\t}\n\t\treturn true;\n\t}\n\n\tfunction drain(): void {\n\t\tif (draining) return;\n\t\tconst item = queue.shift();\n\t\tif (!item) return;\n\t\tdraining = true;\n\t\tlet result: void | PromiseLike<void>;\n\t\ttry {\n\t\t\tresult = run(item);\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn;\n\t\t}\n\t\tif (chainThenable(item, result)) return;\n\t\tfinish(item);\n\t}\n\n\tfunction enqueueBarrier(kind: \"flush\" | \"rollback\", done?: ObserveSinkDone): void {\n\t\tif (disposeRequested) {\n\t\t\tcallDone(done);\n\t\t\treturn;\n\t\t}\n\t\tqueue.push({ kind, done });\n\t\tdrain();\n\t}\n\n\tconst stop = graph.observe(path).subscribe((event) => {\n\t\tif (disposeRequested) return;\n\t\tlet value: T | undefined;\n\t\ttry {\n\t\t\tvalue = map ? map(event) : (event as unknown as T);\n\t\t} catch (error) {\n\t\t\treport(error, { phase: \"map\", event });\n\t\t\treturn;\n\t\t}\n\t\tif (value === undefined) return;\n\t\tqueue.push({ kind: \"write\", event, value });\n\t\tdrain();\n\t});\n\n\treturn {\n\t\tflush(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"flush\", done);\n\t\t},\n\t\trollback(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"rollback\", done);\n\t\t},\n\t\tdispose(done?: ObserveSinkDone): void {\n\t\t\tif (disposed) {\n\t\t\t\tcallDone(done);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (done) disposeDone.push(done);\n\t\t\tif (disposeRequested) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdisposeRequested = true;\n\t\t\tstop();\n\t\t\tqueue.push({ kind: \"dispose\" });\n\t\t\tdrain();\n\t\t},\n\t};\n}\n\n/**\n * Persist Graph.observe() events to an append log. This is a graph-bound\n * adapter over passive storage frames, not graph restore or projection.\n */\nexport function attachObserveEventLog<T = ObserveEvent>(\n\tgraph: Graph,\n\tlog: AppendLogStorageTier<ObserveEventFrame<T>>,\n\topts: AttachObserveEventLogOptions<T> = {},\n): ObserveEventLogHandle {\n\treturn attachObserveSink<ObserveEventFrame<T>>(\n\t\tgraph,\n\t\t{ write: (frame) => log.append(frame).then(() => undefined) },\n\t\t{\n\t\t\tpath: opts.path,\n\t\t\tmap: (event) => {\n\t\t\t\tconst value = opts.map ? opts.map(event) : (event as unknown as T);\n\t\t\t\treturn value === undefined ? undefined : observeEventFrame(event, value, opts);\n\t\t\t},\n\t\t\tonError: opts.onError,\n\t\t},\n\t);\n}\n"],"mappings":"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","names":[]}
|