@dxos/echo-pipeline 0.8.2-staging.7ac8446 → 0.8.2

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 (182) hide show
  1. package/dist/lib/browser/{chunk-32WDI3LB.mjs → chunk-3XSXS5EX.mjs} +15 -21
  2. package/dist/lib/browser/chunk-3XSXS5EX.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
  4. package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-TQJTKNMS.mjs +126 -0
  6. package/dist/lib/browser/chunk-TQJTKNMS.mjs.map +7 -0
  7. package/dist/lib/browser/filter/index.mjs +11 -0
  8. package/dist/lib/browser/filter/index.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +1380 -516
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/testing/index.mjs +202 -22
  13. package/dist/lib/browser/testing/index.mjs.map +4 -4
  14. package/dist/lib/node/chunk-HOPOFWAL.cjs +147 -0
  15. package/dist/lib/node/chunk-HOPOFWAL.cjs.map +7 -0
  16. package/dist/lib/node/chunk-Q7SFCCGT.cjs +33 -0
  17. package/dist/lib/node/chunk-Q7SFCCGT.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-TC2PRBEU.cjs → chunk-SG2PL5RH.cjs} +18 -24
  19. package/dist/lib/node/chunk-SG2PL5RH.cjs.map +7 -0
  20. package/dist/lib/node/filter/index.cjs +32 -0
  21. package/dist/lib/node/filter/index.cjs.map +7 -0
  22. package/dist/lib/node/index.cjs +1381 -525
  23. package/dist/lib/node/index.cjs.map +4 -4
  24. package/dist/lib/node/meta.json +1 -1
  25. package/dist/lib/node/testing/index.cjs +207 -31
  26. package/dist/lib/node/testing/index.cjs.map +4 -4
  27. package/dist/lib/node-esm/{chunk-UKOLB3LW.mjs → chunk-3BZP75TJ.mjs} +15 -21
  28. package/dist/lib/node-esm/chunk-3BZP75TJ.mjs.map +7 -0
  29. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  30. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  31. package/dist/lib/node-esm/chunk-RVK35BS7.mjs +126 -0
  32. package/dist/lib/node-esm/chunk-RVK35BS7.mjs.map +7 -0
  33. package/dist/lib/node-esm/filter/index.mjs +11 -0
  34. package/dist/lib/node-esm/filter/index.mjs.map +7 -0
  35. package/dist/lib/node-esm/index.mjs +1380 -516
  36. package/dist/lib/node-esm/index.mjs.map +4 -4
  37. package/dist/lib/node-esm/meta.json +1 -1
  38. package/dist/lib/node-esm/testing/index.mjs +202 -22
  39. package/dist/lib/node-esm/testing/index.mjs.map +4 -4
  40. package/dist/types/src/automerge/automerge-host.d.ts +6 -4
  41. package/dist/types/src/automerge/automerge-host.d.ts.map +1 -1
  42. package/dist/types/src/automerge/collection-synchronizer.d.ts +1 -1
  43. package/dist/types/src/automerge/collection-synchronizer.d.ts.map +1 -1
  44. package/dist/types/src/automerge/echo-data-monitor.d.ts +6 -6
  45. package/dist/types/src/automerge/echo-data-monitor.d.ts.map +1 -1
  46. package/dist/types/src/automerge/echo-network-adapter.d.ts +4 -1
  47. package/dist/types/src/automerge/echo-network-adapter.d.ts.map +1 -1
  48. package/dist/types/src/automerge/heads-store.d.ts +2 -2
  49. package/dist/types/src/automerge/heads-store.d.ts.map +1 -1
  50. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts +1 -1
  51. package/dist/types/src/automerge/leveldb-storage-adapter.d.ts.map +1 -1
  52. package/dist/types/src/automerge/mesh-echo-replicator-connection.d.ts.map +1 -1
  53. package/dist/types/src/automerge/mesh-echo-replicator.d.ts.map +1 -1
  54. package/dist/types/src/automerge/network-protocol.d.ts +1 -1
  55. package/dist/types/src/automerge/network-protocol.d.ts.map +1 -1
  56. package/dist/types/src/automerge/space-collection.d.ts +1 -1
  57. package/dist/types/src/automerge/space-collection.d.ts.map +1 -1
  58. package/dist/types/src/common/feeds.d.ts.map +1 -1
  59. package/dist/types/src/common/space-id.d.ts.map +1 -1
  60. package/dist/types/src/db-host/automerge-metrics.d.ts +1 -1
  61. package/dist/types/src/db-host/automerge-metrics.d.ts.map +1 -1
  62. package/dist/types/src/db-host/data-service.d.ts.map +1 -1
  63. package/dist/types/src/db-host/database-root.d.ts +7 -7
  64. package/dist/types/src/db-host/database-root.d.ts.map +1 -1
  65. package/dist/types/src/db-host/documents-iterator.d.ts +1 -1
  66. package/dist/types/src/db-host/documents-iterator.d.ts.map +1 -1
  67. package/dist/types/src/db-host/documents-synchronizer.d.ts +4 -4
  68. package/dist/types/src/db-host/documents-synchronizer.d.ts.map +1 -1
  69. package/dist/types/src/db-host/echo-host.d.ts +13 -2
  70. package/dist/types/src/db-host/echo-host.d.ts.map +1 -1
  71. package/dist/types/src/db-host/index.d.ts +0 -1
  72. package/dist/types/src/db-host/index.d.ts.map +1 -1
  73. package/dist/types/src/db-host/query-service.d.ts +2 -0
  74. package/dist/types/src/db-host/query-service.d.ts.map +1 -1
  75. package/dist/types/src/db-host/space-state-manager.d.ts +4 -3
  76. package/dist/types/src/db-host/space-state-manager.d.ts.map +1 -1
  77. package/dist/types/src/edge/echo-edge-replicator.d.ts.map +1 -1
  78. package/dist/types/src/edge/inflight-request-limiter.d.ts.map +1 -1
  79. package/dist/types/src/filter/filter-match.d.ts +13 -0
  80. package/dist/types/src/filter/filter-match.d.ts.map +1 -0
  81. package/dist/types/src/filter/filter-match.test.d.ts +2 -0
  82. package/dist/types/src/filter/filter-match.test.d.ts.map +1 -0
  83. package/dist/types/src/filter/index.d.ts +2 -0
  84. package/dist/types/src/filter/index.d.ts.map +1 -0
  85. package/dist/types/src/index.d.ts +1 -0
  86. package/dist/types/src/index.d.ts.map +1 -1
  87. package/dist/types/src/metadata/metadata-store.d.ts.map +1 -1
  88. package/dist/types/src/pipeline/message-selector.d.ts.map +1 -1
  89. package/dist/types/src/pipeline/pipeline.d.ts.map +1 -1
  90. package/dist/types/src/pipeline/timeframe-clock.d.ts.map +1 -1
  91. package/dist/types/src/query/errors.d.ts +23 -0
  92. package/dist/types/src/query/errors.d.ts.map +1 -0
  93. package/dist/types/src/query/index.d.ts +5 -0
  94. package/dist/types/src/query/index.d.ts.map +1 -0
  95. package/dist/types/src/query/plan.d.ts +132 -0
  96. package/dist/types/src/query/plan.d.ts.map +1 -0
  97. package/dist/types/src/query/query-executor.d.ts +83 -0
  98. package/dist/types/src/query/query-executor.d.ts.map +1 -0
  99. package/dist/types/src/query/query-planner.d.ts +33 -0
  100. package/dist/types/src/query/query-planner.d.ts.map +1 -0
  101. package/dist/types/src/query/query-planner.test.d.ts +2 -0
  102. package/dist/types/src/query/query-planner.test.d.ts.map +1 -0
  103. package/dist/types/src/space/admission-discovery-extension.d.ts.map +1 -1
  104. package/dist/types/src/space/control-pipeline.d.ts.map +1 -1
  105. package/dist/types/src/space/space-manager.d.ts.map +1 -1
  106. package/dist/types/src/space/space-protocol.d.ts.map +1 -1
  107. package/dist/types/src/space/space.d.ts.map +1 -1
  108. package/dist/types/src/testing/change-metadata.d.ts.map +1 -1
  109. package/dist/types/src/testing/index.d.ts +2 -0
  110. package/dist/types/src/testing/index.d.ts.map +1 -1
  111. package/dist/types/src/testing/test-agent-builder.d.ts.map +1 -1
  112. package/dist/types/src/testing/test-data.d.ts +18 -0
  113. package/dist/types/src/testing/test-data.d.ts.map +1 -0
  114. package/dist/types/src/testing/test-network-adapter.d.ts +3 -2
  115. package/dist/types/src/testing/test-network-adapter.d.ts.map +1 -1
  116. package/dist/types/src/testing/test-schema.d.ts +39 -0
  117. package/dist/types/src/testing/test-schema.d.ts.map +1 -0
  118. package/dist/types/src/util.d.ts +2 -2
  119. package/dist/types/src/util.d.ts.map +1 -1
  120. package/dist/types/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +43 -34
  122. package/src/automerge/automerge-host.test.ts +7 -7
  123. package/src/automerge/automerge-host.ts +58 -60
  124. package/src/automerge/automerge-repo.test.ts +65 -65
  125. package/src/automerge/collection-synchronizer.test.ts +1 -1
  126. package/src/automerge/collection-synchronizer.ts +11 -10
  127. package/src/automerge/echo-data-monitor.ts +21 -20
  128. package/src/automerge/echo-network-adapter.test.ts +1 -1
  129. package/src/automerge/echo-network-adapter.ts +25 -18
  130. package/src/automerge/heads-store.ts +4 -3
  131. package/src/automerge/leveldb-storage-adapter.ts +1 -1
  132. package/src/automerge/mesh-echo-replicator-connection.ts +6 -5
  133. package/src/automerge/mesh-echo-replicator.ts +2 -2
  134. package/src/automerge/network-protocol.ts +2 -1
  135. package/src/automerge/space-collection.ts +2 -1
  136. package/src/db-host/automerge-metrics.ts +2 -1
  137. package/src/db-host/data-service.ts +4 -3
  138. package/src/db-host/database-root.ts +17 -22
  139. package/src/db-host/documents-iterator.ts +9 -8
  140. package/src/db-host/documents-synchronizer.test.ts +2 -2
  141. package/src/db-host/documents-synchronizer.ts +20 -18
  142. package/src/db-host/echo-host.ts +44 -15
  143. package/src/db-host/index.ts +0 -1
  144. package/src/db-host/query-service.ts +43 -37
  145. package/src/db-host/space-state-manager.ts +14 -4
  146. package/src/edge/echo-edge-replicator.test.ts +3 -3
  147. package/src/edge/echo-edge-replicator.ts +9 -8
  148. package/src/edge/inflight-request-limiter.ts +4 -4
  149. package/src/filter/filter-match.test.ts +101 -0
  150. package/src/filter/filter-match.ts +174 -0
  151. package/src/filter/index.ts +5 -0
  152. package/src/index.ts +1 -0
  153. package/src/metadata/metadata-store.ts +13 -13
  154. package/src/pipeline/pipeline-stress.test.ts +9 -9
  155. package/src/pipeline/pipeline.ts +13 -13
  156. package/src/pipeline/timeframe-clock.ts +5 -5
  157. package/src/query/errors.ts +7 -0
  158. package/src/query/index.ts +8 -0
  159. package/src/query/plan.ts +179 -0
  160. package/src/query/query-executor.ts +648 -0
  161. package/src/query/query-planner.test.ts +613 -0
  162. package/src/query/query-planner.ts +470 -0
  163. package/src/space/admission-discovery-extension.ts +2 -2
  164. package/src/space/control-pipeline.ts +8 -8
  165. package/src/space/space-manager.ts +5 -4
  166. package/src/space/space-protocol.browser.test.ts +1 -0
  167. package/src/space/space-protocol.test.ts +1 -0
  168. package/src/space/space-protocol.ts +4 -4
  169. package/src/space/space.ts +5 -5
  170. package/src/testing/index.ts +2 -0
  171. package/src/testing/test-agent-builder.ts +6 -6
  172. package/src/testing/test-data.ts +127 -0
  173. package/src/testing/test-network-adapter.ts +15 -12
  174. package/src/testing/test-replicator.ts +2 -2
  175. package/src/testing/test-schema.ts +53 -0
  176. package/src/util.ts +7 -3
  177. package/dist/lib/browser/chunk-32WDI3LB.mjs.map +0 -7
  178. package/dist/lib/node/chunk-TC2PRBEU.cjs.map +0 -7
  179. package/dist/lib/node-esm/chunk-UKOLB3LW.mjs.map +0 -7
  180. package/dist/types/src/db-host/query-state.d.ts +0 -41
  181. package/dist/types/src/db-host/query-state.d.ts.map +0 -1
  182. package/src/db-host/query-state.ts +0 -217
