@dxos/echo-pipeline 0.8.4-main.f9ba587 → 0.8.4-main.fcfe5033a5

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 (186) hide show
  1. package/dist/lib/neutral/chunk-76DA36YG.mjs +247 -0
  2. package/dist/lib/neutral/chunk-76DA36YG.mjs.map +7 -0
  3. package/dist/lib/{browser/chunk-GBFX5J5B.mjs → neutral/chunk-ONB2OWBB.mjs} +290 -198
  4. package/dist/lib/neutral/chunk-ONB2OWBB.mjs.map +7 -0
  5. package/dist/lib/{browser → neutral}/filter/index.mjs +3 -2
  6. package/dist/lib/{browser → neutral}/index.mjs +3452 -1124
  7. package/dist/lib/neutral/index.mjs.map +7 -0
  8. package/dist/lib/neutral/meta.json +1 -0
  9. package/dist/lib/{browser → neutral}/testing/index.mjs +63 -214
  10. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  11. package/dist/types/src/automerge/automerge-host.d.ts +56 -45
  12. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  13. package/dist/types/src/automerge/automerge-repo.test.d.ts +1 -1
  14. package/dist/types/src/automerge/automerge-repo.test.d.ts.map +1 -1
  15. package/dist/types/src/automerge/collection-synchronizer.d.ts +6 -4
  16. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  17. package/dist/types/src/automerge/echo-network-adapter.d.ts +23 -10
  18. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  19. package/dist/types/src/automerge/echo-replicator.d.ts +38 -15
  20. package/dist/types/src/automerge/echo-replicator.d.ts.map +1 -1
  21. package/dist/types/src/automerge/heads-store.d.ts +9 -2
  22. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  23. package/dist/types/src/automerge/index.d.ts +1 -1
  24. package/dist/types/src/automerge/index.d.ts.map +1 -1
  25. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +5 -5
  26. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  27. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts +9 -8
  28. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  29. package/dist/types/src/automerge/mesh-echo-replicator.d.ts +6 -5
  30. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  31. package/dist/types/src/common/codec.d.ts +1 -1
  32. package/dist/types/src/common/codec.d.ts.map +1 -1
  33. package/dist/types/src/db-host/automerge-data-source.d.ts +35 -0
  34. package/dist/types/src/db-host/automerge-data-source.d.ts.map +1 -0
  35. package/dist/types/src/db-host/automerge-data-source.test.d.ts +2 -0
  36. package/dist/types/src/db-host/automerge-data-source.test.d.ts.map +1 -0
  37. package/dist/types/src/db-host/data-service.d.ts +8 -7
  38. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  39. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  40. package/dist/types/src/db-host/documents-synchronizer.d.ts +8 -7
  41. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  42. package/dist/types/src/db-host/echo-host.d.ts +58 -28
  43. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  44. package/dist/types/src/db-host/index.d.ts +1 -0
  45. package/dist/types/src/db-host/index.d.ts.map +1 -1
  46. package/dist/types/src/db-host/local-queue-service.d.ts +19 -0
  47. package/dist/types/src/db-host/local-queue-service.d.ts.map +1 -0
  48. package/dist/types/src/db-host/query-service.d.ts +14 -9
  49. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  50. package/dist/types/src/db-host/queue-data-source.d.ts +38 -0
  51. package/dist/types/src/db-host/queue-data-source.d.ts.map +1 -0
  52. package/dist/types/src/db-host/queue-service.test.d.ts +2 -0
  53. package/dist/types/src/db-host/queue-service.test.d.ts.map +1 -0
  54. package/dist/types/src/db-host/space-state-manager.d.ts +2 -1
  55. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  56. package/dist/types/src/db-host/stub.d.ts +11 -0
  57. package/dist/types/src/db-host/stub.d.ts.map +1 -0
  58. package/dist/types/src/edge/echo-edge-replicator.d.ts +10 -7
  59. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  60. package/dist/types/src/filter/filter-match.d.ts +4 -1
  61. package/dist/types/src/filter/filter-match.d.ts.map +1 -1
  62. package/dist/types/src/metadata/metadata-store.d.ts +1 -1
  63. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  64. package/dist/types/src/pipeline/pipeline.d.ts +3 -3
  65. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  66. package/dist/types/src/query/errors.d.ts +21 -9
  67. package/dist/types/src/query/errors.d.ts.map +1 -1
  68. package/dist/types/src/query/plan.d.ts +66 -8
  69. package/dist/types/src/query/plan.d.ts.map +1 -1
  70. package/dist/types/src/query/query-executor.d.ts +64 -10
  71. package/dist/types/src/query/query-executor.d.ts.map +1 -1
  72. package/dist/types/src/query/query-planner.d.ts +12 -1
  73. package/dist/types/src/query/query-planner.d.ts.map +1 -1
  74. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  75. package/dist/types/src/space/auth.d.ts +3 -3
  76. package/dist/types/src/space/auth.d.ts.map +1 -1
  77. package/dist/types/src/space/control-pipeline.d.ts +5 -4
  78. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  79. package/dist/types/src/space/space-manager.d.ts +8 -7
  80. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  81. package/dist/types/src/space/space-protocol.d.ts +9 -8
  82. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  83. package/dist/types/src/space/space.d.ts +6 -6
  84. package/dist/types/src/space/space.d.ts.map +1 -1
  85. package/dist/types/src/testing/index.d.ts +0 -2
  86. package/dist/types/src/testing/index.d.ts.map +1 -1
  87. package/dist/types/src/testing/test-agent-builder.d.ts +2 -2
  88. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  89. package/dist/types/src/testing/test-network-adapter.d.ts +1 -1
  90. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  91. package/dist/types/src/testing/test-replicator.d.ts +14 -13
  92. package/dist/types/src/testing/test-replicator.d.ts.map +1 -1
  93. package/dist/types/src/util.d.ts +1 -1
  94. package/dist/types/src/util.d.ts.map +1 -1
  95. package/dist/types/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +54 -47
  97. package/src/automerge/automerge-host.test.ts +57 -27
  98. package/src/automerge/automerge-host.ts +413 -137
  99. package/src/automerge/automerge-repo.test.ts +215 -47
  100. package/src/automerge/collection-synchronizer.test.ts +22 -15
  101. package/src/automerge/collection-synchronizer.ts +71 -30
  102. package/src/automerge/echo-data-monitor.ts +1 -1
  103. package/src/automerge/echo-network-adapter.test.ts +5 -4
  104. package/src/automerge/echo-network-adapter.ts +72 -29
  105. package/src/automerge/echo-replicator.ts +41 -15
  106. package/src/automerge/heads-store.ts +42 -3
  107. package/src/automerge/index.ts +1 -1
  108. package/src/automerge/leveldb-storage-adapter.ts +11 -11
  109. package/src/automerge/mesh-echo-replicator-connection.ts +12 -8
  110. package/src/automerge/mesh-echo-replicator.ts +15 -11
  111. package/src/automerge/storage-adapter.test.ts +1 -1
  112. package/src/common/space-id.ts +1 -1
  113. package/src/db-host/automerge-data-source.test.ts +299 -0
  114. package/src/db-host/automerge-data-source.ts +187 -0
  115. package/src/db-host/data-service.ts +25 -26
  116. package/src/db-host/database-root.ts +2 -2
  117. package/src/db-host/documents-synchronizer.test.ts +143 -14
  118. package/src/db-host/documents-synchronizer.ts +61 -45
  119. package/src/db-host/echo-host.ts +241 -93
  120. package/src/db-host/index.ts +1 -0
  121. package/src/db-host/local-queue-service.ts +127 -0
  122. package/src/db-host/query-service.ts +30 -98
  123. package/src/db-host/queue-data-source.ts +159 -0
  124. package/src/db-host/queue-service.test.ts +145 -0
  125. package/src/db-host/space-state-manager.ts +7 -3
  126. package/src/db-host/stub.ts +33 -0
  127. package/src/edge/echo-edge-replicator.test.ts +12 -10
  128. package/src/edge/echo-edge-replicator.ts +144 -58
  129. package/src/filter/filter-match.test.ts +68 -32
  130. package/src/filter/filter-match.ts +184 -20
  131. package/src/metadata/metadata-store.ts +11 -8
  132. package/src/pipeline/pipeline-stress.test.ts +1 -1
  133. package/src/pipeline/pipeline.test.ts +2 -2
  134. package/src/pipeline/pipeline.ts +9 -7
  135. package/src/query/errors.ts +3 -1
  136. package/src/query/plan.ts +82 -8
  137. package/src/query/query-executor.ts +1027 -163
  138. package/src/query/query-planner.test.ts +993 -81
  139. package/src/query/query-planner.ts +467 -27
  140. package/src/space/admission-discovery-extension.ts +3 -3
  141. package/src/space/auth.ts +6 -6
  142. package/src/space/control-pipeline.test.ts +5 -4
  143. package/src/space/control-pipeline.ts +16 -13
  144. package/src/space/space-manager.browser.test.ts +1 -1
  145. package/src/space/space-manager.ts +16 -12
  146. package/src/space/space-protocol.browser.test.ts +15 -14
  147. package/src/space/space-protocol.test.ts +15 -14
  148. package/src/space/space-protocol.ts +22 -18
  149. package/src/space/space.test.ts +3 -3
  150. package/src/space/space.ts +11 -11
  151. package/src/testing/index.ts +0 -2
  152. package/src/testing/test-agent-builder.ts +3 -3
  153. package/src/testing/test-network-adapter.ts +16 -3
  154. package/src/testing/test-replicator.ts +23 -18
  155. package/src/util.ts +7 -3
  156. package/dist/lib/browser/chunk-ANZAS5CC.mjs +0 -126
  157. package/dist/lib/browser/chunk-ANZAS5CC.mjs.map +0 -7
  158. package/dist/lib/browser/chunk-CGS2ULMK.mjs +0 -11
  159. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +0 -7
  160. package/dist/lib/browser/chunk-GBFX5J5B.mjs.map +0 -7
  161. package/dist/lib/browser/index.mjs.map +0 -7
  162. package/dist/lib/browser/meta.json +0 -1
  163. package/dist/lib/browser/testing/index.mjs.map +0 -7
  164. package/dist/lib/node-esm/chunk-2SAZ7CCF.mjs +0 -126
  165. package/dist/lib/node-esm/chunk-2SAZ7CCF.mjs.map +0 -7
  166. package/dist/lib/node-esm/chunk-FQFKWA3X.mjs +0 -2067
  167. package/dist/lib/node-esm/chunk-FQFKWA3X.mjs.map +0 -7
  168. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  169. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +0 -7
  170. package/dist/lib/node-esm/filter/index.mjs +0 -11
  171. package/dist/lib/node-esm/filter/index.mjs.map +0 -7
  172. package/dist/lib/node-esm/index.mjs +0 -4743
  173. package/dist/lib/node-esm/index.mjs.map +0 -7
  174. package/dist/lib/node-esm/meta.json +0 -1
  175. package/dist/lib/node-esm/testing/index.mjs +0 -742
  176. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  177. package/dist/types/src/db-host/documents-iterator.d.ts +0 -7
  178. package/dist/types/src/db-host/documents-iterator.d.ts.map +0 -1
  179. package/dist/types/src/testing/test-data.d.ts +0 -18
  180. package/dist/types/src/testing/test-data.d.ts.map +0 -1
  181. package/dist/types/src/testing/test-schema.d.ts +0 -37
  182. package/dist/types/src/testing/test-schema.d.ts.map +0 -1
  183. package/src/db-host/documents-iterator.ts +0 -74
  184. package/src/testing/test-data.ts +0 -127
  185. package/src/testing/test-schema.ts +0 -53
  186. /package/dist/lib/{browser → neutral}/filter/index.mjs.map +0 -0
