@wovin/core 0.1.36 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +0 -12
  2. package/dist/applog/applog-helpers.d.ts +12 -12
  3. package/dist/applog/applog-helpers.d.ts.map +1 -1
  4. package/dist/applog/applog-utils.d.ts +25 -6
  5. package/dist/applog/applog-utils.d.ts.map +1 -1
  6. package/dist/applog/datom-types.d.ts +4 -5
  7. package/dist/applog/datom-types.d.ts.map +1 -1
  8. package/dist/applog.d.ts +3 -3
  9. package/dist/applog.d.ts.map +1 -1
  10. package/dist/{applog.min.js → applog.js} +6 -7
  11. package/dist/blockstore.d.ts +1 -1
  12. package/dist/blockstore.d.ts.map +1 -1
  13. package/dist/{blockstore.min.js → blockstore.js} +1 -3
  14. package/dist/{blockstore.min.js.map → blockstore.js.map} +1 -1
  15. package/dist/{chunk-KXMTKPF4.min.js → chunk-3JZMOEOD.js} +8 -8
  16. package/dist/chunk-3JZMOEOD.js.map +1 -0
  17. package/dist/chunk-3WZVG277.js +434 -0
  18. package/dist/chunk-3WZVG277.js.map +1 -0
  19. package/dist/chunk-7Z5YDQKK.js +1 -0
  20. package/dist/chunk-CPSDKFBG.js +147 -0
  21. package/dist/chunk-CPSDKFBG.js.map +1 -0
  22. package/dist/chunk-E46VTKTZ.js +1 -0
  23. package/dist/{chunk-H3VQJP56.min.js → chunk-J2FDHGOZ.js} +9 -9
  24. package/dist/chunk-J2FDHGOZ.js.map +1 -0
  25. package/dist/chunk-L5EEEGE6.js +1862 -0
  26. package/dist/chunk-L5EEEGE6.js.map +1 -0
  27. package/dist/{chunk-BRC7LSM6.min.js → chunk-PD3C7XUM.js} +5 -5
  28. package/dist/chunk-PD3C7XUM.js.map +1 -0
  29. package/dist/chunk-QZXKQCAY.js +1026 -0
  30. package/dist/chunk-QZXKQCAY.js.map +1 -0
  31. package/dist/{chunk-QPGEBDMJ.min.js → chunk-YDAKBU6Q.js} +1 -1
  32. package/dist/chunk-YDAKBU6Q.js.map +1 -0
  33. package/dist/chunk-ZAADLBSB.js +36 -0
  34. package/dist/chunk-ZAADLBSB.js.map +1 -0
  35. package/dist/index.d.ts +7 -7
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/{index.min.js → index.js} +73 -46
  38. package/dist/ipfs/car.d.ts +11 -11
  39. package/dist/ipfs/car.d.ts.map +1 -1
  40. package/dist/ipfs/ipfs-utils.d.ts +2 -2
  41. package/dist/ipfs/ipfs-utils.d.ts.map +1 -1
  42. package/dist/ipfs.d.ts +3 -3
  43. package/dist/ipfs.d.ts.map +1 -1
  44. package/dist/{ipfs.min.js → ipfs.js} +7 -10
  45. package/dist/ipns.d.ts +1 -1
  46. package/dist/ipns.d.ts.map +1 -1
  47. package/dist/ipns.js +64 -0
  48. package/dist/ipns.js.map +1 -0
  49. package/dist/pubsub/pub-pull.d.ts +3 -3
  50. package/dist/pubsub/pub-pull.d.ts.map +1 -1
  51. package/dist/pubsub/pubsub-types.d.ts +3 -3
  52. package/dist/pubsub/pubsub-types.d.ts.map +1 -1
  53. package/dist/pubsub/snap-push.d.ts +4 -4
  54. package/dist/pubsub/snap-push.d.ts.map +1 -1
  55. package/dist/pubsub/ucan.d.ts +1 -1
  56. package/dist/pubsub/ucan.d.ts.map +1 -1
  57. package/dist/pubsub.d.ts +4 -4
  58. package/dist/pubsub.d.ts.map +1 -1
  59. package/dist/{pubsub.min.js → pubsub.js} +7 -10
  60. package/dist/query/attr-helpers.d.ts +5 -0
  61. package/dist/query/attr-helpers.d.ts.map +1 -0
  62. package/dist/query/basic.d.ts +85 -21
  63. package/dist/query/basic.d.ts.map +1 -1
  64. package/dist/query/divergences.d.ts +5 -5
  65. package/dist/query/divergences.d.ts.map +1 -1
  66. package/dist/query/entity-collection.d.ts +19 -0
  67. package/dist/query/entity-collection.d.ts.map +1 -0
  68. package/dist/query/matchers.d.ts +1 -1
  69. package/dist/query/matchers.d.ts.map +1 -1
  70. package/dist/query/memoized.d.ts +66 -0
  71. package/dist/query/memoized.d.ts.map +1 -0
  72. package/dist/query/situations.d.ts +2 -1
  73. package/dist/query/situations.d.ts.map +1 -1
  74. package/dist/query/subscribable.d.ts +111 -0
  75. package/dist/query/subscribable.d.ts.map +1 -0
  76. package/dist/query/types.d.ts +54 -14
  77. package/dist/query/types.d.ts.map +1 -1
  78. package/dist/query.d.ts +9 -5
  79. package/dist/query.d.ts.map +1 -1
  80. package/dist/{query.min.js → query.js} +51 -32
  81. package/dist/retrieve/index.d.ts +1 -1
  82. package/dist/retrieve/index.d.ts.map +1 -1
  83. package/dist/retrieve/update-thread.d.ts +3 -3
  84. package/dist/retrieve/update-thread.d.ts.map +1 -1
  85. package/dist/retrieve.d.ts +1 -1
  86. package/dist/retrieve.d.ts.map +1 -1
  87. package/dist/retrieve.js +14 -0
  88. package/dist/thread/basic.d.ts +15 -19
  89. package/dist/thread/basic.d.ts.map +1 -1
  90. package/dist/thread/filters.d.ts +8 -10
  91. package/dist/thread/filters.d.ts.map +1 -1
  92. package/dist/thread/indexes.d.ts +56 -0
  93. package/dist/thread/indexes.d.ts.map +1 -0
  94. package/dist/thread/mapped.d.ts +40 -11
  95. package/dist/thread/mapped.d.ts.map +1 -1
  96. package/dist/thread/utils.d.ts +5 -5
  97. package/dist/thread/utils.d.ts.map +1 -1
  98. package/dist/thread/writeable.d.ts +2 -2
  99. package/dist/thread/writeable.d.ts.map +1 -1
  100. package/dist/thread.d.ts +6 -5
  101. package/dist/thread.d.ts.map +1 -1
  102. package/dist/{thread.min.js → thread.js} +9 -6
  103. package/dist/types/typescript-utils.d.ts +6 -5
  104. package/dist/types/typescript-utils.d.ts.map +1 -1
  105. package/dist/types.d.ts +1 -1
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/{types.min.js → types.js} +3 -4
  108. package/dist/utils/debug-name.d.ts +13 -0
  109. package/dist/utils/debug-name.d.ts.map +1 -0
  110. package/dist/utils.d.ts +1 -1
  111. package/dist/utils.d.ts.map +1 -1
  112. package/dist/utils.js +9 -0
  113. package/package.json +32 -23
  114. package/src/applog/applog-helpers.ts +155 -0
  115. package/src/applog/applog-utils.test.ts +108 -0
  116. package/src/applog/applog-utils.ts +507 -0
  117. package/src/applog/datom-types.ts +148 -0
  118. package/src/applog.ts +3 -0
  119. package/src/blockstore/index.ts +36 -0
  120. package/src/blockstore.ts +1 -0
  121. package/src/index.ts +8 -0
  122. package/src/ipfs/car.ts +291 -0
  123. package/src/ipfs/fetch-snapshot-chain.ts +135 -0
  124. package/src/ipfs/ipfs-utils.ts +132 -0
  125. package/src/ipfs.ts +3 -0
  126. package/src/ipns/ipns-record.ts +115 -0
  127. package/src/ipns.ts +1 -0
  128. package/src/pubsub/UCAN Specs Overview.md +217 -0
  129. package/src/pubsub/connector.ts +9 -0
  130. package/src/pubsub/pub-pull.ts +31 -0
  131. package/src/pubsub/pubsub-types.ts +90 -0
  132. package/src/pubsub/snap-push.ts +277 -0
  133. package/src/pubsub/ucan-example.ts +61 -0
  134. package/src/pubsub/ucan.ts +56 -0
  135. package/src/pubsub.ts +4 -0
  136. package/src/query/attr-helpers.ts +5 -0
  137. package/src/query/basic.ts +1245 -0
  138. package/src/query/divergences.ts +50 -0
  139. package/src/query/entity-collection.ts +131 -0
  140. package/src/query/liveFilterAndMap.test.ts +102 -0
  141. package/src/query/matchers.ts +8 -0
  142. package/src/query/memoized.test.ts +151 -0
  143. package/src/query/memoized.ts +180 -0
  144. package/src/query/query-steps.ts +4 -0
  145. package/src/query/query.test.ts +538 -0
  146. package/src/query/situations.ts +261 -0
  147. package/src/query/subscribable.test.ts +245 -0
  148. package/src/query/subscribable.ts +234 -0
  149. package/src/query/types.ts +155 -0
  150. package/src/query/withoutDeleted.test.ts +204 -0
  151. package/src/query.ts +9 -0
  152. package/src/retrieve/index.ts +1 -0
  153. package/src/retrieve/update-thread.ts +248 -0
  154. package/src/retrieve.ts +1 -0
  155. package/src/test/perf/query.1m.perf.test.ts +94 -0
  156. package/src/test/perf/query.perf.test.ts +389 -0
  157. package/src/test/perf/query.realdata.perf.test.ts +182 -0
  158. package/src/thread/basic.ts +209 -0
  159. package/src/thread/filters.ts +227 -0
  160. package/src/thread/indexes.ts +250 -0
  161. package/src/thread/joinThreads.test.ts +304 -0
  162. package/src/thread/mapped.ts +226 -0
  163. package/src/thread/utils.ts +144 -0
  164. package/src/thread/writeable.ts +163 -0
  165. package/src/thread.ts +6 -0
  166. package/src/types/typescript-utils.ts +64 -0
  167. package/src/types.ts +1 -0
  168. package/src/utils/debug-name.ts +54 -0
  169. package/src/utils.ts +4 -0
  170. package/dist/chunk-2Y2PYHGR.min.js +0 -65
  171. package/dist/chunk-2Y2PYHGR.min.js.map +0 -1
  172. package/dist/chunk-5MMGBK2U.min.js +0 -1
  173. package/dist/chunk-7IDQIMQO.min.js +0 -1
  174. package/dist/chunk-BRC7LSM6.min.js.map +0 -1
  175. package/dist/chunk-COXXILXC.min.js +0 -512
  176. package/dist/chunk-COXXILXC.min.js.map +0 -1
  177. package/dist/chunk-GDX2OO7L.min.js +0 -9080
  178. package/dist/chunk-GDX2OO7L.min.js.map +0 -1
  179. package/dist/chunk-H3VQJP56.min.js.map +0 -1
  180. package/dist/chunk-HYMC7W6S.min.js +0 -1549
  181. package/dist/chunk-HYMC7W6S.min.js.map +0 -1
  182. package/dist/chunk-KEHU7HGZ.min.js +0 -5216
  183. package/dist/chunk-KEHU7HGZ.min.js.map +0 -1
  184. package/dist/chunk-KXMTKPF4.min.js.map +0 -1
  185. package/dist/chunk-PHITDXZT.min.js +0 -36
  186. package/dist/chunk-QO2KMGDN.min.js +0 -3771
  187. package/dist/chunk-QO2KMGDN.min.js.map +0 -1
  188. package/dist/chunk-QPGEBDMJ.min.js.map +0 -1
  189. package/dist/chunk-WXLCBTHX.min.js +0 -1606
  190. package/dist/chunk-WXLCBTHX.min.js.map +0 -1
  191. package/dist/ipns.min.js +0 -6419
  192. package/dist/ipns.min.js.map +0 -1
  193. package/dist/mobx/mobx-utils.d.ts +0 -82
  194. package/dist/mobx/mobx-utils.d.ts.map +0 -1
  195. package/dist/mobx.d.ts +0 -2
  196. package/dist/mobx.d.ts.map +0 -1
  197. package/dist/mobx.min.js +0 -141
  198. package/dist/retrieve.min.js +0 -17
  199. package/dist/types.min.js.map +0 -1
  200. package/dist/utils.min.js +0 -10
  201. package/dist/utils.min.js.map +0 -1
  202. /package/dist/{applog.min.js.map → applog.js.map} +0 -0
  203. /package/dist/{chunk-5MMGBK2U.min.js.map → chunk-7Z5YDQKK.js.map} +0 -0
  204. /package/dist/{chunk-7IDQIMQO.min.js.map → chunk-E46VTKTZ.js.map} +0 -0
  205. /package/dist/{chunk-PHITDXZT.min.js.map → index.js.map} +0 -0
  206. /package/dist/{index.min.js.map → ipfs.js.map} +0 -0
  207. /package/dist/{ipfs.min.js.map → pubsub.js.map} +0 -0
  208. /package/dist/{mobx.min.js.map → query.js.map} +0 -0
  209. /package/dist/{pubsub.min.js.map → retrieve.js.map} +0 -0
  210. /package/dist/{query.min.js.map → thread.js.map} +0 -0
  211. /package/dist/{retrieve.min.js.map → types.js.map} +0 -0
  212. /package/dist/{thread.min.js.map → utils.js.map} +0 -0
