@wovin/core 0.0.1-RC6 → 0.0.1-RC7

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.
@@ -0,0 +1,577 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ var _chunkMS4K4RCZcjs = require('./chunk-MS4K4RCZ.cjs');
19
+
20
+
21
+ var _chunkMLDNHGG3cjs = require('./chunk-MLDNHGG3.cjs');
22
+
23
+ // src/stream/writeable.ts
24
+ var _src = require('besonders-logger/src');
25
+ var _mobx = require('mobx');
26
+
27
+ // src/data/applog-helpers.ts
28
+
29
+
30
+
31
+ // src/queries/basic.ts
32
+
33
+
34
+ var _safestablestringify = require('safe-stable-stringify'); var _safestablestringify2 = _interopRequireDefault(_safestablestringify);
35
+ var { WARN, LOG, DEBUG, VERBOSE, ERROR } = _src.Logger.setup(_src.Logger.INFO, { prefix: "[q]" });
36
+ var QueryNode = class {
37
+ constructor(logsOfThisNode, variables, prev = null) {
38
+ this.logsOfThisNode = logsOfThisNode;
39
+ this.variables = variables;
40
+ this.prev = prev;
41
+ _mobx.makeObservable.call(void 0, this, {
42
+ allApplogs: _mobx.computed
43
+ // ? intuitively only put the ones here that felt expensive to compute (join)
44
+ });
45
+ }
46
+ get record() {
47
+ return this.variables;
48
+ }
49
+ get allApplogs() {
50
+ if (!this.prev)
51
+ return this.logsOfThisNode;
52
+ return joinStreams([
53
+ this.logsOfThisNode,
54
+ this.prev.allApplogs
55
+ ]);
56
+ }
57
+ };
58
+ var QueryNodes = class {
59
+ constructor(nodes) {
60
+ this.nodes = nodes;
61
+ _mobx.makeObservable.call(void 0, this, {
62
+ allApplogs: _mobx.computed,
63
+ // ? intuitively only put the ones here that felt expensive to compute (join)
64
+ size: _mobx.computed,
65
+ // ... or cheap to cache
66
+ isEmpty: _mobx.computed
67
+ });
68
+ }
69
+ get size() {
70
+ return this.records.length;
71
+ }
72
+ get isEmpty() {
73
+ return this.records.length === 0;
74
+ }
75
+ get untrackedSize() {
76
+ return _mobx.untracked.call(void 0, () => this.records.length);
77
+ }
78
+ get records() {
79
+ return this.nodes.map(({ variables }) => variables);
80
+ }
81
+ get applogSets() {
82
+ return this.nodes.map(({ logsOfThisNode: stream }) => stream.applogs);
83
+ }
84
+ get applogStreams() {
85
+ return this.nodes.map(({ logsOfThisNode: stream }) => stream);
86
+ }
87
+ get allApplogs() {
88
+ return joinStreams(this.nodes.map((node) => node.allApplogs));
89
+ }
90
+ };
91
+ var withoutHistory = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function withoutHistory2(stream, { inverseToOnlyReturnFirstLogs, tolerateAlreadyFiltered } = {}) {
92
+ VERBOSE(`withoutHistory${inverseToOnlyReturnFirstLogs ? ".inversed" : ""} < ${stream.nameAndSizeUntracked} > initializing`);
93
+ if (stream.filters.includes("withoutHistory")) {
94
+ if (tolerateAlreadyFiltered) {
95
+ DEBUG(`[withoutHistory] already filtered, but tolerateAlreadyFiltered=true, so returning`);
96
+ return stream;
97
+ }
98
+ throw ERROR(`stream already filtered withoutHistory:`, stream.filters, { name: stream.name });
99
+ }
100
+ let rollingMap;
101
+ const mappedStream = _chunkMS4K4RCZcjs.rollingMapper.call(void 0, stream, function(event, sourceStream) {
102
+ const isInitial = _chunkMS4K4RCZcjs.isInitEvent.call(void 0, event);
103
+ let newLogs;
104
+ const toAdd = [];
105
+ const toRemove = isInitial ? null : [];
106
+ if (isInitial) {
107
+ rollingMap = /* @__PURE__ */ new Map();
108
+ newLogs = event.init;
109
+ } else {
110
+ newLogs = event.added;
111
+ }
112
+ let tsCheck;
113
+ for (let i = inverseToOnlyReturnFirstLogs ? 0 : newLogs.length - 1; inverseToOnlyReturnFirstLogs ? i < newLogs.length : i >= 0; inverseToOnlyReturnFirstLogs ? i++ : i--) {
114
+ const log = newLogs[i];
115
+ const key = _safestablestringify2.default.call(void 0, [log.en, log.at]);
116
+ if (tsCheck && (inverseToOnlyReturnFirstLogs ? tsCheck > log.ts : tsCheck < log.ts)) {
117
+ throw ERROR(`withoutHistory.mapper logs not sorted:`, tsCheck, inverseToOnlyReturnFirstLogs ? ">" : "<", log.ts, {
118
+ log,
119
+ i,
120
+ newLogs,
121
+ inverseToOnlyReturnFirstLogs
122
+ });
123
+ }
124
+ tsCheck = log.ts;
125
+ const existing = rollingMap.get(key);
126
+ if (!existing || (inverseToOnlyReturnFirstLogs ? existing.ts > log.ts : existing.ts < log.ts)) {
127
+ if (existing && !isInitial)
128
+ toRemove.push(existing);
129
+ toAdd.push(log);
130
+ rollingMap.set(key, log);
131
+ }
132
+ }
133
+ _chunkMS4K4RCZcjs.sortApplogsByTs.call(void 0, toAdd);
134
+ VERBOSE.isDisabled || VERBOSE(
135
+ `withoutHistory${inverseToOnlyReturnFirstLogs ? ".inversed" : ""}<${stream.nameAndSizeUntracked}> mapped event`,
136
+ isInitial ? { ...Object.fromEntries(Object.entries(event).map(([k, v]) => [k, _optionalChain([v, 'optionalAccess', _ => _.length])])), toAdd: toAdd.length, toRemove } : { ...event, toAdd, toRemove }
137
+ );
138
+ return isInitial ? { init: toAdd } : { added: toAdd, removed: toRemove };
139
+ }, { name: `withoutHistory${inverseToOnlyReturnFirstLogs ? ".inversed" : ""}`, extraFilterName: "withoutHistory" });
140
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => {
141
+ VERBOSE(`withoutHistory<${stream.nameAndSizeUntracked}> filtered down to`, mappedStream.applogs.length);
142
+ });
143
+ return mappedStream;
144
+ }, { equals: _chunkMS4K4RCZcjs.applogStreamComparer });
145
+ var withoutDeleted = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function withoutDeleted2(stream) {
146
+ VERBOSE(`withoutDeleted<${stream.nameAndSizeUntracked}>`);
147
+ if (stream.filters.includes("withoutDeleted")) {
148
+ throw ERROR(`stream already filtered withoutDeleted:`, stream.filters, { name: stream.name });
149
+ }
150
+ const deletionLogs = _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, { at: ["isDeleted", "relation/isDeleted", "block/isDeleted"], vl: true }, {
151
+ name: "isDeleted"
152
+ });
153
+ VERBOSE(`withoutDeleted<${stream.nameAndSizeUntracked}> deletionLogs:`, _mobx.untracked.call(void 0, () => [...deletionLogs.applogs]));
154
+ const obsArrMapName = _chunkMS4K4RCZcjs.createDebugName.call(void 0, { caller: "allDeletedEntities", stream });
155
+ const deleted = _chunkMS4K4RCZcjs.observableArrayMap.call(void 0, () => deletionLogs.map((log) => log.en), { name: obsArrMapName });
156
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => {
157
+ VERBOSE(`withoutDeleted<${stream.nameAndSizeUntracked}> deleted:`, [...deleted]);
158
+ });
159
+ return _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, { "!en": deleted }, { name: `withoutDeleted`, extraFilterName: "withoutDeleted" });
160
+ }, { equals: _chunkMS4K4RCZcjs.applogStreamComparer });
161
+ var query = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function query2(stream, patternOrPatterns, startVariables = {}, opts = {}) {
162
+ DEBUG(`query<${stream.nameAndSizeUntracked}>:`, patternOrPatterns);
163
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
164
+ let nodes;
165
+ if (patterns.length === 1) {
166
+ nodes = null;
167
+ } else {
168
+ const pattersExceptLast = patterns.slice(0, -1);
169
+ nodes = query2(stream, pattersExceptLast, startVariables, opts);
170
+ }
171
+ const lastPattern = patterns[patterns.length - 1];
172
+ const stepResult = queryStep(stream, nodes, lastPattern, opts);
173
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => VERBOSE(`query result:`, _mobx.toJS.call(void 0, stepResult)));
174
+ return stepResult;
175
+ }, { equals: _chunkMS4K4RCZcjs.queryNodesComparer });
176
+ var queryStep = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function queryStep2(stream, nodeSet, pattern, opts = {}) {
177
+ DEBUG(`queryStep<${stream.nameAndSizeUntracked}> with`, _nullishCoalesce(_optionalChain([nodeSet, 'optionalAccess', _2 => _2.untrackedSize]), () => ( "all")), "nodes, pattern:", pattern);
178
+ if (!Object.entries(pattern).length)
179
+ throw new Error(`Pattern is empty`);
180
+ const observableResultNodes = _chunkMS4K4RCZcjs.observableArrayMap.call(void 0,
181
+ () => {
182
+ function doQuery(node) {
183
+ const [patternWithResolvedVars, variablesToFill] = _chunkMS4K4RCZcjs.resolveOrRemoveVariables.call(void 0, pattern, _nullishCoalesce(_optionalChain([node, 'optionalAccess', _3 => _3.variables]), () => ( {})));
184
+ VERBOSE(`[queryStep] patternWithoutVars: `, patternWithResolvedVars);
185
+ const applogsMatchingStatic = _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, patternWithResolvedVars);
186
+ const varMapper = mapTo(variablesToFill);
187
+ const newVarsAndTheirLog = applogsMatchingStatic.map((log) => ({ log, vars: varMapper(log) }));
188
+ VERBOSE.isDisabled || VERBOSE(
189
+ `[queryStep] step node:`,
190
+ _optionalChain([node, 'optionalAccess', _4 => _4.variables]),
191
+ " =>",
192
+ newVarsAndTheirLog,
193
+ "from:",
194
+ _mobx.untracked.call(void 0, () => applogsMatchingStatic.applogs)
195
+ );
196
+ const resultNodes = newVarsAndTheirLog.map(({ log, vars }) => {
197
+ const nodeVars = Object.assign({}, _optionalChain([node, 'optionalAccess', _5 => _5.variables]), vars);
198
+ return new QueryNode(
199
+ new ApplogStreamInMemory(
200
+ [log],
201
+ stream.filters,
202
+ _chunkMS4K4RCZcjs.createDebugName.call(void 0, {
203
+ caller: "QueryNode",
204
+ stream: applogsMatchingStatic,
205
+ pattern: `${_safestablestringify2.default.call(void 0, nodeVars)}@${_safestablestringify2.default.call(void 0, patternWithResolvedVars)}`
206
+ }),
207
+ true,
208
+ applogsMatchingStatic
209
+ ),
210
+ nodeVars,
211
+ node
212
+ );
213
+ });
214
+ if (opts.debug) {
215
+ LOG(
216
+ `[queryStep] step result:`,
217
+ _mobx.untracked.call(void 0,
218
+ () => resultNodes.map(({ variables, logsOfThisNode: stream2 }) => ({
219
+ variables,
220
+ stream: (
221
+ /* util.inspect( */
222
+ stream2.applogs
223
+ )
224
+ /* , { showHidden: false, depth: null }) */
225
+ }))
226
+ )
227
+ );
228
+ }
229
+ return resultNodes;
230
+ }
231
+ if (nodeSet) {
232
+ return nodeSet.nodes.flatMap(doQuery);
233
+ } else {
234
+ return doQuery(null);
235
+ }
236
+ },
237
+ { name: _chunkMS4K4RCZcjs.createDebugName.call(void 0, { caller: "queryStep", stream, pattern }) }
238
+ );
239
+ VERBOSE(`queryStep result:`, observableResultNodes);
240
+ return new QueryNodes(observableResultNodes);
241
+ }, { equals: _chunkMS4K4RCZcjs.queryNodesComparer });
242
+ var queryNot = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function queryNot2(stream, startNodes, patternOrPatterns, opts = {}) {
243
+ let nodes = startNodes.nodes;
244
+ DEBUG(`queryNot<${stream.nameAndSizeUntracked}> from: ${nodes.length} nodes`);
245
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
246
+ for (const pattern of patterns) {
247
+ if (!Object.entries(patternOrPatterns).length)
248
+ throw new Error(`Pattern is empty`);
249
+ nodes = nodes.filter(({
250
+ /* applogs, */
251
+ variables
252
+ }) => {
253
+ const [patternWithResolvedVars, _variablesToFill] = _chunkMS4K4RCZcjs.resolveOrRemoveVariables.call(void 0, pattern, _nullishCoalesce(variables, () => ( {})));
254
+ VERBOSE(`[queryNot] patternWithoutVars: `, patternWithResolvedVars);
255
+ const newApplogs = _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, patternWithResolvedVars);
256
+ VERBOSE(`[queryNot] step node:`, variables, " =>", newApplogs.size, "applogs");
257
+ VERBOSE.isDisabled || VERBOSE(`[queryNot] step node:`, variables, " => empty?", _mobx.untracked.call(void 0, () => newApplogs.applogs));
258
+ if (opts.debug)
259
+ LOG(`[queryNot] node result:`, variables, "=>", newApplogs.applogs);
260
+ return newApplogs.isEmpty;
261
+ });
262
+ }
263
+ return new QueryNodes(nodes);
264
+ }, { equals: _chunkMS4K4RCZcjs.queryNodesComparer });
265
+ var filterAndMap = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function filterAndMap2(stream, pattern, mapper) {
266
+ DEBUG(`filterAndMap<${stream.nameAndSizeUntracked}>`, pattern);
267
+ const filtered = _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, pattern);
268
+ VERBOSE(`[filterAndMap] filtered:`, filtered.untrackedSize);
269
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => VERBOSE(`[filterAndMap] filtered:`, filtered.applogs));
270
+ const mapperFX = function filterAndMapGetterFx() {
271
+ if (typeof mapper === "function") {
272
+ return filtered.map(mapper);
273
+ } else if (typeof mapper === "string") {
274
+ return filtered.map((log) => log[mapper]);
275
+ } else {
276
+ return filtered.map(mapTo(mapper));
277
+ }
278
+ };
279
+ const name = _chunkMS4K4RCZcjs.createDebugName.call(void 0, { stream, pattern, caller: "filterAndMap" });
280
+ const mapped = _chunkMS4K4RCZcjs.observableArrayMap.call(void 0, mapperFX, { name });
281
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => VERBOSE(`[filterAndMap] mapped:`, mapped));
282
+ return mapped;
283
+ }, { equals: _mobx.comparer.structural });
284
+ var queryAndMap = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function queryAndMap2(stream, patternOrPatterns, map, variables = {}) {
285
+ DEBUG(`queryAndMap<${stream.nameAndSizeUntracked}>`, { patternOrPatterns, variables, map });
286
+ const debugName = _chunkMS4K4RCZcjs.createDebugName.call(void 0, { stream, caller: "queryAndMap" });
287
+ const filtered = query(stream, patternOrPatterns);
288
+ VERBOSE(`[queryAndMap] filtered count:`, filtered.untrackedSize);
289
+ const mapped = _chunkMS4K4RCZcjs.observableArrayMap.call(void 0,
290
+ () => {
291
+ if (typeof map === "function") {
292
+ return filtered.records.map(map);
293
+ } else if (typeof map === "string") {
294
+ return filtered.records.map((log) => log[map]);
295
+ } else {
296
+ throw new Error("what's this map param about?");
297
+ }
298
+ },
299
+ { name: debugName }
300
+ );
301
+ VERBOSE.isDisabled || _mobx.autorun.call(void 0, () => VERBOSE(`[queryAndMap] result:`, _mobx.toJS.call(void 0, mapped)));
302
+ return mapped;
303
+ }, { equals: _mobx.comparer.structural });
304
+ var queryEntity = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function queryEntity2(stream, name, entityID, attributes) {
305
+ DEBUG(`queryEntity<${stream.nameAndSizeUntracked}>`, entityID, name);
306
+ const filtered = _chunkMS4K4RCZcjs.rollingFilter.call(void 0, stream, { en: entityID, at: prefixAttrs(name, attributes) });
307
+ VERBOSE(`queryEntity applogs:`, filtered.applogs);
308
+ return _mobx.computed.call(void 0,
309
+ () => filtered.isEmpty ? null : Object.fromEntries(
310
+ filtered.map(({ at, vl }) => [at.slice(name.length + 1), vl])
311
+ )
312
+ );
313
+ }, { equals: _chunkMS4K4RCZcjs.computedStructuralComparer });
314
+ var agentsOfStream = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function agentsOfStream2(stream) {
315
+ LOG(`agentsOfStream<${stream.nameAndSizeUntracked}>`);
316
+ const mapped = _mobx.observable.map();
317
+ function onEvent(event) {
318
+ for (const log of _chunkMS4K4RCZcjs.isInitEvent.call(void 0, event) ? event.init : event.added) {
319
+ const prev = _nullishCoalesce(mapped.get(log.ag), () => ( 0));
320
+ mapped.set(log.ag, prev + 1);
321
+ }
322
+ for (const log of !_chunkMS4K4RCZcjs.isInitEvent.call(void 0, event) && event.removed || []) {
323
+ const prev = mapped.get(log.ag);
324
+ if (!prev || prev < 1)
325
+ throw ERROR(`[agentsOfStream] number is now negative`, { log, event, mapped, prev });
326
+ mapped.set(log.ag, prev - 1);
327
+ }
328
+ LOG(`agentsOfStream<${stream.nameAndSizeUntracked}> processed event`, { event, mapped });
329
+ }
330
+ _mobx.untracked.call(void 0, () => onEvent({ init: stream.applogs }));
331
+ stream.subscribe(onEvent);
332
+ _mobx.onBecomeObserved.call(void 0, mapped, () => stream.unsubscribe(onEvent));
333
+ return mapped;
334
+ });
335
+ var entityOverlap = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function entityOverlapCount(streamA, streamB) {
336
+ LOG(`entityOverlap<${streamA.nameAndSizeUntracked}, ${streamB.nameAndSizeUntracked}>`);
337
+ return _mobx.computed.call(void 0, () => {
338
+ const entitiesA = new Set(streamA.map((log) => log.en));
339
+ const entitiesB = new Set(streamB.map((log) => log.en));
340
+ return [...entitiesA].filter((en) => entitiesB.has(en));
341
+ });
342
+ });
343
+ var entityOverlapCount2 = _chunkMS4K4RCZcjs.computedFnDeepCompare.call(void 0, function entityOverlapCount3(streamA, streamB) {
344
+ return _mobx.computed.call(void 0, () => entityOverlap(streamA, streamB).get().length);
345
+ });
346
+ function mapTo(applogFieldMap) {
347
+ return (applog) => {
348
+ return Object.entries(applogFieldMap).reduce((acc, [key, value]) => {
349
+ acc[value] = applog[key];
350
+ return acc;
351
+ }, {});
352
+ };
353
+ }
354
+ function startsWith(str) {
355
+ return (value) => value.startsWith(str);
356
+ }
357
+ function prefixAttrs(prefix, attrs) {
358
+ return attrs.map((at) => prefixAt(prefix, at));
359
+ }
360
+ function prefixAt(prefix, attr) {
361
+ return `${prefix}/${attr}`;
362
+ }
363
+
364
+ // src/data/applog-helpers.ts
365
+ var { WARN: WARN2, LOG: LOG2, DEBUG: DEBUG2, VERBOSE: VERBOSE2, ERROR: ERROR2 } = _src.Logger.setup(_src.Logger.INFO);
366
+ var sortApplogByTs = (p, n) => p.ts < n.ts ? -1 : p.ts > n.ts ? 1 : 0;
367
+ var sortApplogByTsDec = (p, n) => p.ts < n.ts ? 1 : p.ts > n.ts ? -1 : 0;
368
+ function filterOnlyLatest(logs, onlyLatest) {
369
+ if (!onlyLatest || !_optionalChain([logs, 'optionalAccess', _6 => _6.length])) {
370
+ return logs;
371
+ }
372
+ logs = [...logs].sort((a, b) => a.ts < b.ts ? -1 : a.ts == b.ts ? 0 : 1);
373
+ const mapped = /* @__PURE__ */ new Map();
374
+ for (const log of logs) {
375
+ if (!log) {
376
+ continue;
377
+ }
378
+ mapped.set(JSON.stringify([log.en, log.at]), log);
379
+ }
380
+ return [...mapped.values()];
381
+ }
382
+ function hasAg(log) {
383
+ return !!log.ag;
384
+ }
385
+ function hasTs(log) {
386
+ return !!log.ts;
387
+ }
388
+ function hasPv(log) {
389
+ return !!log.pv;
390
+ }
391
+ function withTs(log, ts) {
392
+ return hasTs(log) ? log : { ...log, ts };
393
+ }
394
+ function withPv(log, ds) {
395
+ const { en, at } = log;
396
+ const pvs = filterAndMap(withoutHistory(ds), { en, at }, "cid");
397
+ if (pvs.length > 1)
398
+ WARN2(`[withPv] unexpected result count:`, pvs.length);
399
+ let pv = pvs.length ? pvs[0] : null;
400
+ const isMatchingPv = !!(pv === log.pv);
401
+ if (log.pv && !isMatchingPv)
402
+ WARN2(`[withPv] different than pre-set pv:`, { queriedPv: pv, logPv: log.pv });
403
+ pv = _nullishCoalesce(log.pv, () => ( pv));
404
+ return { ...log, pv: _nullishCoalesce(pv, () => ( null)) };
405
+ }
406
+ function joinStreams(streams) {
407
+ if (streams.length === 0)
408
+ throw ERROR2(`joinStreams called with empty array`);
409
+ if (streams.length === 1)
410
+ return streams[0];
411
+ const fullJoin = () => _chunkMS4K4RCZcjs.sortApplogsByTs.call(void 0,
412
+ _chunkMS4K4RCZcjs.removeDuplicateAppLogs.call(void 0, streams.flatMap((s) => {
413
+ const logs = s.applogs;
414
+ if (!logs) {
415
+ ERROR2(`falsy applogs of stream`, s);
416
+ throw new Error(`falsy applogs of stream`);
417
+ }
418
+ return logs;
419
+ }))
420
+ );
421
+ const initialMergeResult = _mobx.untracked.call(void 0, () => fullJoin());
422
+ const eventMapper = _mobx.action.call(void 0, function(event, sourceStream) {
423
+ if (_chunkMS4K4RCZcjs.isInitEvent.call(void 0, event)) {
424
+ return { init: _mobx.untracked.call(void 0, () => fullJoin()) };
425
+ } else {
426
+ return {
427
+ // TODO: test this stuff
428
+ added: event.added.filter((addedLog) => !this.hasApplog(addedLog, true)),
429
+ removed: event.added.filter(
430
+ (addedLog) => !this.parents.some((parent) => {
431
+ if (parent === sourceStream)
432
+ return false;
433
+ return parent.hasApplog(addedLog, true);
434
+ })
435
+ )
436
+ };
437
+ }
438
+ });
439
+ return new (0, _chunkMS4K4RCZcjs.MappedApplogStream)(streams, ["?"], initialMergeResult, eventMapper, `join(${streams.map((s) => s.name).join(", ")})`);
440
+ }
441
+
442
+ // src/data/datom-types.ts
443
+ var _typebox = require('@sinclair/typebox');
444
+ var _compiler = require('@sinclair/typebox/compiler');
445
+ var Nullable = (schema) => _typebox.Type.Union([schema, _typebox.Type.Null()]);
446
+ var EntityID_LENGTH = 7;
447
+ var isCID = /^(k51qz|baguq)[0-9a-z]{56,57}$/;
448
+ var isShortHash = /^[0-9A-Fa-f]{7,8}$/g;
449
+ _typebox.FormatRegistry.Set("EntityID", (value) => !!value.match(isShortHash) || !!value.match(isCID));
450
+ var EntityID = _typebox.Type.String({ format: "EntityID" });
451
+ _typebox.FormatRegistry.Set("CID", (value) => !!value.match(isCID));
452
+ var CIDTB = _typebox.Type.String({ format: "EntityID" });
453
+ var isURL = /^http([s]?):\/\/.*\..*/;
454
+ _typebox.FormatRegistry.Set("URL", (value) => !!value.match(isURL));
455
+ var URL = _typebox.Type.String({ format: "URL" });
456
+ var AppLogTB = _typebox.Type.Object({
457
+ en: EntityID,
458
+ // EntityID
459
+ at: _typebox.Type.String(),
460
+ // Attribute
461
+ vl: Nullable(_typebox.Type.Union([_typebox.Type.String(), _typebox.Type.Boolean(), _typebox.Type.Number()])),
462
+ // TODO refactor to semantic typesafe ApplogValue
463
+ ts: _typebox.Type.String(),
464
+ // Timestamp
465
+ ag: _typebox.Type.String()
466
+ // AgentHash
467
+ });
468
+ var AppLogTBC = _compiler.TypeCompiler.Compile(AppLogTB);
469
+ var getApplogTypeErrors = (obj) => Array.from(AppLogTBC.Errors(obj));
470
+ var isValidApplog = AppLogTBC.Check.bind(AppLogTBC);
471
+
472
+ // src/stream/writeable.ts
473
+ var { WARN: WARN3, LOG: LOG3, DEBUG: DEBUG3, VERBOSE: VERBOSE3, ERROR: ERROR3 } = _src.Logger.setup(_src.Logger.INFO);
474
+ var WriteableApplogStream = class extends _chunkMS4K4RCZcjs.ApplogStream {
475
+ constructor(parents, filters, applogs = [], name) {
476
+ super(parents, filters, applogs, name);
477
+ _mobx.makeObservable.call(void 0, this, {
478
+ insert: _mobx.action
479
+ // ? is there an advantage to do this here instead of wrapping the fx in action below?
480
+ });
481
+ }
482
+ insert(appLogsToInsert) {
483
+ const ts = _chunkMS4K4RCZcjs.dateNowIso.call(void 0, );
484
+ const mapped = appLogsToInsert.map((log) => {
485
+ const logWithTs = withTs(log, ts);
486
+ if (!isValidApplog(logWithTs)) {
487
+ throw ERROR3(`Bogus Applog ${JSON.stringify(logWithTs)}`, getApplogTypeErrors(logWithTs));
488
+ }
489
+ const logWithPv = withPv(logWithTs, this);
490
+ const cid = _chunkMLDNHGG3cjs.encodeApplogAndGetCid.call(void 0, logWithPv).toString();
491
+ const logWithCid = { ...logWithPv, cid };
492
+ return Object.freeze(logWithCid);
493
+ });
494
+ const mappedLogs = _chunkMS4K4RCZcjs.removeDuplicateAppLogs.call(void 0, mapped);
495
+ if (appLogsToInsert.length !== mappedLogs.length) {
496
+ WARN3("request to insert duplicate log, inserting mappedLogs:", { appLogsToInsert, mappedLogs });
497
+ } else if (!appLogsToInsert.length) {
498
+ WARN3("request to insert empty logs array");
499
+ } else {
500
+ LOG3("Inserting:", mappedLogs.length === 1 ? mappedLogs[0] : mappedLogs, { ds: this });
501
+ }
502
+ if (!mappedLogs.length)
503
+ return [];
504
+ _chunkMS4K4RCZcjs.sortApplogsByTs.call(void 0, mappedLogs);
505
+ const sortNeeded = this._applogs.length && _chunkMS4K4RCZcjs.isTsBefore.call(void 0, mappedLogs[0], this._applogs[this._applogs.length - 1]);
506
+ this._applogs.push(...mappedLogs);
507
+ if (sortNeeded) {
508
+ _chunkMS4K4RCZcjs.sortApplogsByTs.call(void 0, this._applogs);
509
+ }
510
+ this.notifySubscribers({ added: mappedLogs, removed: null });
511
+ void this.persist(mappedLogs);
512
+ return mappedLogs;
513
+ }
514
+ get readOnly() {
515
+ return false;
516
+ }
517
+ };
518
+ var ApplogStreamInMemory = class extends WriteableApplogStream {
519
+ constructor(applogs, filters, name, _readOnly, parents = null) {
520
+ super(parents, filters, applogs, name);
521
+ this._readOnly = _readOnly;
522
+ _mobx.makeObservable.call(void 0, this, {
523
+ // @ts-expect-error bc it's private
524
+ _applogs: _mobx.observable.shallow
525
+ });
526
+ }
527
+ get readOnly() {
528
+ return this._readOnly;
529
+ }
530
+ persist(logs) {
531
+ VERBOSE3(`[InMem.persist] no persist for`, logs);
532
+ if (this.readOnly) {
533
+ throw ERROR3(`[persist] called for readOnly stream`);
534
+ }
535
+ }
536
+ };
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+ exports.Nullable = Nullable; exports.EntityID_LENGTH = EntityID_LENGTH; exports.EntityID = EntityID; exports.CIDTB = CIDTB; exports.URL = URL; exports.AppLogTB = AppLogTB; exports.AppLogTBC = AppLogTBC; exports.getApplogTypeErrors = getApplogTypeErrors; exports.isValidApplog = isValidApplog; exports.WriteableApplogStream = WriteableApplogStream; exports.ApplogStreamInMemory = ApplogStreamInMemory; exports.QueryNode = QueryNode; exports.QueryNodes = QueryNodes; exports.withoutHistory = withoutHistory; exports.withoutDeleted = withoutDeleted; exports.query = query; exports.queryStep = queryStep; exports.queryNot = queryNot; exports.filterAndMap = filterAndMap; exports.queryAndMap = queryAndMap; exports.queryEntity = queryEntity; exports.agentsOfStream = agentsOfStream; exports.entityOverlap = entityOverlap; exports.entityOverlapCount = entityOverlapCount2; exports.mapTo = mapTo; exports.startsWith = startsWith; exports.prefixAttrs = prefixAttrs; exports.prefixAt = prefixAt; exports.sortApplogByTs = sortApplogByTs; exports.sortApplogByTsDec = sortApplogByTsDec; exports.filterOnlyLatest = filterOnlyLatest; exports.hasAg = hasAg; exports.hasTs = hasTs; exports.hasPv = hasPv; exports.withTs = withTs; exports.withPv = withPv; exports.joinStreams = joinStreams;
577
+ //# sourceMappingURL=chunk-LR7LTEQ6.cjs.map