@@ -0,0 +1,247 @@
1
+ import "@dxos/node-std/globals";
2
+
3
+ // src/filter/filter-match.ts
4
+ import { EncodedReference, ObjectStructure, isEncodedReference } from "@dxos/echo-protocol";
5
+ import { ATTR_META } from "@dxos/echo/internal";
6
+ import { DXN } from "@dxos/keys";
7
+ var filterMatchObject = (filter, obj) => {
8
+ switch (filter.type) {
9
+ case "object": {
10
+ if (filter.typename !== null) {
11
+ if (!obj.doc.system?.type?.["/"]) {
12
+ return false;
13
+ } else {
14
+ const actualDXN = DXN.parse(obj.doc.system.type["/"]);
15
+ const expectedDXN = DXN.parse(filter.typename);
16
+ if (!compareTypename(expectedDXN, actualDXN)) {
17
+ return false;
18
+ }
19
+ }
20
+ }
21
+ if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {
22
+ return false;
23
+ }
24
+ if (filter.props) {
25
+ for (const [key, valueFilter] of Object.entries(filter.props)) {
26
+ const value = obj.doc.data[key];
27
+ if (!filterMatchValue(valueFilter, value)) {
28
+ return false;
29
+ }
30
+ }
31
+ }
32
+ if (filter.foreignKeys && filter.foreignKeys.length > 0) {
33
+ const hasMatchingKey = filter.foreignKeys.some((filterKey) => obj.doc.meta.keys.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id));
34
+ if (!hasMatchingKey) {
35
+ return false;
36
+ }
37
+ }
38
+ return true;
39
+ }
40
+ case "tag": {
41
+ const tags = ObjectStructure.getTags(obj.doc);
42
+ return tags.some((tag) => tag === filter.tag);
43
+ }
44
+ case "text-search": {
45
+ return false;
46
+ }
47
+ case "timestamp": {
48
+ throw new Error("Timestamp filters must be handled at the index level, not in-memory matching.");
49
+ }
50
+ case "child-of": {
51
+ throw new Error("child-of filters must be handled at the executor level, not in-memory matching.");
52
+ }
53
+ case "not": {
54
+ return !filterMatchObject(filter.filter, obj);
55
+ }
56
+ case "and": {
57
+ return filter.filters.every((f) => filterMatchObject(f, obj));
58
+ }
59
+ case "or": {
60
+ return filter.filters.some((f) => filterMatchObject(f, obj));
61
+ }
62
+ default:
63
+ return false;
64
+ }
65
+ };
66
+ var filterMatchObjectJSON = (filter, obj) => {
67
+ switch (filter.type) {
68
+ case "object": {
69
+ if (filter.typename !== null) {
70
+ if (!obj["@type"]) {
71
+ return false;
72
+ } else {
73
+ const actualDXN = DXN.parse(obj["@type"]);
74
+ const expectedDXN = DXN.parse(filter.typename);
75
+ if (!compareTypename(expectedDXN, actualDXN)) {
76
+ return false;
77
+ }
78
+ }
79
+ }
80
+ if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {
81
+ return false;
82
+ }
83
+ if (filter.props) {
84
+ for (const [key, valueFilter] of Object.entries(filter.props)) {
85
+ if (key.startsWith("@")) {
86
+ continue;
87
+ }
88
+ const value = obj[key];
89
+ if (!filterMatchValue(valueFilter, value)) {
90
+ return false;
91
+ }
92
+ }
93
+ }
94
+ if (filter.foreignKeys && filter.foreignKeys.length > 0) {
95
+ const hasMatchingKey = filter.foreignKeys.some((filterKey) => obj["@meta"]?.keys?.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id));
96
+ if (!hasMatchingKey) {
97
+ return false;
98
+ }
99
+ }
100
+ return true;
101
+ }
102
+ case "tag": {
103
+ const tags = obj[ATTR_META]?.tags ?? [];
104
+ return tags.some((tag) => tag === filter.tag);
105
+ }
106
+ // TODO: Implement text search.
107
+ case "text-search": {
108
+ return false;
109
+ }
110
+ case "timestamp": {
111
+ throw new Error("Timestamp filters must be handled at the index level, not in-memory matching.");
112
+ }
113
+ case "child-of": {
114
+ throw new Error("child-of filters must be handled at the executor level, not in-memory matching.");
115
+ }
116
+ case "not": {
117
+ return !filterMatchObjectJSON(filter.filter, obj);
118
+ }
119
+ case "and": {
120
+ return filter.filters.every((f) => filterMatchObjectJSON(f, obj));
121
+ }
122
+ case "or": {
123
+ return filter.filters.some((f) => filterMatchObjectJSON(f, obj));
124
+ }
125
+ default:
126
+ return false;
127
+ }
128
+ };
129
+ var structuralMatch = (filterObj, targetObj, strict = true) => {
130
+ if (typeof filterObj !== "object" || filterObj === null) {
131
+ return filterObj === targetObj;
132
+ }
133
+ if (typeof targetObj !== "object" || targetObj === null) {
134
+ return false;
135
+ }
136
+ const filterKeys = Object.keys(filterObj);
137
+ const targetKeys = Object.keys(targetObj);
138
+ if (strict && filterKeys.length !== targetKeys.length) {
139
+ return false;
140
+ }
141
+ return filterKeys.every((key) => {
142
+ if (!(key in targetObj)) {
143
+ return false;
144
+ }
145
+ const filterValue = filterObj[key];
146
+ const targetValue = targetObj[key];
147
+ if (typeof filterValue === "object" && filterValue !== null) {
148
+ return structuralMatch(filterValue, targetValue);
149
+ }
150
+ return filterValue === targetValue;
151
+ });
152
+ };
153
+ var filterMatchValue = (filter, value) => {
154
+ switch (filter.type) {
155
+ case "compare": {
156
+ const compareValue = filter.value;
157
+ switch (filter.operator) {
158
+ case "eq":
159
+ if (isEncodedReference(compareValue)) {
160
+ if (!isEncodedReference(value)) {
161
+ return false;
162
+ }
163
+ return DXN.equals(EncodedReference.toDXN(value), EncodedReference.toDXN(compareValue));
164
+ }
165
+ return value === compareValue;
166
+ case "neq":
167
+ return value !== compareValue;
168
+ case "gt":
169
+ return value > compareValue;
170
+ case "gte":
171
+ return value >= compareValue;
172
+ case "lt":
173
+ return value < compareValue;
174
+ case "lte":
175
+ return value <= compareValue;
176
+ default:
177
+ return false;
178
+ }
179
+ }
180
+ case "object": {
181
+ if (typeof value !== "object" || value === null) {
182
+ return false;
183
+ }
184
+ if (filter.props) {
185
+ for (const [key, valueFilter] of Object.entries(filter.props)) {
186
+ const nestedValue = value[key];
187
+ if (!filterMatchValue(valueFilter, nestedValue)) {
188
+ return false;
189
+ }
190
+ }
191
+ }
192
+ return true;
193
+ }
194
+ case "in": {
195
+ return filter.values.includes(value);
196
+ }
197
+ case "contains": {
198
+ if (!Array.isArray(value)) {
199
+ return false;
200
+ }
201
+ return value.some((element) => {
202
+ if (typeof filter.value === "object" && filter.value !== null && !Array.isArray(filter.value)) {
203
+ return structuralMatch(filter.value, element);
204
+ }
205
+ return element === filter.value;
206
+ });
207
+ }
208
+ case "range": {
209
+ return value >= filter.from && value <= filter.to;
210
+ }
211
+ case "not": {
212
+ return !filterMatchValue(filter.filter, value);
213
+ }
214
+ case "and": {
215
+ return filter.filters.every((f) => filterMatchValue(f, value));
216
+ }
217
+ case "or": {
218
+ return filter.filters.some((f) => filterMatchValue(f, value));
219
+ }
220
+ default:
221
+ return false;
222
+ }
223
+ };
224
+ var compareTypename = (expectedDXN, actualDXN) => {
225
+ const expectedTypeDXN = expectedDXN.asTypeDXN();
226
+ if (expectedTypeDXN) {
227
+ const actualTypeDXN = actualDXN.asTypeDXN();
228
+ if (!actualTypeDXN) {
229
+ return false;
230
+ }
231
+ if (actualTypeDXN.type !== expectedTypeDXN.type || expectedTypeDXN.version !== void 0 && actualTypeDXN.version !== void 0 && actualTypeDXN.version !== expectedTypeDXN.version) {
232
+ return false;
233
+ }
234
+ } else {
235
+ if (!DXN.equals(actualDXN, expectedDXN)) {
236
+ return false;
237
+ }
238
+ }
239
+ return true;
240
+ };
241
+
242
+ export {
243
+ filterMatchObject,
244
+ filterMatchObjectJSON,
245
+ filterMatchValue
246
+ };
247
+ //# sourceMappingURL=chunk-76DA36YG.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/filter/filter-match.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { EncodedReference, ObjectStructure, type QueryAST, isEncodedReference } from '@dxos/echo-protocol';\nimport { ATTR_META, type ObjectJSON } from '@dxos/echo/internal';\nimport { DXN, type ObjectId, type SpaceId } from '@dxos/keys';\n\nexport type MatchedObject = {\n id: ObjectId;\n spaceId: SpaceId;\n doc: ObjectStructure;\n};\n\n/**\n * Matches an object against a filter AST.\n * @param obj object structure as stored in automerge.\n */\nexport const filterMatchObject = (filter: QueryAST.Filter, obj: MatchedObject): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified.\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj.doc.system?.type?.['/']) {\n // Objects with no type are deprecated.\n return false;\n } else {\n const actualDXN = DXN.parse(obj.doc.system.type['/']);\n const expectedDXN = DXN.parse(filter.typename);\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified.\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties.\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n const value = obj.doc.data[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified.\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj.doc.meta.keys.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'tag': {\n const tags = ObjectStructure.getTags(obj.doc);\n return tags.some((tag) => tag === filter.tag);\n }\n\n case 'text-search': {\n // TODO(???): Implement text search.\n return false;\n }\n\n case 'timestamp': {\n throw new Error('Timestamp filters must be handled at the index level, not in-memory matching.');\n }\n\n case 'child-of': {\n throw new Error('child-of filters must be handled at the executor level, not in-memory matching.');\n }\n\n case 'not': {\n return !filterMatchObject(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObject(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObject(f, obj));\n }\n\n default:\n return false;\n }\n};\n\n// TODO(burdon): Reconcile with filterMatchObject.\nexport const filterMatchObjectJSON = (filter: QueryAST.Filter, obj: ObjectJSON): boolean => {\n switch (filter.type) {\n case 'object': {\n // Check typename if specified\n if (filter.typename !== null) {\n // TODO(dmaretskyi): `system` is missing in some cases.\n if (!obj['@type']) {\n // Objects with no type are deprecated.\n return false;\n } else {\n const actualDXN = DXN.parse(obj['@type']);\n const expectedDXN = DXN.parse(filter.typename);\n if (!compareTypename(expectedDXN, actualDXN)) {\n return false;\n }\n }\n }\n\n // Check IDs if specified\n if (filter.id && filter.id.length > 0 && !filter.id.includes(obj.id)) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n if (key.startsWith('@')) {\n // ignore meta properties\n continue;\n }\n const value = (obj as any)[key];\n if (!filterMatchValue(valueFilter, value)) {\n return false;\n }\n }\n }\n\n // Check foreign keys if specified\n if (filter.foreignKeys && filter.foreignKeys.length > 0) {\n const hasMatchingKey = filter.foreignKeys.some((filterKey) =>\n obj['@meta']?.keys?.some((objKey) => objKey.source === filterKey.source && objKey.id === filterKey.id),\n );\n if (!hasMatchingKey) {\n return false;\n }\n }\n\n return true;\n }\n\n case 'tag': {\n const tags = obj[ATTR_META]?.tags ?? [];\n return tags.some((tag) => tag === filter.tag);\n }\n\n // TODO: Implement text search.\n case 'text-search': {\n return false;\n }\n\n case 'timestamp': {\n throw new Error('Timestamp filters must be handled at the index level, not in-memory matching.');\n }\n\n case 'child-of': {\n throw new Error('child-of filters must be handled at the executor level, not in-memory matching.');\n }\n\n case 'not': {\n return !filterMatchObjectJSON(filter.filter, obj);\n }\n\n case 'and': {\n return filter.filters.every((f) => filterMatchObjectJSON(f, obj));\n }\n\n case 'or': {\n return filter.filters.some((f) => filterMatchObjectJSON(f, obj));\n }\n\n default:\n return false;\n }\n};\n\n/**\n * Performs structural matching between a filter object and a target object.\n * This handles nested object comparison for array matching scenarios.\n */\n// TODO(wittjosiah): Add ast support for non-strict matching.\nconst structuralMatch = (filterObj: any, targetObj: any, strict = true): boolean => {\n if (typeof filterObj !== 'object' || filterObj === null) {\n return filterObj === targetObj;\n }\n\n if (typeof targetObj !== 'object' || targetObj === null) {\n return false;\n }\n\n // Prohibit extra keys in targetObj.\n const filterKeys = Object.keys(filterObj);\n const targetKeys = Object.keys(targetObj);\n if (strict && filterKeys.length !== targetKeys.length) {\n return false;\n }\n\n return filterKeys.every((key) => {\n if (!(key in targetObj)) {\n return false;\n }\n const filterValue = filterObj[key];\n const targetValue = targetObj[key];\n\n if (typeof filterValue === 'object' && filterValue !== null) {\n return structuralMatch(filterValue, targetValue);\n }\n\n return filterValue === targetValue;\n });\n};\n\nexport const filterMatchValue = (filter: QueryAST.Filter, value: unknown): boolean => {\n switch (filter.type) {\n case 'compare': {\n const compareValue = filter.value as any;\n switch (filter.operator) {\n case 'eq':\n if (isEncodedReference(compareValue)) {\n if (!isEncodedReference(value)) {\n return false;\n }\n return DXN.equals(EncodedReference.toDXN(value), EncodedReference.toDXN(compareValue));\n }\n return value === compareValue;\n case 'neq':\n return value !== compareValue;\n case 'gt':\n return (value as any) > compareValue;\n case 'gte':\n return (value as any) >= compareValue;\n case 'lt':\n return (value as any) < compareValue;\n case 'lte':\n return (value as any) <= compareValue;\n default:\n return false;\n }\n }\n case 'object': {\n // Handle nested object filters for property matching\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n // Check properties\n if (filter.props) {\n for (const [key, valueFilter] of Object.entries(filter.props)) {\n const nestedValue = (value as any)[key];\n if (!filterMatchValue(valueFilter, nestedValue)) {\n return false;\n }\n }\n }\n\n return true;\n }\n case 'in': {\n return filter.values.includes(value);\n }\n case 'contains': {\n if (!Array.isArray(value)) {\n return false;\n }\n\n return value.some((element) => {\n if (typeof filter.value === 'object' && filter.value !== null && !Array.isArray(filter.value)) {\n return structuralMatch(filter.value, element);\n }\n\n return element === filter.value;\n });\n }\n case 'range': {\n return (value as any) >= filter.from && (value as any) <= filter.to;\n }\n case 'not': {\n return !filterMatchValue(filter.filter, value);\n }\n case 'and': {\n return filter.filters.every((f) => filterMatchValue(f, value));\n }\n case 'or': {\n return filter.filters.some((f) => filterMatchValue(f, value));\n }\n default:\n return false;\n }\n};\n\n/**\n * Compares typename DXNs.\n * @returns true if they match\n *\n * Compares typename string.\n * Missing version (on either actual or expected) matches any version.\n * non `type` DXNs are compared exactly.\n *\n * Examples: (expected) (actual)\n *\n * dxn:type:com.example.type.task !== dxn:type:com.example.type.contact\n * dxn:type:com.example.type.task === dxn:type:com.example.type.task\n * dxn:type:com.example.type.task:0.1.0 !== dxn:type:com.example.type.task:0.2.0\n * dxn:type:com.example.type.task === dxn:type:com.example.type.task:0.1.0\n * dxn:type:com.example.type.task:0.1.0 === dxn:type:com.example.type.task\n *\n */\nconst compareTypename = (expectedDXN: DXN, actualDXN: DXN): boolean => {\n const expectedTypeDXN = expectedDXN.asTypeDXN();\n if (expectedTypeDXN) {\n const actualTypeDXN = actualDXN.asTypeDXN();\n if (!actualTypeDXN) {\n return false;\n }\n if (\n actualTypeDXN.type !== expectedTypeDXN.type ||\n (expectedTypeDXN.version !== undefined &&\n actualTypeDXN.version !== undefined &&\n actualTypeDXN.version !== expectedTypeDXN.version)\n ) {\n return false;\n }\n } else {\n if (!DXN.equals(actualDXN, expectedDXN)) {\n return false;\n }\n }\n return true;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["EncodedReference", "ObjectStructure", "isEncodedReference", "ATTR_META", "DXN", "filterMatchObject", "filter", "obj", "type", "typename", "doc", "system", "actualDXN", "DXN", "parse", "expectedDXN", "compareTypename", "id", "length", "includes", "props", "key", "valueFilter", "Object", "entries", "value", "data", "filterMatchValue", "foreignKeys", "hasMatchingKey", "some", "filterKey", "meta", "keys", "objKey", "source", "tags", "ObjectStructure", "getTags", "tag", "Error", "filters", "every", "f", "filterMatchObjectJSON", "startsWith", "ATTR_META", "structuralMatch", "filterObj", "targetObj", "strict", "filterKeys", "targetKeys", "filterValue", "targetValue", "compareValue", "operator", "isEncodedReference", "equals", "EncodedReference", "toDXN", "nestedValue", "values", "Array", "isArray", "element", "from", "to", "expectedTypeDXN", "asTypeDXN", "actualTypeDXN", "version", "undefined"]
7
+ }