@dxos/echo-protocol 0.8.4-main.dedc0f3 → 0.8.4-main.e098934

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/echo-protocol",
3
- "version": "0.8.4-main.dedc0f3",
3
+ "version": "0.8.4-main.e098934",
4
4
  "description": "Core ECHO APIs.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -27,11 +27,11 @@
27
27
  ],
28
28
  "dependencies": {
29
29
  "effect": "3.17.7",
30
- "@dxos/crypto": "0.8.4-main.dedc0f3",
31
- "@dxos/keys": "0.8.4-main.dedc0f3",
32
- "@dxos/invariant": "0.8.4-main.dedc0f3",
33
- "@dxos/protocols": "0.8.4-main.dedc0f3",
34
- "@dxos/util": "0.8.4-main.dedc0f3"
30
+ "@dxos/crypto": "0.8.4-main.e098934",
31
+ "@dxos/invariant": "0.8.4-main.e098934",
32
+ "@dxos/keys": "0.8.4-main.e098934",
33
+ "@dxos/util": "0.8.4-main.e098934",
34
+ "@dxos/protocols": "0.8.4-main.e098934"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
package/src/query/ast.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Schema } from 'effect';
5
+ import { Match, Schema } from 'effect';
6
6
 
7
7
  import { DXN, ObjectId } from '@dxos/keys';
8
8
 
@@ -61,6 +61,17 @@ const FilterIn_ = Schema.Struct({
61
61
  export interface FilterIn extends Schema.Schema.Type<typeof FilterIn_> {}
62
62
  export const FilterIn: Schema.Schema<FilterIn> = FilterIn_;
63
63
 
64
+ const FilterContains_ = Schema.Struct({
65
+ type: Schema.Literal('contains'),
66
+ value: Schema.Any,
67
+ });
68
+ export interface FilterContains extends Schema.Schema.Type<typeof FilterContains_> {}
69
+ /**
70
+ * Predicate for an array property to contain the provided value.
71
+ * Nested objects are matched using strict structural matching.
72
+ */
73
+ export const FilterContains: Schema.Schema<FilterContains> = FilterContains_;
74
+
64
75
  const FilterRange_ = Schema.Struct({
65
76
  type: Schema.Literal('range'),
66
77
  from: Schema.Any,
@@ -103,6 +114,7 @@ export const Filter = Schema.Union(
103
114
  FilterTextSearch,
104
115
  FilterCompare,
105
116
  FilterIn,
117
+ FilterContains,
106
118
  FilterRange,
107
119
  FilterNot,
108
120
  FilterAnd,
@@ -284,56 +296,41 @@ export const QueryOptions = Schema.Struct({
284
296
  export interface QueryOptions extends Schema.Schema.Type<typeof QueryOptions> {}
285
297
 
286
298
  export const visit = (query: Query, visitor: (node: Query) => void) => {
287
- switch (query.type) {
288
- case 'filter':
289
- visit(query.selection, visitor);
290
- break;
291
- case 'reference-traversal':
292
- visit(query.anchor, visitor);
293
- break;
294
- case 'incoming-references':
295
- visit(query.anchor, visitor);
296
- break;
297
- case 'relation':
298
- visit(query.anchor, visitor);
299
- break;
300
- case 'options':
301
- visit(query.query, visitor);
302
- break;
303
- case 'relation-traversal':
304
- visit(query.anchor, visitor);
305
- break;
306
- case 'union':
307
- query.queries.forEach((q) => visit(q, visitor));
308
- break;
309
- case 'set-difference':
310
- visit(query.source, visitor);
311
- visit(query.exclude, visitor);
312
- break;
313
- }
299
+ visitor(query);
300
+
301
+ Match.value(query).pipe(
302
+ Match.when({ type: 'filter' }, ({ selection }) => visit(selection, visitor)),
303
+ Match.when({ type: 'reference-traversal' }, ({ anchor }) => visit(anchor, visitor)),
304
+ Match.when({ type: 'incoming-references' }, ({ anchor }) => visit(anchor, visitor)),
305
+ Match.when({ type: 'relation' }, ({ anchor }) => visit(anchor, visitor)),
306
+ Match.when({ type: 'options' }, ({ query }) => visit(query, visitor)),
307
+ Match.when({ type: 'relation-traversal' }, ({ anchor }) => visit(anchor, visitor)),
308
+ Match.when({ type: 'union' }, ({ queries }) => queries.forEach((q) => visit(q, visitor))),
309
+ Match.when({ type: 'set-difference' }, ({ source, exclude }) => {
310
+ visit(source, visitor);
311
+ visit(exclude, visitor);
312
+ }),
313
+ Match.when({ type: 'order' }, ({ query }) => visit(query, visitor)),
314
+ Match.when({ type: 'select' }, () => {}),
315
+ Match.exhaustive,
316
+ );
314
317
  };
315
318
 
316
319
  export const fold = <T>(query: Query, reducer: (node: Query) => T): T[] => {
317
- switch (query.type) {
318
- case 'filter':
319
- return fold(query.selection, reducer);
320
- case 'reference-traversal':
321
- return fold(query.anchor, reducer);
322
- case 'incoming-references':
323
- return fold(query.anchor, reducer);
324
- case 'relation':
325
- return fold(query.anchor, reducer);
326
- case 'options':
327
- return fold(query.query, reducer);
328
- case 'relation-traversal':
329
- return fold(query.anchor, reducer);
330
- case 'union':
331
- return query.queries.flatMap((q: Query) => fold(q, reducer));
332
- case 'set-difference':
333
- return fold(query.source, reducer);
334
- case 'order':
335
- return fold(query.query, reducer);
336
- case 'select':
337
- return [];
338
- }
320
+ return Match.value(query).pipe(
321
+ Match.withReturnType<T[]>(),
322
+ Match.when({ type: 'filter' }, ({ selection }) => fold(selection, reducer)),
323
+ Match.when({ type: 'reference-traversal' }, ({ anchor }) => fold(anchor, reducer)),
324
+ Match.when({ type: 'incoming-references' }, ({ anchor }) => fold(anchor, reducer)),
325
+ Match.when({ type: 'relation' }, ({ anchor }) => fold(anchor, reducer)),
326
+ Match.when({ type: 'options' }, ({ query }) => fold(query, reducer)),
327
+ Match.when({ type: 'relation-traversal' }, ({ anchor }) => fold(anchor, reducer)),
328
+ Match.when({ type: 'union' }, ({ queries }) => queries.flatMap((q) => fold(q, reducer))),
329
+ Match.when({ type: 'set-difference' }, ({ source, exclude }) =>
330
+ fold(source, reducer).concat(fold(exclude, reducer)),
331
+ ),
332
+ Match.when({ type: 'order' }, ({ query }) => fold(query, reducer)),
333
+ Match.when({ type: 'select' }, () => []),
334
+ Match.exhaustive,
335
+ );
339
336
  };