@dxos/echo-protocol 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b

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.3eb6e50203",
3
+ "version": "0.8.4-main.3fbcb4aa9b",
4
4
  "description": "Core ECHO APIs.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -20,20 +20,17 @@
20
20
  }
21
21
  },
22
22
  "types": "dist/types/src/index.d.ts",
23
- "typesVersions": {
24
- "*": {}
25
- },
26
23
  "files": [
27
24
  "dist",
28
25
  "src"
29
26
  ],
30
27
  "dependencies": {
31
- "effect": "3.19.16",
32
- "@dxos/crypto": "0.8.4-main.3eb6e50203",
33
- "@dxos/invariant": "0.8.4-main.3eb6e50203",
34
- "@dxos/keys": "0.8.4-main.3eb6e50203",
35
- "@dxos/protocols": "0.8.4-main.3eb6e50203",
36
- "@dxos/util": "0.8.4-main.3eb6e50203"
28
+ "effect": "3.20.0",
29
+ "@dxos/invariant": "0.8.4-main.3fbcb4aa9b",
30
+ "@dxos/keys": "0.8.4-main.3fbcb4aa9b",
31
+ "@dxos/crypto": "0.8.4-main.3fbcb4aa9b",
32
+ "@dxos/protocols": "0.8.4-main.3fbcb4aa9b",
33
+ "@dxos/util": "0.8.4-main.3fbcb4aa9b"
37
34
  },