@@ -0,0 +1,1026 @@
1
+ import {
2
+ StaticThread,
3
+ SubscribableArrayImpl,
4
+ SubscribableImpl,
5
+ ThreadInMemory,
6
+ applogsByEntity,
7
+ createDebugName,
8
+ hasFilter,
9
+ isArrayInitEvent,
10
+ isInitEvent,
11
+ isLaterByTsAndPv,
12
+ isVariable,
13
+ isoDateStrCompare,
14
+ joinThreads,
15
+ makeFilter,
16
+ memoizedFn,
17
+ resolveOrRemoveVariables,
18
+ rollingFilter,
19
+ rollingMapper,
20
+ sortApplogsByTs
21
+ } from "./chunk-L5EEEGE6.js";
22
+
23
+ // src/query/types.ts
24
+ var QueryNode = class {
25
+ constructor(logsOfThisNode, variables, prevNode = null) {
26
+ this.logsOfThisNode = logsOfThisNode;
27
+ this.variables = variables;
28
+ this.prevNode = prevNode;
29
+ }
30
+ get record() {
31
+ return this.variables;
32
+ }
33
+ get threadOfTrail() {
34
+ if (!this.prevNode) return this.logsOfThisNode;
35
+ return joinThreads([
36
+ this.logsOfThisNode,
37
+ this.prevNode.threadOfTrail
38
+ ]);
39
+ }
40
+ get trailLogs() {
41
+ return this.threadOfTrail.applogs;
42
+ }
43
+ };
44
+ var QueryResult = class {
45
+ constructor(nodes) {
46
+ this.nodes = nodes;
47
+ }
48
+ get size() {
49
+ return this.nodes.length;
50
+ }
51
+ get isEmpty() {
52
+ return this.nodes.length === 0;
53
+ }
54
+ get untrackedSize() {
55
+ return this.nodes.length;
56
+ }
57
+ get records() {
58
+ return this.nodes.map(({ variables }) => variables);
59
+ }
60
+ get leafNodeThread() {
61
+ return joinThreads(
62
+ this.nodes.map(({ logsOfThisNode: thread }) => thread)
63
+ );
64
+ }
65
+ get leafNodeLogSet() {
66
+ return this.nodes.map(({ logsOfThisNode: thread }) => thread.applogs);
67
+ }
68
+ get leafNodeLogs() {
69
+ return this.nodes.flatMap(({ logsOfThisNode: thread }) => thread.applogs);
70
+ }
71
+ get threadOfAllTrails() {
72
+ return joinThreads(this.nodes.map((node) => node.threadOfTrail));
73
+ }
74
+ get thread() {
75
+ return this.threadOfAllTrails;
76
+ }
77
+ get allApplogs() {
78
+ return this.threadOfAllTrails.applogs;
79
+ }
80
+ };
81
+ var LiveQueryResult = class {
82
+ constructor(_source, activate = true) {
83
+ this._source = _source;
84
+ if (activate) {
85
+ this._activationUnsub = this._source.subscribe(() => {
86
+ });
87
+ }
88
+ }
89
+ _activationUnsub = null;
90
+ /** Subscribe to node change events. Callback fires on future changes only. */
91
+ subscribe(cb, type) {
92
+ return this._source.subscribe(cb, type);
93
+ }
94
+ /** Current nodes — live view, always up-to-date while not disposed */
95
+ get nodes() {
96
+ return this._source.items;
97
+ }
98
+ get size() {
99
+ return this._source.length;
100
+ }
101
+ get isEmpty() {
102
+ return this._source.length === 0;
103
+ }
104
+ get untrackedSize() {
105
+ return this._source.length;
106
+ }
107
+ get records() {
108
+ return this.nodes.map(({ variables }) => variables);
109
+ }
110
+ get leafNodeThread() {
111
+ return joinThreads(
112
+ this.nodes.map(({ logsOfThisNode: thread }) => thread)
113
+ );
114
+ }
115
+ get leafNodeLogSet() {
116
+ return this.nodes.map(({ logsOfThisNode: thread }) => thread.applogs);
117
+ }
118
+ get leafNodeLogs() {
119
+ return this.nodes.flatMap(({ logsOfThisNode: thread }) => thread.applogs);
120
+ }
121
+ get threadOfAllTrails() {
122
+ return joinThreads(this.nodes.map((node) => node.threadOfTrail));
123
+ }
124
+ get thread() {
125
+ return this.threadOfAllTrails;
126
+ }
127
+ get allApplogs() {
128
+ return this.threadOfAllTrails.applogs;
129
+ }
130
+ dispose() {
131
+ this._activationUnsub?.();
132
+ this._activationUnsub = null;
133
+ this._source.dispose();
134
+ }
135
+ };
136
+
137
+ // src/query/basic.ts
138
+ import { Logger } from "besonders-logger";
139
+ import stringify from "safe-stable-stringify";
140
+ var { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO, { prefix: "[q]" });
141
+ function assertLWW(thread) {
142
+ if (!hasFilter(thread, "lastWriteWins")) {
143
+ throw ERROR(`requires lastWriteWins-filtered thread, got filters:`, thread.filters, { name: thread.name });
144
+ }
145
+ }
146
+ var globalQueryTimeoutTime = null;
147
+ var lastWriteWins = memoizedFn("lastWriteWins", function lastWriteWins2(thread, { inverseToOnlyReturnFirstLogs, tolerateAlreadyFiltered } = {}) {
148
+ VERBOSE(`lastWriteWins${inverseToOnlyReturnFirstLogs ? ".inversed" : ""} < ${thread.nameAndSizeUntracked} > initializing`);
149
+ if (thread.filters.includes("lastWriteWins")) {
150
+ if (tolerateAlreadyFiltered) {
151
+ DEBUG(`[lastWriteWins] already filtered, but tolerateAlreadyFiltered=true, so returning`);
152
+ return thread;
153
+ }
154
+ throw ERROR(`thread already filtered lastWriteWins:`, thread.filters, { name: thread.name });
155
+ }
156
+ let rollingMap;
157
+ const processLogs = (newLogs, toRemove) => {
158
+ const toAdd = [];
159
+ let prevTs;
160
+ for (let i = inverseToOnlyReturnFirstLogs ? 0 : newLogs.length - 1; inverseToOnlyReturnFirstLogs ? i < newLogs.length : i >= 0; inverseToOnlyReturnFirstLogs ? i++ : i--) {
161
+ const log = newLogs[i];
162
+ const key = log.en + "|" + log.at;
163
+ if (prevTs !== void 0) {
164
+ const cmp = isoDateStrCompare(prevTs, log.ts);
165
+ if (inverseToOnlyReturnFirstLogs ? cmp > 0 : cmp < 0) {
166
+ throw ERROR(`lastWriteWins.processLogs logs not ts-sorted:`, prevTs, inverseToOnlyReturnFirstLogs ? ">" : "<", log.ts, {
167
+ log,
168
+ i,
169
+ newLogs,
170
+ inverseToOnlyReturnFirstLogs
171
+ });
172
+ }
173
+ }
174
+ prevTs = log.ts;
175
+ const existing = rollingMap.get(key);
176
+ const replaces = !existing || (inverseToOnlyReturnFirstLogs ? isLaterByTsAndPv(existing, log) : isLaterByTsAndPv(log, existing));
177
+ if (replaces) {
178
+ if (existing && toRemove) toRemove.push(existing);
179
+ toAdd.push(log);
180
+ rollingMap.set(key, log);
181
+ }
182
+ }
183
+ return toAdd;
184
+ };
185
+ const lwwName = `lastWriteWins${inverseToOnlyReturnFirstLogs ? ".inversed" : ""}`;
186
+ const derivation = {
187
+ compute(parents) {
188
+ if (parents.length !== 1) {
189
+ throw ERROR(`${lwwName} requires exactly one parent`, { parents: parents.length });
190
+ }
191
+ const [parent] = parents;
192
+ rollingMap = /* @__PURE__ */ new Map();
193
+ const toAdd = processLogs(parent.applogs, null);
194
+ sortApplogsByTs(toAdd);
195
+ VERBOSE.isDisabled || VERBOSE(`${lwwName}<${thread.nameAndSizeUntracked}> compute`, { toAdd: toAdd.length });
196
+ return toAdd;
197
+ },
198
+ mapDelta(delta) {
199
+ const toRemove = [];
200
+ const toAdd = processLogs(delta.added, toRemove);
201
+ sortApplogsByTs(toAdd);
202
+ VERBOSE.isDisabled || VERBOSE(`${lwwName}<${thread.nameAndSizeUntracked}> mapDelta`, { ...delta, toAdd, toRemove });
203
+ return { added: toAdd, removed: toRemove };
204
+ }
205
+ };
206
+ const mappedThread = rollingMapper(thread, derivation, { name: lwwName, extraFilterName: "lastWriteWins" });
207
+ VERBOSE.isDisabled || VERBOSE(`lastWriteWins<${thread.nameAndSizeUntracked}> filtered down to`, mappedThread.applogs.length);
208
+ return mappedThread;
209
+ }, { argsDebugName: (thread) => createDebugName({ caller: "lastWriteWins", thread }) });
210
+ var isDeletedAttrs = ["isDeleted", "relation/isDeleted", "block/isDeleted"];
211
+ function isDeletionLog(log) {
212
+ return log.vl === true && isDeletedAttrs.includes(log.at);
213
+ }
214
+ var withoutDeleted = memoizedFn("withoutDeleted", function withoutDeleted2(thread) {
215
+ if (VERBOSE.isEnabled) VERBOSE(`withoutDeleted<${thread.nameAndSizeUntracked}>`);
216
+ if (thread.filters.includes("withoutDeleted")) {
217
+ throw ERROR(`thread already filtered withoutDeleted:`, thread.filters, { name: thread.name });
218
+ }
219
+ if (!thread.filters.includes("lastWriteWins")) {
220
+ WARN(`withoutDeleted on non-lastWriteWins thread: un-deletion (isDeleted: false) won't take effect`, { thread: thread.name });
221
+ }
222
+ const byEntity = applogsByEntity(thread);
223
+ const activeDeletionMarkers = /* @__PURE__ */ new Map();
224
+ for (const log of thread.applogs) {
225
+ if (isDeletionLog(log)) {
226
+ activeDeletionMarkers.set(log.en, (activeDeletionMarkers.get(log.en) ?? 0) + 1);
227
+ }
228
+ }
229
+ const isHidden = (en) => activeDeletionMarkers.has(en);
230
+ const derivation = {
231
+ compute(parents) {
232
+ if (parents.length !== 1) throw ERROR(`withoutDeleted requires exactly one parent`, { parents: parents.length });
233
+ const [parent] = parents;
234
+ activeDeletionMarkers.clear();
235
+ for (const log of parent.applogs) {
236
+ if (isDeletionLog(log)) {
237
+ activeDeletionMarkers.set(log.en, (activeDeletionMarkers.get(log.en) ?? 0) + 1);
238
+ }
239
+ }
240
+ return parent.applogs.filter((log) => !isHidden(log.en));
241
+ },
242
+ mapDelta: (delta) => {
243
+ const hiddenBefore = new Set(activeDeletionMarkers.keys());
244
+ const entitiesNowHidden = [];
245
+ const entitiesNowVisible = [];
246
+ for (const log of delta.added) {
247
+ if (!isDeletionLog(log)) continue;
248
+ const prev = activeDeletionMarkers.get(log.en) ?? 0;
249
+ activeDeletionMarkers.set(log.en, prev + 1);
250
+ if (prev === 0) entitiesNowHidden.push(log.en);
251
+ }
252
+ if (delta.removed) {
253
+ for (const log of delta.removed) {
254
+ if (!isDeletionLog(log)) continue;
255
+ const prev = activeDeletionMarkers.get(log.en) ?? 0;
256
+ const next = prev - 1;
257
+ if (next > 0) activeDeletionMarkers.set(log.en, next);
258
+ else {
259
+ activeDeletionMarkers.delete(log.en);
260
+ entitiesNowVisible.push(log.en);
261
+ }
262
+ }
263
+ }
264
+ const newAddedSet = new Set(delta.added);
265
+ const syntheticRemovals = [];
266
+ for (const en of entitiesNowHidden) {
267
+ const applogs = byEntity.get(en);
268
+ if (!applogs) continue;
269
+ for (const log of applogs) {
270
+ if (!newAddedSet.has(log)) syntheticRemovals.push(log);
271
+ }
272
+ }
273
+ const syntheticAdditions = [];
274
+ for (const en of entitiesNowVisible) {
275
+ const applogs = byEntity.get(en);
276
+ if (applogs) syntheticAdditions.push(...applogs);
277
+ }
278
+ const passAdded = delta.added.filter((log) => !hiddenBefore.has(log.en) && !isHidden(log.en));
279
+ const passRemoved = delta.removed?.filter((log) => !hiddenBefore.has(log.en)) ?? [];
280
+ return {
281
+ added: [...passAdded, ...syntheticAdditions],
282
+ removed: [...passRemoved, ...syntheticRemovals]
283
+ };
284
+ }
285
+ };
286
+ const result = rollingMapper(thread, derivation, { name: "withoutDeleted", extraFilterName: "withoutDeleted" });
287
+ return result;
288
+ });
289
+ function makeQueryNode(log, parentNode, varMapper, threadName) {
290
+ const nodeVars = Object.assign({}, parentNode?.variables, varMapper(log));
291
+ return new QueryNode(
292
+ StaticThread.fromArray([log], threadName),
293
+ nodeVars,
294
+ parentNode
295
+ );
296
+ }
297
+ var query = memoizedFn("query", function query2(threadOrLogs, patternOrPatterns, startVariables = {}, opts = {}) {
298
+ throwOnTimeout();
299
+ const thread = threadFromMaybeArray(threadOrLogs);
300
+ DEBUG(`query<${thread.nameAndSizeUntracked}>:`, patternOrPatterns);
301
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
302
+ warnIfDisjointQuerySteps(patterns);
303
+ let prevNodes;
304
+ if (patterns.length === 1) {
305
+ prevNodes = null;
306
+ } else {
307
+ const patternsExceptLast = patterns.slice(0, -1);
308
+ prevNodes = query2(thread, patternsExceptLast, startVariables, opts).nodes;
309
+ }
310
+ const lastPattern = patterns[patterns.length - 1];
311
+ const stepResult = queryStepOnce(thread, prevNodes, lastPattern, opts);
312
+ VERBOSE.isDisabled || VERBOSE(`query result:`, stepResult.nodes);
313
+ return stepResult;
314
+ }, {
315
+ argsDebugName: (thread, pattern, startVars) => createDebugName({ caller: "query", thread, args: startVars ? { pattern, startVars } : pattern })
316
+ });
317
+ function queryStepOnce(thread, prevNodes, pattern, opts = {}) {
318
+ DEBUG(`queryStepOnce<${thread.nameAndSizeUntracked}> with`, prevNodes?.length ?? "all", "nodes, pattern:", pattern);
319
+ if (!Object.entries(pattern).length) throw new Error(`Pattern is empty`);
320
+ function doQueryOnce(node) {
321
+ const [patternWithResolvedVars, variablesToFill] = resolveOrRemoveVariables(pattern, node?.variables ?? {});
322
+ VERBOSE(`[queryStepOnce.doQuery] patternWithoutVars: `, patternWithResolvedVars);
323
+ const filter = makeFilter(patternWithResolvedVars);
324
+ const matchingLogs = filter(thread.applogs);
325
+ const varMapper = createObjMapper(variablesToFill);
326
+ const nodes = matchingLogs.map((log) => makeQueryNode(
327
+ log,
328
+ node,
329
+ varMapper,
330
+ createDebugName({
331
+ caller: "QueryNode",
332
+ thread,
333
+ pattern: `${stringify(Object.assign({}, node?.variables, varMapper(log)))}@${stringify(patternWithResolvedVars)}`
334
+ })
335
+ ));
336
+ if (VERBOSE.isEnabled) VERBOSE(`[queryStepOnce.doQuery] nodes:`, nodes.map((n) => n.variables));
337
+ if (opts.debug) {
338
+ LOG(`[queryStepOnce] step result:`, nodes.map(({ variables, logsOfThisNode: thread2 }) => ({
339
+ variables,
340
+ thread: thread2
341
+ })));
342
+ }
343
+ return nodes;
344
+ }
345
+ if (!prevNodes) {
346
+ return new QueryResult(doQueryOnce(null));
347
+ }
348
+ const allNodes = prevNodes.flatMap((inputNode) => doQueryOnce(inputNode));
349
+ return new QueryResult(allNodes);
350
+ }
351
+ var liveQuery = memoizedFn("liveQuery", function liveQuery2(threadOrLogs, patternOrPatterns, startVariables = {}, opts = {}) {
352
+ throwOnTimeout();
353
+ const thread = threadFromMaybeArray(threadOrLogs);
354
+ DEBUG(`liveQuery<${thread.nameAndSizeUntracked}>:`, patternOrPatterns);
355
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
356
+ let prevResult;
357
+ if (patterns.length === 1) {
358
+ prevResult = null;
359
+ } else {
360
+ const patternsExceptLast = patterns.slice(0, -1);
361
+ prevResult = liveQuery2(thread, patternsExceptLast, startVariables, opts);
362
+ }
363
+ const lastPattern = patterns[patterns.length - 1];
364
+ const stepResult = liveQueryStep(thread, prevResult, lastPattern, opts);
365
+ VERBOSE.isDisabled || VERBOSE(`liveQuery result:`, stepResult.nodes);
366
+ return stepResult;
367
+ }, {
368
+ argsDebugName: (thread, pattern, startVars) => createDebugName({ caller: "liveQuery", thread, args: startVars ? { pattern, startVars } : pattern })
369
+ });
370
+ var liveQueryStep = memoizedFn("liveQueryStep", function liveQueryStep2(thread, nodeSet, pattern, opts = {}) {
371
+ DEBUG(`liveQueryStep<${thread.nameAndSizeUntracked}> with`, nodeSet?.untrackedSize ?? "all", "nodes, pattern:", pattern);
372
+ if (!Object.entries(pattern).length) throw new Error(`Pattern is empty`);
373
+ function doQuery(node) {
374
+ const [patternWithResolvedVars, variablesToFill] = resolveOrRemoveVariables(pattern, node?.variables ?? {});
375
+ VERBOSE(`[liveQueryStep.doQuery] patternWithoutVars: `, patternWithResolvedVars);
376
+ const applogsMatchingStatic = rollingFilter(thread, patternWithResolvedVars);
377
+ const varMapper = createObjMapper(variablesToFill);
378
+ function makeNode(log) {
379
+ return makeQueryNode(
380
+ log,
381
+ node,
382
+ varMapper,
383
+ createDebugName({
384
+ caller: "QueryNode",
385
+ thread: applogsMatchingStatic,
386
+ pattern: `${stringify(Object.assign({}, node?.variables, varMapper(log)))}@${stringify(patternWithResolvedVars)}`
387
+ })
388
+ );
389
+ }
390
+ const initialNodes = applogsMatchingStatic.applogs.map(makeNode);
391
+ if (VERBOSE.isEnabled) VERBOSE(`[liveQueryStep.doQuery] initial nodes:`, initialNodes.map((n) => n.variables));
392
+ if (opts.debug) {
393
+ LOG(`[liveQueryStep] step result:`, initialNodes.map(({ variables, logsOfThisNode: thread2 }) => ({
394
+ variables,
395
+ thread: thread2
396
+ })));
397
+ }
398
+ const result = new SubscribableArrayImpl(
399
+ initialNodes,
400
+ () => applogsMatchingStatic.subscribe((event) => {
401
+ if (isInitEvent(event)) {
402
+ result._reset(event.init.map(makeNode));
403
+ } else {
404
+ if (event.added.length) {
405
+ result._push(...event.added.map(makeNode));
406
+ }
407
+ if (event.removed?.length) {
408
+ const removedCids = new Set(event.removed.map((log) => log.cid));
409
+ const toRemove = result.items.filter(
410
+ (qn) => removedCids.has(qn.logsOfThisNode.applogs[0]?.cid)
411
+ );
412
+ if (toRemove.length) result._remove(toRemove);
413
+ }
414
+ }
415
+ }, "derived")
416
+ );
417
+ return result;
418
+ }
419
+ if (!nodeSet) {
420
+ return new LiveQueryResult(doQuery(null));
421
+ }
422
+ const initialInners = nodeSet.nodes.map((inputNode) => ({
423
+ inputNode,
424
+ inner: doQuery(inputNode)
425
+ }));
426
+ const initialItems = initialInners.flatMap(({ inner }) => [...inner.items]);
427
+ const aggregated = new SubscribableArrayImpl(
428
+ initialItems,
429
+ () => {
430
+ const subsByInputNode = /* @__PURE__ */ new Map();
431
+ function wireInner(inputNode, inner) {
432
+ const entry = { inner, unsub: null, nodes: [...inner.items] };
433
+ entry.unsub = inner.subscribe((event) => {
434
+ if (isArrayInitEvent(event)) {
435
+ if (entry.nodes.length) aggregated._remove(entry.nodes);
436
+ entry.nodes = [...event.init];
437
+ if (entry.nodes.length) aggregated._push(...entry.nodes);
438
+ } else {
439
+ if (event.added.length) {
440
+ entry.nodes.push(...event.added);
441
+ aggregated._push(...event.added);
442
+ }
443
+ if (event.removed?.length) {
444
+ for (const r of event.removed) {
445
+ const idx = entry.nodes.indexOf(r);
446
+ if (idx >= 0) entry.nodes.splice(idx, 1);
447
+ }
448
+ aggregated._remove(event.removed);
449
+ }
450
+ }
451
+ }, "derived");
452
+ subsByInputNode.set(inputNode, entry);
453
+ return entry.nodes;
454
+ }
455
+ function addInputNode(inputNode) {
456
+ return wireInner(inputNode, doQuery(inputNode));
457
+ }
458
+ function removeInputNode(inputNode) {
459
+ const entry = subsByInputNode.get(inputNode);
460
+ if (!entry) return [];
461
+ entry.unsub();
462
+ entry.inner.dispose();
463
+ const removed = entry.nodes;
464
+ subsByInputNode.delete(inputNode);
465
+ return removed;
466
+ }
467
+ for (const { inputNode, inner } of initialInners) {
468
+ wireInner(inputNode, inner);
469
+ }
470
+ const prevUnsub = nodeSet.subscribe((event) => {
471
+ if (isArrayInitEvent(event)) {
472
+ for (const [, entry] of subsByInputNode) {
473
+ entry.unsub();
474
+ entry.inner.dispose();
475
+ }
476
+ subsByInputNode.clear();
477
+ const allNodes = [];
478
+ for (const node of event.init) {
479
+ allNodes.push(...addInputNode(node));
480
+ }
481
+ aggregated._reset(allNodes);
482
+ } else {
483
+ if (event.added.length) {
484
+ const allAdded = [];
485
+ for (const node of event.added) {
486
+ allAdded.push(...addInputNode(node));
487
+ }
488
+ if (allAdded.length) aggregated._push(...allAdded);
489
+ }
490
+ if (event.removed?.length) {
491
+ const allRemoved = [];
492
+ for (const node of event.removed) {
493
+ allRemoved.push(...removeInputNode(node));
494
+ }
495
+ if (allRemoved.length) aggregated._remove(allRemoved);
496
+ }
497
+ }
498
+ }, "derived");
499
+ return () => {
500
+ prevUnsub();
501
+ for (const [, entry] of subsByInputNode) {
502
+ entry.unsub();
503
+ entry.inner.dispose();
504
+ }
505
+ subsByInputNode.clear();
506
+ };
507
+ }
508
+ );
509
+ if (VERBOSE.isEnabled) VERBOSE(`[liveQueryStep] aggregated initial:`, [...aggregated.items]);
510
+ return new LiveQueryResult(aggregated);
511
+ }, { argsDebugName: (thread, _nodes, pattern) => createDebugName({ caller: "liveQueryStep", thread, pattern }) });
512
+ var queryNot = memoizedFn("queryNot", function queryNot2(thread, startNodes, patternOrPatterns, opts = {}) {
513
+ const nodes = startNodes.nodes;
514
+ DEBUG(`queryNot<${thread.nameAndSizeUntracked}> from: ${nodes.length} nodes`);
515
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
516
+ const filtered = nodes.filter(function innerNodeFilter({ variables }) {
517
+ let bindings = [variables ?? {}];
518
+ for (const pattern of patterns) {
519
+ if (!Object.entries(pattern).length) throw new Error(`Pattern is empty`);
520
+ const nextBindings = [];
521
+ for (const binding of bindings) {
522
+ const [resolved, varsToFill] = resolveOrRemoveVariables(pattern, binding);
523
+ const filter = makeFilter(resolved);
524
+ const matchingLogs = filter(thread.applogs);
525
+ const varMapper = createObjMapper(varsToFill);
526
+ for (const log of matchingLogs) {
527
+ nextBindings.push({ ...binding, ...varMapper(log) });
528
+ }
529
+ }
530
+ bindings = nextBindings;
531
+ if (bindings.length === 0) break;
532
+ }
533
+ VERBOSE(`[queryNot] node:`, variables, "=> bindings:", bindings.length);
534
+ if (opts.debug) LOG(`[queryNot] node result:`, variables, "=>", bindings);
535
+ return bindings.length === 0;
536
+ });
537
+ return new QueryResult([...filtered]);
538
+ }, { argsDebugName: (thread, nodes, pattern) => createDebugName({ caller: "queryNot", thread, pattern }) });
539
+ var liveQueryNot = memoizedFn("liveQueryNot", function liveQueryNot2(thread, upstream, patternOrPatterns, opts = {}) {
540
+ const patterns = Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns];
541
+ function nodeMatchesNot(node, applogs) {
542
+ let bindings = [node.variables ?? {}];
543
+ for (const pattern of patterns) {
544
+ const nextBindings = [];
545
+ for (const binding of bindings) {
546
+ const [resolved, varsToFill] = resolveOrRemoveVariables(pattern, binding);
547
+ const filter = makeFilter(resolved);
548
+ const varMapper = createObjMapper(varsToFill);
549
+ for (const log of filter(applogs)) {
550
+ nextBindings.push({ ...binding, ...varMapper(log) });
551
+ }
552
+ }
553
+ bindings = nextBindings;
554
+ if (bindings.length === 0) return false;
555
+ }
556
+ return bindings.length > 0;
557
+ }
558
+ function computeAll() {
559
+ return upstream.nodes.filter((node) => !nodeMatchesNot(node, thread.applogs));
560
+ }
561
+ const result = new SubscribableArrayImpl(
562
+ computeAll(),
563
+ () => {
564
+ const threadUnsub = thread.subscribe((event) => {
565
+ if (isInitEvent(event)) {
566
+ result._reset(computeAll());
567
+ return;
568
+ }
569
+ if (event.removed?.length) {
570
+ result._reset(computeAll());
571
+ return;
572
+ }
573
+ if (event.added.length) {
574
+ const toRemove = result.items.filter((node) => nodeMatchesNot(node, event.added));
575
+ if (toRemove.length > 0) {
576
+ result._remove(toRemove);
577
+ }
578
+ }
579
+ }, "derived");
580
+ const upstreamUnsub = upstream.subscribe((event) => {
581
+ if (isArrayInitEvent(event)) {
582
+ result._reset(computeAll());
583
+ return;
584
+ }
585
+ if (event.added.length) {
586
+ const passing = event.added.filter((node) => !nodeMatchesNot(node, thread.applogs));
587
+ if (passing.length > 0) result._push(...passing);
588
+ }
589
+ if (event.removed?.length) {
590
+ const removedSet = new Set(event.removed);
591
+ const toRemove = result.items.filter((node) => removedSet.has(node));
592
+ if (toRemove.length > 0) result._remove(toRemove);
593
+ }
594
+ }, "derived");
595
+ return () => {
596
+ threadUnsub();
597
+ upstreamUnsub();
598
+ };
599
+ }
600
+ );
601
+ return new LiveQueryResult(result);
602
+ }, { argsDebugName: (thread, _nodes, pattern) => createDebugName({ caller: "liveQueryNot", thread, pattern }) });
603
+ var filterAndMap = memoizedFn("filterAndMap", function filterAndMap2(thread, pattern, mapper) {
604
+ DEBUG(`filterAndMap<${thread.nameAndSizeUntracked}>`, pattern);
605
+ const filter = makeFilter(pattern);
606
+ const filtered = filter(thread.applogs);
607
+ return mapApplogsWith(filtered, mapper);
608
+ }, { argsDebugName: (thread, pattern) => createDebugName({ caller: "filterAndMap", thread, pattern }) });
609
+ var liveFilterAndMap = memoizedFn("liveFilterAndMap", function liveFilterAndMap2(thread, pattern, mapper) {
610
+ DEBUG(`liveFilterAndMap<${thread.nameAndSizeUntracked}>`, pattern);
611
+ const filtered = rollingFilter(thread, pattern);
612
+ const mapFn = makeApplogMapper(mapper);
613
+ const cidToMapped = /* @__PURE__ */ new Map();
614
+ const mapAndTrack = (log) => {
615
+ const r = mapFn(log);
616
+ cidToMapped.set(log.cid, r);
617
+ return r;
618
+ };
619
+ const initial = filtered.applogs.map(mapAndTrack);
620
+ const result = new SubscribableArrayImpl(
621
+ initial,
622
+ () => filtered.subscribe((event) => {
623
+ if (isInitEvent(event)) {
624
+ cidToMapped.clear();
625
+ result._reset(event.init.map(mapAndTrack));
626
+ } else {
627
+ if (event.added.length) result._push(...event.added.map(mapAndTrack));
628
+ if (event.removed?.length) {
629
+ const toRemove = [];
630
+ for (const log of event.removed) {
631
+ const r = cidToMapped.get(log.cid);
632
+ if (r === void 0) {
633
+ WARN(`[liveFilterAndMap] removed log not in cidToMapped`, { log });
634
+ continue;
635
+ }
636
+ cidToMapped.delete(log.cid);
637
+ toRemove.push(r);
638
+ }
639
+ if (toRemove.length) result._remove(toRemove);
640
+ }
641
+ }
642
+ }, "derived")
643
+ );
644
+ return result;
645
+ }, { argsDebugName: (thread, pattern) => createDebugName({ caller: "liveFilterAndMap", thread, pattern }) });
646
+ var queryAndMap = memoizedFn("queryAndMap", function queryAndMap2(threadOrLogs, patternOrPatterns, mapDef, variables = {}) {
647
+ const thread = threadFromMaybeArray(threadOrLogs);
648
+ DEBUG(`queryAndMap<${thread.nameAndSizeUntracked}>`, { patternOrPatterns, variables, map: mapDef });
649
+ const queryResult = query(thread, patternOrPatterns);
650
+ return mapQueryResultWith(queryResult, mapDef);
651
+ }, { argsDebugName: (thread, pattern) => createDebugName({ caller: "queryAndMap", thread, pattern }) });
652
+ var liveQueryAndMap = memoizedFn("liveQueryAndMap", function liveQueryAndMap2(thread, patternOrPatterns, mapDef) {
653
+ DEBUG(`liveQueryAndMap<${thread.nameAndSizeUntracked}>`, { patternOrPatterns, map: mapDef });
654
+ const live = liveQuery(thread, patternOrPatterns);
655
+ function computeAll() {
656
+ const snapshot = new QueryResult(live.nodes);
657
+ return mapQueryResultWith(snapshot, mapDef);
658
+ }
659
+ const result = new SubscribableArrayImpl(
660
+ computeAll(),
661
+ () => live.subscribe(() => {
662
+ result._reset(computeAll());
663
+ }, "derived")
664
+ );
665
+ return result;
666
+ }, { argsDebugName: (thread, pattern) => createDebugName({ caller: "liveQueryAndMap", thread, pattern }) });
667
+ var queryEntity = memoizedFn("queryEntity", function queryEntity2(thread, name, entityID, attributes) {
668
+ assertLWW(thread);
669
+ DEBUG(`queryEntity<${thread.nameAndSizeUntracked}>`, entityID, name);
670
+ const filter = makeFilter({ en: entityID, at: prefixAttrs(name, attributes) });
671
+ const filtered = filter(thread.applogs);
672
+ VERBOSE(`queryEntity applogs:`, filtered);
673
+ if (filtered.length === 0) return null;
674
+ return Object.fromEntries(
675
+ filtered.map(({ at, vl }) => [at.slice(name.length + 1), vl])
676
+ );
677
+ }, {
678
+ argsDebugName: (thread, name, entityID) => createDebugName({ caller: "queryEntity", thread, args: { name, entityID } })
679
+ });
680
+ var liveQueryEntity = memoizedFn("liveQueryEntity", function liveQueryEntity2(thread, name, entityID, attributes) {
681
+ assertLWW(thread);
682
+ DEBUG(`liveQueryEntity<${thread.nameAndSizeUntracked}>`, entityID, name);
683
+ const filtered = rollingFilter(thread, { en: entityID, at: prefixAttrs(name, attributes) });
684
+ function compute() {
685
+ if (filtered.isEmpty) return null;
686
+ return Object.fromEntries(
687
+ filtered.map(({ at, vl }) => [at.slice(name.length + 1), vl])
688
+ );
689
+ }
690
+ const result = new SubscribableImpl(
691
+ compute(),
692
+ () => filtered.subscribe(() => {
693
+ result._set(compute());
694
+ }, "derived")
695
+ );
696
+ return result;
697
+ }, {
698
+ argsDebugName: (thread, name, entityID) => createDebugName({ caller: "liveQueryEntity", thread, args: { name, entityID } })
699
+ });
700
+ var liveEntityAt = memoizedFn("liveEntityAt", function liveEntityAt2(thread, entityID, at) {
701
+ assertLWW(thread);
702
+ DEBUG(`liveEntityAt<${thread.nameAndSizeUntracked}>`, entityID, at);
703
+ const filtered = rollingFilter(thread, { en: entityID, at });
704
+ function compute() {
705
+ if (filtered.isEmpty) return null;
706
+ return filtered.applogs[filtered.applogs.length - 1].vl;
707
+ }
708
+ const result = new SubscribableImpl(
709
+ compute(),
710
+ () => filtered.subscribe(() => {
711
+ result._set(compute());
712
+ }, "derived")
713
+ );
714
+ return result;
715
+ }, {
716
+ argsDebugName: (thread, entityID, at) => createDebugName({ caller: "liveEntityAt", thread, args: { entityID, at } })
717
+ });
718
+ var agentsOfThread = memoizedFn("agentsOfThread", function agentsOfThread2(thread) {
719
+ DEBUG(`agentsOfThread<${thread.nameAndSizeUntracked}>`);
720
+ const mapped = /* @__PURE__ */ new Map();
721
+ const onEvent = (event) => {
722
+ for (const log of isInitEvent(event) ? event.init : event.added) {
723
+ const prev = mapped.get(log.ag) ?? 0;
724
+ mapped.set(log.ag, prev + 1);
725
+ }
726
+ for (const log of !isInitEvent(event) && event.removed || []) {
727
+ const prev = mapped.get(log.ag);
728
+ if (!prev || prev < 1) throw ERROR(`[agentsOfThread] number is now negative`, { log, event, mapped, prev });
729
+ mapped.set(log.ag, prev - 1);
730
+ }
731
+ LOG(`agentsOfThread<${thread.nameAndSizeUntracked}> processed event`, { event, mapped });
732
+ };
733
+ onEvent({ init: thread.applogs });
734
+ thread.subscribe(onEvent, "derived");
735
+ return mapped;
736
+ });
737
+ var entityOverlap = memoizedFn("entityOverlap", function entityOverlapCount(threadA, threadB) {
738
+ LOG(`entityOverlap<${threadA.nameAndSizeUntracked}, ${threadB.nameAndSizeUntracked}>`);
739
+ const entitiesA = new Set(threadA.map((log) => log.en));
740
+ const entitiesB = new Set(threadB.map((log) => log.en));
741
+ return [...entitiesA].filter((en) => entitiesB.has(en));
742
+ });
743
+ var entityOverlapMap = function entityOverlapMap2(threadA, threadB, threadAName = "incoming", threadBName = "current") {
744
+ const useInferredVM = (en, thread) => en;
745
+ const overlapping = entityOverlap(threadA, threadB);
746
+ const mapped = /* @__PURE__ */ new Map();
747
+ overlapping.forEach((eachEntityID) => mapped.set(eachEntityID, {
748
+ [threadAName]: useInferredVM(eachEntityID, threadA),
749
+ [threadBName]: useInferredVM(eachEntityID, threadB)
750
+ }));
751
+ };
752
+ var entityOverlapCount2 = memoizedFn(
753
+ "entityOverlapCount",
754
+ function entityOverlapCount3(threadA, threadB) {
755
+ return entityOverlap(threadA, threadB).length;
756
+ }
757
+ );
758
+ var liveEntityOverlapCount = memoizedFn(
759
+ "liveEntityOverlapCount",
760
+ function liveEntityOverlapCount2(threadA, threadB) {
761
+ function compute() {
762
+ const entitiesA = new Set(threadA.map((log) => log.en));
763
+ const entitiesB = new Set(threadB.map((log) => log.en));
764
+ return [...entitiesA].filter((en) => entitiesB.has(en)).length;
765
+ }
766
+ const result = new SubscribableImpl(
767
+ compute(),
768
+ () => {
769
+ const unsub1 = threadA.subscribe(() => result._set(compute()), "derived");
770
+ const unsub2 = threadB.subscribe(() => result._set(compute()), "derived");
771
+ return () => {
772
+ unsub1();
773
+ unsub2();
774
+ };
775
+ }
776
+ );
777
+ return result;
778
+ }
779
+ );
780
+ var querySingle = memoizedFn("querySingle", function querySingle2(threadOrLogs, patternOrPatterns, variables = {}) {
781
+ const result = query(threadOrLogs, patternOrPatterns, variables);
782
+ if (result.isEmpty) return null;
783
+ if (result.size > 1) throw ERROR(`[querySingle] got`, result.size, `results:`, result);
784
+ const logsOfThisNode = result.nodes[0].logsOfThisNode;
785
+ if (logsOfThisNode.size != 1) throw ERROR(`[querySingle] single result, but got`, logsOfThisNode.size, `logs:`, logsOfThisNode.applogs);
786
+ return logsOfThisNode.applogs[0];
787
+ }, {
788
+ argsDebugName: (thread, pattern) => createDebugName({ caller: "querySingle", thread, pattern })
789
+ });
790
+ var querySingleAndMap = memoizedFn(
791
+ "querySingleAndMap",
792
+ function querySingleAndMap2(threadOrLogs, patternOrPatterns, mapDef, variables = {}) {
793
+ const log = querySingle(threadOrLogs, patternOrPatterns, variables);
794
+ if (!log) return void 0;
795
+ if (typeof mapDef === "string") {
796
+ return log[mapDef];
797
+ } else {
798
+ return createObjMapper(mapDef)(log);
799
+ }
800
+ },
801
+ {
802
+ argsDebugName: (thread, pattern) => createDebugName({ caller: "querySingleAndMap", thread, pattern })
803
+ }
804
+ );
805
+ var liveQuerySingle = memoizedFn("liveQuerySingle", function liveQuerySingle2(thread, patternOrPatterns) {
806
+ DEBUG(`liveQuerySingle<${thread.nameAndSizeUntracked}>`);
807
+ const live = liveQuery(thread, patternOrPatterns);
808
+ function compute() {
809
+ if (live.isEmpty) return null;
810
+ if (live.size > 1) throw ERROR(`[liveQuerySingle] got`, live.size, `results`);
811
+ const logsOfThisNode = live.nodes[0].logsOfThisNode;
812
+ if (logsOfThisNode.size !== 1) throw ERROR(`[liveQuerySingle] single result, but got`, logsOfThisNode.size, `logs`);
813
+ return logsOfThisNode.applogs[0];
814
+ }
815
+ const result = new SubscribableImpl(
816
+ compute(),
817
+ () => live.subscribe(() => {
818
+ result._set(compute());
819
+ })
820
+ );
821
+ return result;
822
+ }, {
823
+ argsDebugName: (thread, pattern) => createDebugName({ caller: "liveQuerySingle", thread, pattern })
824
+ });
825
+ var liveQuerySingleAndMap = memoizedFn(
826
+ "liveQuerySingleAndMap",
827
+ function liveQuerySingleAndMap2(thread, patternOrPatterns, mapDef) {
828
+ DEBUG(`liveQuerySingleAndMap<${thread.nameAndSizeUntracked}>`);
829
+ const liveSingle = liveQuerySingle(thread, patternOrPatterns);
830
+ function compute() {
831
+ const log = liveSingle.value;
832
+ if (!log) return void 0;
833
+ if (typeof mapDef === "string") {
834
+ return log[mapDef];
835
+ } else {
836
+ return createObjMapper(mapDef)(log);
837
+ }
838
+ }
839
+ const result = new SubscribableImpl(
840
+ compute(),
841
+ () => liveSingle.subscribe(() => {
842
+ result._set(compute());
843
+ })
844
+ );
845
+ return result;
846
+ },
847
+ {
848
+ argsDebugName: (thread, pattern) => createDebugName({ caller: "liveQuerySingleAndMap", thread, pattern })
849
+ }
850
+ );
851
+ function makeApplogMapper(mapDef) {
852
+ if (typeof mapDef === "function") {
853
+ return mapDef;
854
+ } else if (typeof mapDef === "string") {
855
+ return (log) => log[mapDef];
856
+ } else {
857
+ return createObjMapper(mapDef);
858
+ }
859
+ }
860
+ function mapApplogsWith(applogs, mapDef) {
861
+ return applogs.map(makeApplogMapper(mapDef));
862
+ }
863
+ var mapThreadWith = function filterAndMapGetterFx(thread, mapDef) {
864
+ return mapApplogsWith(thread.applogs, mapDef);
865
+ };
866
+ var mapQueryResultWith = function filterAndMapGetterFx2(queryResult, mapDef) {
867
+ if (typeof mapDef === "function") {
868
+ return queryResult.records.map(mapDef);
869
+ } else if (typeof mapDef === "string") {
870
+ return queryResult.nodes.map((node) => {
871
+ if (!Object.hasOwn(node.record, mapDef)) {
872
+ if (node.logsOfThisNode.size !== 1) {
873
+ throw ERROR(`not sure what to map (it's not a var and a result node log count of ${node.logsOfThisNode.size})`);
874
+ }
875
+ return node.logsOfThisNode.firstLog[mapDef];
876
+ }
877
+ return node.record[mapDef];
878
+ });
879
+ } else {
880
+ return queryResult.nodes.map((node) => {
881
+ return createObjMapper(mapDef)(node.record);
882
+ });
883
+ }
884
+ };
885
+ function createObjMapper(applogFieldMap) {
886
+ return (applog) => {
887
+ return Object.entries(applogFieldMap).reduce((acc, [key, value]) => {
888
+ acc[value] = applog[key];
889
+ return acc;
890
+ }, {});
891
+ };
892
+ }
893
+ function startsWith(str) {
894
+ return (value) => value.startsWith(str);
895
+ }
896
+ function prefixAttrs(prefix, attrs) {
897
+ return attrs.map((at) => prefixAt(prefix, at));
898
+ }
899
+ function prefixAt(prefix, attr) {
900
+ return `${prefix}/${attr}`;
901
+ }
902
+ function stripAtPrefix(attr) {
903
+ const idx = attr.indexOf("/");
904
+ return idx >= 0 ? attr.slice(idx + 1) : attr;
905
+ }
906
+ function mapAttributes(mapping) {
907
+ return (attr) => mapping[attr] ?? attr;
908
+ }
909
+ function resolveKeyMapper(opts) {
910
+ if (!opts) return (attr) => attr;
911
+ if (opts.mapKeys) return opts.mapKeys;
912
+ if (opts.stripAtPrefix === true) return stripAtPrefix;
913
+ if (typeof opts.stripAtPrefix === "string") {
914
+ const prefix = opts.stripAtPrefix + "/";
915
+ return (attr) => attr.startsWith(prefix) ? attr.slice(prefix.length) : attr;
916
+ }
917
+ return (attr) => attr;
918
+ }
919
+ function threadFromMaybeArray(threadOrLogs, name) {
920
+ if (!Array.isArray(threadOrLogs)) {
921
+ return threadOrLogs;
922
+ }
923
+ return ThreadInMemory.fromArray(threadOrLogs, name || `threadFromArray[${threadOrLogs.length}]`, true);
924
+ }
925
+ function withTimeout(timeoutMilliseconds, func) {
926
+ if (globalQueryTimeoutTime) throw ERROR(`Nested timeout not supported`);
927
+ globalQueryTimeoutTime = performance.now() + timeoutMilliseconds;
928
+ try {
929
+ return func();
930
+ } finally {
931
+ globalQueryTimeoutTime = null;
932
+ }
933
+ }
934
+ function getPatternVariableNames(pattern) {
935
+ const vars = /* @__PURE__ */ new Set();
936
+ for (const value of Object.values(pattern)) {
937
+ if (isVariable(value)) {
938
+ vars.add(value.slice(1));
939
+ }
940
+ }
941
+ return vars;
942
+ }
943
+ function warnIfDisjointQuerySteps(patterns) {
944
+ if (patterns.length < 2) return;
945
+ const varSets = patterns.map(getPatternVariableNames);
946
+ const reachable = new Set(varSets[0]);
947
+ for (let i = 1; i < varSets.length; i++) {
948
+ const stepVars = varSets[i];
949
+ if (stepVars.size === 0) {
950
+ WARN(
951
+ `[query] Step ${i} has no variables \u2014 it produces identical results regardless of previous steps (cartesian product).`,
952
+ `Patterns:`,
953
+ patterns
954
+ );
955
+ continue;
956
+ }
957
+ const connected = [...stepVars].some((v) => reachable.has(v));
958
+ if (!connected) {
959
+ WARN(
960
+ `[query] Step ${i} is disconnected from previous steps \u2014 no shared variable.`,
961
+ `This produces a cartesian product instead of a join.`,
962
+ `Step ${i} variables: {${[...stepVars].join(", ")}}`,
963
+ `Reachable from prior steps: {${[...reachable].join(", ")}}`,
964
+ `Patterns:`,
965
+ patterns
966
+ );
967
+ }
968
+ for (const v of stepVars) reachable.add(v);
969
+ }
970
+ }
971
+ function throwOnTimeout() {
972
+ if (globalQueryTimeoutTime == null) return;
973
+ if (performance.now() >= globalQueryTimeoutTime) {
974
+ throw new QueryTimeoutError(globalQueryTimeoutTime);
975
+ }
976
+ }
977
+ var QueryTimeoutError = class extends Error {
978
+ constructor(message) {
979
+ super(message);
980
+ }
981
+ };
982
+
983
+ export {
984
+ QueryNode,
985
+ QueryResult,
986
+ LiveQueryResult,
987
+ lastWriteWins,
988
+ withoutDeleted,
989
+ query,
990
+ queryStepOnce,
991
+ liveQuery,
992
+ liveQueryStep,
993
+ queryNot,
994
+ liveQueryNot,
995
+ filterAndMap,
996
+ liveFilterAndMap,
997
+ queryAndMap,
998
+ liveQueryAndMap,
999
+ queryEntity,
1000
+ liveQueryEntity,
1001
+ liveEntityAt,
1002
+ agentsOfThread,
1003
+ entityOverlap,
1004
+ entityOverlapMap,
1005
+ entityOverlapCount2 as entityOverlapCount,
1006
+ liveEntityOverlapCount,
1007
+ querySingle,
1008
+ querySingleAndMap,
1009
+ liveQuerySingle,
1010
+ liveQuerySingleAndMap,
1011
+ makeApplogMapper,
1012
+ mapApplogsWith,
1013
+ mapThreadWith,
1014
+ mapQueryResultWith,
1015
+ createObjMapper,
1016
+ startsWith,
1017
+ prefixAttrs,
1018
+ prefixAt,
1019
+ stripAtPrefix,
1020
+ mapAttributes,
1021
+ resolveKeyMapper,
1022
+ threadFromMaybeArray,
1023
+ withTimeout,
1024
+ throwOnTimeout
1025
+ };
1026
+ //# sourceMappingURL=chunk-QZXKQCAY.js.map