@@ -0,0 +1,613 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import { describe, expect, test } from 'vitest';
6
+
7
+ import { type QueryAST } from '@dxos/echo-protocol';
8
+ import { Filter, Query } from '@dxos/echo-schema';
9
+ import { SpaceId } from '@dxos/keys';
10
+
11
+ import { QueryPlanner } from './query-planner';
12
+ import { TestSchema } from '../testing';
13
+
14
+ describe('QueryPlanner', () => {
15
+ const planner = new QueryPlanner();
16
+
17
+ test('get all people', () => {
18
+ const query = Query.select(Filter.type(TestSchema.Person));
19
+
20
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
21
+ expect(plan).toMatchInlineSnapshot(`
22
+ {
23
+ "steps": [
24
+ {
25
+ "_tag": "SelectStep",
26
+ "selector": {
27
+ "_tag": "TypeSelector",
28
+ "inverted": false,
29
+ "typename": [
30
+ "dxn:type:dxos.org/type/Person:0.1.0",
31
+ ],
32
+ },
33
+ "spaces": [
34
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
35
+ ],
36
+ },
37
+ {
38
+ "_tag": "FilterDeletedStep",
39
+ "mode": "only-non-deleted",
40
+ },
41
+ ],
42
+ }
43
+ `);
44
+ });
45
+
46
+ test('get all people named Fred', () => {
47
+ const query = Query.select(Filter.type(TestSchema.Person, { name: 'Fred' }));
48
+
49
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
50
+ expect(plan).toMatchInlineSnapshot(`
51
+ {
52
+ "steps": [
53
+ {
54
+ "_tag": "SelectStep",
55
+ "selector": {
56
+ "_tag": "TypeSelector",
57
+ "inverted": false,
58
+ "typename": [
59
+ "dxn:type:dxos.org/type/Person:0.1.0",
60
+ ],
61
+ },
62
+ "spaces": [
63
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
64
+ ],
65
+ },
66
+ {
67
+ "_tag": "FilterDeletedStep",
68
+ "mode": "only-non-deleted",
69
+ },
70
+ {
71
+ "_tag": "FilterStep",
72
+ "filter": {
73
+ "id": undefined,
74
+ "props": {
75
+ "name": {
76
+ "operator": "eq",
77
+ "type": "compare",
78
+ "value": "Fred",
79
+ },
80
+ },
81
+ "type": "object",
82
+ "typename": null,
83
+ },
84
+ },
85
+ ],
86
+ }
87
+ `);
88
+ });
89
+
90
+ test('get all orgs Fred worked for since 2020', () => {
91
+ const query = Query.select(Filter.type(TestSchema.Person, { id: '01JVS9YYT5VMVJW0GGTM1YHCCH' }))
92
+ .sourceOf(TestSchema.WorksFor, { since: Filter.gt('2020') })
93
+ .target();
94
+
95
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
96
+ expect(plan).toMatchInlineSnapshot(`
97
+ {
98
+ "steps": [
99
+ {
100
+ "_tag": "SelectStep",
101
+ "selector": {
102
+ "_tag": "IdSelector",
103
+ "objectIds": [
104
+ "01JVS9YYT5VMVJW0GGTM1YHCCH",
105
+ ],
106
+ },
107
+ "spaces": [
108
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
109
+ ],
110
+ },
111
+ {
112
+ "_tag": "FilterDeletedStep",
113
+ "mode": "only-non-deleted",
114
+ },
115
+ {
116
+ "_tag": "FilterStep",
117
+ "filter": {
118
+ "id": undefined,
119
+ "props": {},
120
+ "type": "object",
121
+ "typename": "dxn:type:dxos.org/type/Person:0.1.0",
122
+ },
123
+ },
124
+ {
125
+ "_tag": "TraverseStep",
126
+ "traversal": {
127
+ "_tag": "RelationTraversal",
128
+ "direction": "source-to-relation",
129
+ },
130
+ },
131
+ {
132
+ "_tag": "FilterDeletedStep",
133
+ "mode": "only-non-deleted",
134
+ },
135
+ {
136
+ "_tag": "FilterStep",
137
+ "filter": {
138
+ "id": undefined,
139
+ "props": {
140
+ "since": {
141
+ "operator": "gt",
142
+ "type": "compare",
143
+ "value": "2020",
144
+ },
145
+ },
146
+ "type": "object",
147
+ "typename": "dxn:type:dxos.org/type/WorksFor:0.1.0",
148
+ },
149
+ },
150
+ {
151
+ "_tag": "TraverseStep",
152
+ "traversal": {
153
+ "_tag": "RelationTraversal",
154
+ "direction": "relation-to-target",
155
+ },
156
+ },
157
+ {
158
+ "_tag": "FilterDeletedStep",
159
+ "mode": "only-non-deleted",
160
+ },
161
+ ],
162
+ }
163
+ `);
164
+ });
165
+
166
+ test('get all tasks for Fred', () => {
167
+ const query = Query.select(Filter.type(TestSchema.Person, { id: '01JVS9YYT7H6A6DXRN56RSHT6Z' })).referencedBy(
168
+ TestSchema.Task,
169
+ 'assignee',
170
+ );
171
+
172
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
173
+ expect(plan).toMatchInlineSnapshot(`
174
+ {
175
+ "steps": [
176
+ {
177
+ "_tag": "SelectStep",
178
+ "selector": {
179
+ "_tag": "IdSelector",
180
+ "objectIds": [
181
+ "01JVS9YYT7H6A6DXRN56RSHT6Z",
182
+ ],
183
+ },
184
+ "spaces": [
185
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
186
+ ],
187
+ },
188
+ {
189
+ "_tag": "FilterDeletedStep",
190
+ "mode": "only-non-deleted",
191
+ },
192
+ {
193
+ "_tag": "FilterStep",
194
+ "filter": {
195
+ "id": undefined,
196
+ "props": {},
197
+ "type": "object",
198
+ "typename": "dxn:type:dxos.org/type/Person:0.1.0",
199
+ },
200
+ },
201
+ {
202
+ "_tag": "TraverseStep",
203
+ "traversal": {
204
+ "_tag": "ReferenceTraversal",
205
+ "direction": "incoming",
206
+ "property": "assignee",
207
+ },
208
+ },
209
+ {
210
+ "_tag": "FilterDeletedStep",
211
+ "mode": "only-non-deleted",
212
+ },
213
+ {
214
+ "_tag": "FilterStep",
215
+ "filter": {
216
+ "props": {},
217
+ "type": "object",
218
+ "typename": "dxn:type:dxos.org/type/Task:0.1.0",
219
+ },
220
+ },
221
+ ],
222
+ }
223
+ `);
224
+ });
225
+
226
+ test('get all tasks for employees of Cyberdyne', () => {
227
+ const query = Query.select(Filter.type(TestSchema.Organization, { name: 'Cyberdyne' }))
228
+ .targetOf(TestSchema.WorksFor)
229
+ .source()
230
+ .referencedBy(TestSchema.Task, 'assignee');
231
+
232
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
233
+ expect(plan).toMatchInlineSnapshot(`
234
+ {
235
+ "steps": [
236
+ {
237
+ "_tag": "SelectStep",
238
+ "selector": {
239
+ "_tag": "TypeSelector",
240
+ "inverted": false,
241
+ "typename": [
242
+ "dxn:type:dxos.org/type/Organization:0.1.0",
243
+ ],
244
+ },
245
+ "spaces": [
246
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
247
+ ],
248
+ },
249
+ {
250
+ "_tag": "FilterDeletedStep",
251
+ "mode": "only-non-deleted",
252
+ },
253
+ {
254
+ "_tag": "FilterStep",
255
+ "filter": {
256
+ "id": undefined,
257
+ "props": {
258
+ "name": {
259
+ "operator": "eq",
260
+ "type": "compare",
261
+ "value": "Cyberdyne",
262
+ },
263
+ },
264
+ "type": "object",
265
+ "typename": null,
266
+ },
267
+ },
268
+ {
269
+ "_tag": "TraverseStep",
270
+ "traversal": {
271
+ "_tag": "RelationTraversal",
272
+ "direction": "target-to-relation",
273
+ },
274
+ },
275
+ {
276
+ "_tag": "FilterDeletedStep",
277
+ "mode": "only-non-deleted",
278
+ },
279
+ {
280
+ "_tag": "FilterStep",
281
+ "filter": {
282
+ "id": undefined,
283
+ "props": {},
284
+ "type": "object",
285
+ "typename": "dxn:type:dxos.org/type/WorksFor:0.1.0",
286
+ },
287
+ },
288
+ {
289
+ "_tag": "TraverseStep",
290
+ "traversal": {
291
+ "_tag": "RelationTraversal",
292
+ "direction": "relation-to-source",
293
+ },
294
+ },
295
+ {
296
+ "_tag": "FilterDeletedStep",
297
+ "mode": "only-non-deleted",
298
+ },
299
+ {
300
+ "_tag": "TraverseStep",
301
+ "traversal": {
302
+ "_tag": "ReferenceTraversal",
303
+ "direction": "incoming",
304
+ "property": "assignee",
305
+ },
306
+ },
307
+ {
308
+ "_tag": "FilterDeletedStep",
309
+ "mode": "only-non-deleted",
310
+ },
311
+ {
312
+ "_tag": "FilterStep",
313
+ "filter": {
314
+ "props": {},
315
+ "type": "object",
316
+ "typename": "dxn:type:dxos.org/type/Task:0.1.0",
317
+ },
318
+ },
319
+ ],
320
+ }
321
+ `);
322
+ });
323
+
324
+ test('get all people or orgs', () => {
325
+ const query = Query.all(
326
+ Query.select(Filter.type(TestSchema.Person)),
327
+ Query.select(Filter.type(TestSchema.Organization)),
328
+ );
329
+
330
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
331
+ expect(plan).toMatchInlineSnapshot(`
332
+ {
333
+ "steps": [
334
+ {
335
+ "_tag": "UnionStep",
336
+ "plans": [
337
+ {
338
+ "steps": [
339
+ {
340
+ "_tag": "SelectStep",
341
+ "selector": {
342
+ "_tag": "TypeSelector",
343
+ "inverted": false,
344
+ "typename": [
345
+ "dxn:type:dxos.org/type/Person:0.1.0",
346
+ ],
347
+ },
348
+ "spaces": [
349
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
350
+ ],
351
+ },
352
+ {
353
+ "_tag": "FilterDeletedStep",
354
+ "mode": "only-non-deleted",
355
+ },
356
+ ],
357
+ },
358
+ {
359
+ "steps": [
360
+ {
361
+ "_tag": "SelectStep",
362
+ "selector": {
363
+ "_tag": "TypeSelector",
364
+ "inverted": false,
365
+ "typename": [
366
+ "dxn:type:dxos.org/type/Organization:0.1.0",
367
+ ],
368
+ },
369
+ "spaces": [
370
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
371
+ ],
372
+ },
373
+ {
374
+ "_tag": "FilterDeletedStep",
375
+ "mode": "only-non-deleted",
376
+ },
377
+ ],
378
+ },
379
+ ],
380
+ },
381
+ ],
382
+ }
383
+ `);
384
+ });
385
+
386
+ test('get assignees of all tasks created after 2020', () => {
387
+ const query = Query.select(Filter.type(TestSchema.Task, { createdAt: Filter.gt('2020') })).reference('assignee');
388
+
389
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
390
+ expect(plan).toMatchInlineSnapshot(`
391
+ {
392
+ "steps": [
393
+ {
394
+ "_tag": "SelectStep",
395
+ "selector": {
396
+ "_tag": "TypeSelector",
397
+ "inverted": false,
398
+ "typename": [
399
+ "dxn:type:dxos.org/type/Task:0.1.0",
400
+ ],
401
+ },
402
+ "spaces": [
403
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
404
+ ],
405
+ },
406
+ {
407
+ "_tag": "FilterDeletedStep",
408
+ "mode": "only-non-deleted",
409
+ },
410
+ {
411
+ "_tag": "FilterStep",
412
+ "filter": {
413
+ "id": undefined,
414
+ "props": {
415
+ "createdAt": {
416
+ "operator": "gt",
417
+ "type": "compare",
418
+ "value": "2020",
419
+ },
420
+ },
421
+ "type": "object",
422
+ "typename": null,
423
+ },
424
+ },
425
+ {
426
+ "_tag": "TraverseStep",
427
+ "traversal": {
428
+ "_tag": "ReferenceTraversal",
429
+ "direction": "outgoing",
430
+ "property": "assignee",
431
+ },
432
+ },
433
+ {
434
+ "_tag": "FilterDeletedStep",
435
+ "mode": "only-non-deleted",
436
+ },
437
+ ],
438
+ }
439
+ `);
440
+ });
441
+
442
+ test('contact full-text search', () => {
443
+ const query = Query.select(Filter.text('Bill')).select(Filter.type(TestSchema.Person));
444
+
445
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
446
+ expect(plan).toMatchInlineSnapshot(`
447
+ {
448
+ "steps": [
449
+ {
450
+ "_tag": "SelectStep",
451
+ "selector": {
452
+ "_tag": "TextSelector",
453
+ "searchKind": "full-text",
454
+ "text": "Bill",
455
+ },
456
+ "spaces": [
457
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
458
+ ],
459
+ },
460
+ {
461
+ "_tag": "FilterDeletedStep",
462
+ "mode": "only-non-deleted",
463
+ },
464
+ {
465
+ "_tag": "FilterStep",
466
+ "filter": {
467
+ "id": undefined,
468
+ "props": {},
469
+ "type": "object",
470
+ "typename": "dxn:type:dxos.org/type/Person:0.1.0",
471
+ },
472
+ },
473
+ ],
474
+ }
475
+ `);
476
+ });
477
+
478
+ test('vector search', () => {
479
+ const query = Query.select(Filter.text('Bill', { type: 'vector' }));
480
+
481
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
482
+ expect(plan).toMatchInlineSnapshot(`
483
+ {
484
+ "steps": [
485
+ {
486
+ "_tag": "SelectStep",
487
+ "selector": {
488
+ "_tag": "TextSelector",
489
+ "searchKind": "vector",
490
+ "text": "Bill",
491
+ },
492
+ "spaces": [
493
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
494
+ ],
495
+ },
496
+ {
497
+ "_tag": "FilterDeletedStep",
498
+ "mode": "only-non-deleted",
499
+ },
500
+ ],
501
+ }
502
+ `);
503
+ });
504
+
505
+ test('select multiple types', () => {
506
+ const query = Query.select(Filter.or(Filter.type(TestSchema.Organization), Filter.type(TestSchema.Person)));
507
+
508
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
509
+ expect(plan).toMatchInlineSnapshot(`
510
+ {
511
+ "steps": [
512
+ {
513
+ "_tag": "SelectStep",
514
+ "selector": {
515
+ "_tag": "TypeSelector",
516
+ "inverted": false,
517
+ "typename": [
518
+ "dxn:type:dxos.org/type/Organization:0.1.0",
519
+ "dxn:type:dxos.org/type/Person:0.1.0",
520
+ ],
521
+ },
522
+ "spaces": [
523
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
524
+ ],
525
+ },
526
+ {
527
+ "_tag": "FilterDeletedStep",
528
+ "mode": "only-non-deleted",
529
+ },
530
+ ],
531
+ }
532
+ `);
533
+ });
534
+
535
+ // TODO(dmaretskyi): Implement this.
536
+ test.skip('select everything but the type', () => {
537
+ const query = Query.select(Filter.not(Filter.type(TestSchema.Person)));
538
+
539
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
540
+ expect(plan).toMatchInlineSnapshot();
541
+ });
542
+
543
+ test('select excluding multiple types', () => {
544
+ const query = Query.select(
545
+ Filter.not(Filter.or(Filter.type(TestSchema.Organization), Filter.type(TestSchema.Person))),
546
+ );
547
+
548
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
549
+ expect(plan).toMatchInlineSnapshot(`
550
+ {
551
+ "steps": [
552
+ {
553
+ "_tag": "SelectStep",
554
+ "selector": {
555
+ "_tag": "TypeSelector",
556
+ "inverted": true,
557
+ "typename": [
558
+ "dxn:type:dxos.org/type/Organization:0.1.0",
559
+ "dxn:type:dxos.org/type/Person:0.1.0",
560
+ ],
561
+ },
562
+ "spaces": [
563
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
564
+ ],
565
+ },
566
+ {
567
+ "_tag": "FilterDeletedStep",
568
+ "mode": "only-non-deleted",
569
+ },
570
+ ],
571
+ }
572
+ `);
573
+ });
574
+
575
+ test('select deleted tasks', () => {
576
+ const query = Query.select(Filter.type(TestSchema.Task)).options({ deleted: 'only' });
577
+
578
+ const plan = planner.createPlan(withSpaceIdOptions(query.ast));
579
+ expect(plan).toMatchInlineSnapshot(`
580
+ {
581
+ "steps": [
582
+ {
583
+ "_tag": "SelectStep",
584
+ "selector": {
585
+ "_tag": "TypeSelector",
586
+ "inverted": false,
587
+ "typename": [
588
+ "dxn:type:dxos.org/type/Task:0.1.0",
589
+ ],
590
+ },
591
+ "spaces": [
592
+ "B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO",
593
+ ],
594
+ },
595
+ {
596
+ "_tag": "FilterDeletedStep",
597
+ "mode": "only-deleted",
598
+ },
599
+ ],
600
+ }
601
+ `);
602
+ });
603
+ });
604
+
605
+ const SPACE_ID = SpaceId.make('B2NJDFNVZIW77OQSXUBNAD7BUMBD3G5PO'); // Stable id for inline snapshots.
606
+
607
+ const withSpaceIdOptions = (query: QueryAST.Query): QueryAST.Query => ({
608
+ type: 'options',
609
+ query,
610
+ options: {
611
+ spaceIds: [SPACE_ID],
612
+ },
613
+ });