38
35
  "publishConfig": {
39
36
  "access": "public"
package/src/query/ast.ts CHANGED
@@ -107,6 +107,20 @@ const FilterRange_ = Schema.Struct({
107
107
  export interface FilterRange extends Schema.Schema.Type<typeof FilterRange_> {}
108
108
  export const FilterRange: Schema.Schema<FilterRange> = FilterRange_;
109
109
 
110
+ /**
111
+ * Filter by system timestamp (createdAt / updatedAt).
112
+ * Timestamps are unix milliseconds stored in the object meta index.
113
+ */
114
+ const FilterTimestamp_ = Schema.Struct({
115
+ type: Schema.Literal('timestamp'),
116
+ field: Schema.Literal('createdAt', 'updatedAt'),
117
+ operator: Schema.Literal('gt', 'gte', 'lt', 'lte'),
118
+ value: Schema.Number,
119
+ });
120
+
121
+ export interface FilterTimestamp extends Schema.Schema.Type<typeof FilterTimestamp_> {}
122
+ export const FilterTimestamp: Schema.Schema<FilterTimestamp> = FilterTimestamp_;
123
+
110
124
  /**
111
125
  * Text search.
112
126
  */
@@ -152,6 +166,21 @@ const FilterOr_ = Schema.Struct({
152
166
  export interface FilterOr extends Schema.Schema.Type<typeof FilterOr_> {}
153
167
  export const FilterOr: Schema.Schema<FilterOr> = FilterOr_;
154
168
 
169
+ /**
170
+ * Filter objects that are children of the specified parents.
171
+ * With transitive=true (default), matches grandchildren and beyond.
172
+ */
173
+ const FilterChildOf_ = Schema.Struct({
174
+ type: Schema.Literal('child-of'),
175
+ /** Parent DXNs to match children of. */
176
+ parents: Schema.Array(DXN.Schema),
177
+ /** Whether to match transitively (grandchildren, etc.). Defaults to true. */
178
+ transitive: Schema.Boolean,
179
+ });
180
+
181
+ export interface FilterChildOf extends Schema.Schema.Type<typeof FilterChildOf_> {}
182
+ export const FilterChildOf: Schema.Schema<FilterChildOf> = FilterChildOf_;
183
+
155
184
  /**
156
185
  * Union of filters.
157
186
  */
@@ -162,11 +191,13 @@ export const Filter = Schema.Union(
162
191
  FilterContains,
163
192
  FilterTag,
164
193
  FilterRange,
194
+ FilterTimestamp,
165
195
  FilterTextSearch,
196
+ FilterChildOf,
166
197
  FilterNot,
167
198
  FilterAnd,
168
199
  FilterOr,
169
- ).annotations({ identifier: 'dxos.org/schema/Filter' });
200
+ ).annotations({ identifier: 'org.dxos.schema.filter' });
170
201
 
171
202
  export type Filter = Schema.Schema.Type<typeof Filter>;
172
203
 
@@ -355,6 +386,21 @@ const QueryLimitClause_ = Schema.Struct({
355
386
  export interface QueryLimitClause extends Schema.Schema.Type<typeof QueryLimitClause_> {}
356
387
  export const QueryLimitClause: Schema.Schema<QueryLimitClause> = QueryLimitClause_;
357
388
 
389
+ export const QueryFromClause_ = Schema.Struct({
390
+ type: Schema.Literal('from'),
391
+ query: Schema.suspend(() => Query),
392
+ from: Schema.Union(
393
+ Schema.TaggedStruct('scope', {
394
+ scope: Schema.suspend(() => Scope),
395
+ }),
396
+ Schema.TaggedStruct('query', {
397
+ query: Schema.suspend(() => Query),
398
+ }),
399
+ ),
400
+ });
401
+ export interface QueryFromClause extends Schema.Schema.Type<typeof QueryFromClause_> {}
402
+ export const QueryFromClause: Schema.Schema<QueryFromClause> = QueryFromClause_;
403
+
358
404
  const Query_ = Schema.Union(
359
405
  QuerySelectClause,
360
406
  QueryFilterClause,
@@ -368,12 +414,30 @@ const Query_ = Schema.Union(
368
414
  QueryOrderClause,
369
415
  QueryOptionsClause,
370
416
  QueryLimitClause,
371
- ).annotations({ identifier: 'dxos.org/schema/Query' });
417
+ QueryFromClause,
418
+ ).annotations({ identifier: 'org.dxos.schema.query' });
372
419
 
373
420
  export type Query = Schema.Schema.Type<typeof Query_>;
374
421
  export const Query: Schema.Schema<Query> = Query_;
375
422
 
376
423
  export const QueryOptions = Schema.Struct({
424
+ /**
425
+ * Nested select statements will use this option to filter deleted objects.
426
+ */
427
+ deleted: Schema.optional(Schema.Literal('include', 'exclude', 'only')),
428
+
429
+ /**
430
+ * Diagnostics-only label for logs / tooling (not used by execution semantics).
431
+ */
432
+ debugLabel: Schema.optional(Schema.String),
433
+ });
434
+
435
+ export interface QueryOptions extends Schema.Schema.Type<typeof QueryOptions> {}
436
+
437
+ /**
438
+ * Specifies the scope of the data to query from.
439
+ */
440
+ export const Scope = Schema.Struct({
377
441
  /**
378
442
  * The nested select statemets will select from the given spaces.
379
443
  *
@@ -392,14 +456,8 @@ export const QueryOptions = Schema.Struct({
392
456
  * NOTE: Spaces and queues are unioned together if both are specified.
393
457
  */
394
458
  queues: Schema.optional(Schema.Array(DXN.Schema)),
395
-
396
- /**
397
- * Nested select statements will use this option to filter deleted objects.
398
- */
399
- deleted: Schema.optional(Schema.Literal('include', 'exclude', 'only')),
400
459
  });
401
-
402
- export interface QueryOptions extends Schema.Schema.Type<typeof QueryOptions> {}
460
+ export interface Scope extends Schema.Schema.Type<typeof Scope> {}
403
461
 
404
462
  export const visit = (query: Query, visitor: (node: Query) => void) => {
405
463
  visitor(query);
@@ -419,11 +477,49 @@ export const visit = (query: Query, visitor: (node: Query) => void) => {
419
477
  }),
420
478
  Match.when({ type: 'order' }, ({ query }) => visit(query, visitor)),
421
479
  Match.when({ type: 'limit' }, ({ query }) => visit(query, visitor)),
480
+ Match.when({ type: 'from' }, (node) => {
481
+ visit(node.query, visitor);
482
+ if (node.from._tag === 'query') {
483
+ visit(node.from.query, visitor);
484
+ }
485
+ }),
422
486
  Match.when({ type: 'select' }, () => {}),
423
487
  Match.exhaustive,
424
488
  );
425
489
  };
426
490
 
491
+ /**
492
+ * Recursively transforms a query tree bottom-up.
493
+ * The mapper receives each node with its children already transformed.
494
+ */
495
+ export const map = (query: Query, mapper: (node: Query) => Query): Query => {
496
+ const mapped: Query = Match.value(query).pipe(
497
+ Match.when({ type: 'filter' }, (node) => ({ ...node, selection: map(node.selection, mapper) })),
498
+ Match.when({ type: 'reference-traversal' }, (node) => ({ ...node, anchor: map(node.anchor, mapper) })),
499
+ Match.when({ type: 'incoming-references' }, (node) => ({ ...node, anchor: map(node.anchor, mapper) })),
500
+ Match.when({ type: 'relation' }, (node) => ({ ...node, anchor: map(node.anchor, mapper) })),
501
+ Match.when({ type: 'relation-traversal' }, (node) => ({ ...node, anchor: map(node.anchor, mapper) })),
502
+ Match.when({ type: 'hierarchy-traversal' }, (node) => ({ ...node, anchor: map(node.anchor, mapper) })),
503
+ Match.when({ type: 'options' }, (node) => ({ ...node, query: map(node.query, mapper) })),
504
+ Match.when({ type: 'order' }, (node) => ({ ...node, query: map(node.query, mapper) })),
505
+ Match.when({ type: 'limit' }, (node) => ({ ...node, query: map(node.query, mapper) })),
506
+ Match.when({ type: 'from' }, (node) => ({
507
+ ...node,
508
+ query: map(node.query, mapper),
509
+ ...(node.from._tag === 'query' ? { from: { _tag: 'query' as const, query: map(node.from.query, mapper) } } : {}),
510
+ })),
511
+ Match.when({ type: 'union' }, (node) => ({ ...node, queries: node.queries.map((q) => map(q, mapper)) })),
512
+ Match.when({ type: 'set-difference' }, (node) => ({
513
+ ...node,
514
+ source: map(node.source, mapper),
515
+ exclude: map(node.exclude, mapper),
516
+ })),
517
+ Match.when({ type: 'select' }, (node) => node),
518
+ Match.exhaustive,
519
+ );
520
+ return mapper(mapped);
521
+ };
522
+
427
523
  export const fold = <T>(query: Query, reducer: (node: Query) => T): T[] => {
428
524
  return Match.value(query).pipe(
429
525
  Match.withReturnType<T[]>(),
@@ -440,6 +536,13 @@ export const fold = <T>(query: Query, reducer: (node: Query) => T): T[] => {
440
536
  ),
441
537
  Match.when({ type: 'order' }, ({ query }) => fold(query, reducer)),
442
538
  Match.when({ type: 'limit' }, ({ query }) => fold(query, reducer)),
539
+ Match.when({ type: 'from' }, (node) => {
540
+ const results = fold(node.query, reducer);
541
+ if (node.from._tag === 'query') {
542
+ return results.concat(fold(node.from.query, reducer));
543
+ }
544
+ return results;
545
+ }),
443
546
  Match.when({ type: 'select' }, () => []),
444
547
  Match.exhaustive,
445
548
  );