@dxos/echo-protocol 0.8.4-main.40e3dcdf1b → 0.8.4-main.43cb759274
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/LICENSE +102 -5
- package/README.md +1 -1
- package/dist/lib/neutral/index.mjs +87 -182
- package/dist/lib/neutral/index.mjs.map +4 -4
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/types/src/document-structure.d.ts +69 -34
- package/dist/types/src/document-structure.d.ts.map +1 -1
- package/dist/types/src/echo-feed-codec.d.ts.map +1 -1
- package/dist/types/src/edge-peer.d.ts +11 -0
- package/dist/types/src/edge-peer.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/query/ast.d.ts +133 -54
- package/dist/types/src/query/ast.d.ts.map +1 -1
- package/dist/types/src/reference.d.ts +11 -65
- package/dist/types/src/reference.d.ts.map +1 -1
- package/dist/types/src/space-id.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -11
- package/src/document-structure.ts +81 -37
- package/src/edge-peer.ts +27 -0
- package/src/index.ts +1 -0
- package/src/query/ast.ts +89 -25
- package/src/reference.ts +12 -160
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo-protocol",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.43cb759274",
|
|
4
4
|
"description": "Core ECHO APIs.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/dxos/dxos"
|
|
10
10
|
},
|
|
11
|
-
"license": "
|
|
11
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
12
12
|
"author": "DXOS.org",
|
|
13
13
|
"sideEffects": false,
|
|
14
14
|
"type": "module",
|
|
@@ -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.
|
|
32
|
-
"@dxos/crypto": "0.8.4-main.
|
|
33
|
-
"@dxos/invariant": "0.8.4-main.
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
28
|
+
"effect": "3.21.2",
|
|
29
|
+
"@dxos/crypto": "0.8.4-main.43cb759274",
|
|
30
|
+
"@dxos/invariant": "0.8.4-main.43cb759274",
|
|
31
|
+
"@dxos/keys": "0.8.4-main.43cb759274",
|
|
32
|
+
"@dxos/util": "0.8.4-main.43cb759274",
|
|
33
|
+
"@dxos/protocols": "0.8.4-main.43cb759274"
|
|
37
34
|
},
|
|
38
35
|
"publishConfig": {
|
|
39
36
|
"access": "public"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { invariant } from '@dxos/invariant';
|
|
6
|
-
import type {
|
|
6
|
+
import type { EntityId, URI } from '@dxos/keys';
|
|
7
7
|
import { visitValues } from '@dxos/util';
|
|
8
8
|
|
|
9
9
|
import { type RawString } from './automerge';
|
|
@@ -19,8 +19,8 @@ export type SpaceState = {
|
|
|
19
19
|
/**
|
|
20
20
|
* Array indexes get converted to strings.
|
|
21
21
|
*/
|
|
22
|
-
export type
|
|
23
|
-
export type
|
|
22
|
+
export type EntityProp = string;
|
|
23
|
+
export type EntityPropPath = EntityProp[];
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Link to all documents that hold objects in the space.
|
|
@@ -35,13 +35,13 @@ export interface DatabaseDirectory {
|
|
|
35
35
|
* Objects inlined in the current document.
|
|
36
36
|
*/
|
|
37
37
|
objects?: {
|
|
38
|
-
[id: string]:
|
|
38
|
+
[id: string]: EntityStructure;
|
|
39
39
|
};
|
|
40
40
|
/**
|
|
41
41
|
* Object id points to an automerge doc url where the object is embedded.
|
|
42
42
|
*/
|
|
43
43
|
links?: {
|
|
44
|
-
[
|
|
44
|
+
[echoUri: string]: string | RawString;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
/**
|
|
@@ -67,11 +67,11 @@ export const DatabaseDirectory = Object.freeze({
|
|
|
67
67
|
return rawKey;
|
|
68
68
|
},
|
|
69
69
|
|
|
70
|
-
getInlineObject: (doc: DatabaseDirectory, id:
|
|
70
|
+
getInlineObject: (doc: DatabaseDirectory, id: EntityId): EntityStructure | undefined => {
|
|
71
71
|
return doc.objects?.[id];
|
|
72
72
|
},
|
|
73
73
|
|
|
74
|
-
getLink: (doc: DatabaseDirectory, id:
|
|
74
|
+
getLink: (doc: DatabaseDirectory, id: EntityId): string | undefined => {
|
|
75
75
|
return doc.links?.[id]?.toString();
|
|
76
76
|
},
|
|
77
77
|
|
|
@@ -81,7 +81,7 @@ export const DatabaseDirectory = Object.freeze({
|
|
|
81
81
|
links,
|
|
82
82
|
}: {
|
|
83
83
|
spaceKey: string;
|
|
84
|
-
objects?: Record<string,
|
|
84
|
+
objects?: Record<string, EntityStructure>;
|
|
85
85
|
links?: Record<string, RawString>;
|
|
86
86
|
}): DatabaseDirectory => ({
|
|
87
87
|
access: {
|
|
@@ -95,11 +95,11 @@ export const DatabaseDirectory = Object.freeze({
|
|
|
95
95
|
/**
|
|
96
96
|
* Representation of an ECHO object in an AM document.
|
|
97
97
|
*/
|
|
98
|
-
export type
|
|
98
|
+
export type EntityStructure = {
|
|
99
99
|
// TODO(dmaretskyi): Missing in some cases.
|
|
100
|
-
system?:
|
|
100
|
+
system?: EntitySystem;
|
|
101
101
|
|
|
102
|
-
meta:
|
|
102
|
+
meta: EntityMeta;
|
|
103
103
|
/**
|
|
104
104
|
* User-defined data.
|
|
105
105
|
* Adheres to schema in `system.type`
|
|
@@ -107,46 +107,46 @@ export type ObjectStructure = {
|
|
|
107
107
|
data: Record<string, any>;
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
-
// Helper methods to interact with the {@link
|
|
111
|
-
export const
|
|
110
|
+
// Helper methods to interact with the {@link EntityStructure}.
|
|
111
|
+
export const EntityStructure = Object.freeze({
|
|
112
112
|
/**
|
|
113
113
|
* @throws On invalid object structure.
|
|
114
114
|
*/
|
|
115
|
-
getTypeReference: (object:
|
|
115
|
+
getTypeReference: (object: EntityStructure): EncodedReference | undefined => {
|
|
116
116
|
return object.system?.type;
|
|
117
117
|
},
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* @throws On invalid object structure.
|
|
121
121
|
*/
|
|
122
|
-
getEntityKind: (object:
|
|
122
|
+
getEntityKind: (object: EntityStructure): 'object' | 'relation' | 'type' => {
|
|
123
123
|
const kind = object.system?.kind ?? 'object';
|
|
124
|
-
invariant(kind === 'object' || kind === 'relation', 'Invalid kind');
|
|
124
|
+
invariant(kind === 'object' || kind === 'relation' || kind === 'type', 'Invalid kind');
|
|
125
125
|
return kind;
|
|
126
126
|
},
|
|
127
127
|
|
|
128
|
-
isDeleted: (object:
|
|
128
|
+
isDeleted: (object: EntityStructure): boolean => {
|
|
129
129
|
return object.system?.deleted ?? false;
|
|
130
130
|
},
|
|
131
131
|
|
|
132
|
-
getRelationSource: (object:
|
|
132
|
+
getRelationSource: (object: EntityStructure): EncodedReference | undefined => {
|
|
133
133
|
return object.system?.source;
|
|
134
134
|
},
|
|
135
135
|
|
|
136
|
-
getRelationTarget: (object:
|
|
136
|
+
getRelationTarget: (object: EntityStructure): EncodedReference | undefined => {
|
|
137
137
|
return object.system?.target;
|
|
138
138
|
},
|
|
139
139
|
|
|
140
|
-
getParent: (object:
|
|
140
|
+
getParent: (object: EntityStructure): EncodedReference | undefined => {
|
|
141
141
|
return object.system?.parent;
|
|
142
142
|
},
|
|
143
143
|
|
|
144
144
|
/**
|
|
145
145
|
* @returns All references in the data section of the object.
|
|
146
146
|
*/
|
|
147
|
-
getAllOutgoingReferences: (object:
|
|
148
|
-
const references: { path:
|
|
149
|
-
const visit = (path:
|
|
147
|
+
getAllOutgoingReferences: (object: EntityStructure): { path: EntityPropPath; reference: EncodedReference }[] => {
|
|
148
|
+
const references: { path: EntityPropPath; reference: EncodedReference }[] = [];
|
|
149
|
+
const visit = (path: EntityPropPath, value: unknown) => {
|
|
150
150
|
if (isEncodedReference(value)) {
|
|
151
151
|
references.push({ path, reference: value });
|
|
152
152
|
} else {
|
|
@@ -157,7 +157,7 @@ export const ObjectStructure = Object.freeze({
|
|
|
157
157
|
return references;
|
|
158
158
|
},
|
|
159
159
|
|
|
160
|
-
getTags: (object:
|
|
160
|
+
getTags: (object: EntityStructure): (EncodedReference | string)[] => {
|
|
161
161
|
return object.meta.tags ?? [];
|
|
162
162
|
},
|
|
163
163
|
|
|
@@ -166,11 +166,11 @@ export const ObjectStructure = Object.freeze({
|
|
|
166
166
|
data,
|
|
167
167
|
keys,
|
|
168
168
|
}: {
|
|
169
|
-
type:
|
|
169
|
+
type: URI.URI;
|
|
170
170
|
deleted?: boolean;
|
|
171
171
|
keys?: ForeignKey[];
|
|
172
172
|
data?: unknown;
|
|
173
|
-
}):
|
|
173
|
+
}): EntityStructure => {
|
|
174
174
|
return {
|
|
175
175
|
system: {
|
|
176
176
|
kind: 'object',
|
|
@@ -191,13 +191,13 @@ export const ObjectStructure = Object.freeze({
|
|
|
191
191
|
keys,
|
|
192
192
|
data,
|
|
193
193
|
}: {
|
|
194
|
-
type:
|
|
194
|
+
type: URI.URI;
|
|
195
195
|
source: EncodedReference;
|
|
196
196
|
target: EncodedReference;
|
|
197
197
|
deleted?: boolean;
|
|
198
198
|
keys?: ForeignKey[];
|
|
199
199
|
data?: unknown;
|
|
200
|
-
}):
|
|
200
|
+
}): EntityStructure => {
|
|
201
201
|
return {
|
|
202
202
|
system: {
|
|
203
203
|
kind: 'relation',
|
|
@@ -212,12 +212,25 @@ export const ObjectStructure = Object.freeze({
|
|
|
212
212
|
data: data ?? {},
|
|
213
213
|
};
|
|
214
214
|
},
|
|
215
|
+
|
|
216
|
+
makeType: ({ type, keys, data }: { type: URI.URI; keys?: ForeignKey[]; data?: unknown }): EntityStructure => {
|
|
217
|
+
return {
|
|
218
|
+
system: {
|
|
219
|
+
kind: 'type',
|
|
220
|
+
type: { '/': type },
|
|
221
|
+
},
|
|
222
|
+
meta: {
|
|
223
|
+
keys: keys ?? [],
|
|
224
|
+
},
|
|
225
|
+
data: data ?? {},
|
|
226
|
+
};
|
|
227
|
+
},
|
|
215
228
|
});
|
|
216
229
|
|
|
217
230
|
/**
|
|
218
231
|
* Echo object metadata.
|
|
219
232
|
*/
|
|
220
|
-
export type
|
|
233
|
+
export type EntityMeta = {
|
|
221
234
|
/**
|
|
222
235
|
* Foreign keys.
|
|
223
236
|
*/
|
|
@@ -225,25 +238,56 @@ export type ObjectMeta = {
|
|
|
225
238
|
|
|
226
239
|
/**
|
|
227
240
|
* Tags.
|
|
228
|
-
*
|
|
241
|
+
* Encoded references to Tag objects within the space.
|
|
229
242
|
*
|
|
230
|
-
* NOTE: Optional for backwards
|
|
243
|
+
* NOTE: Optional for backwards compatibility; legacy data may store bare DXN strings, which are
|
|
244
|
+
* upgraded to encoded references on read (see `object-core.ts`).
|
|
231
245
|
*/
|
|
232
|
-
tags?: string[];
|
|
246
|
+
tags?: (EncodedReference | string)[];
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Fully-qualified registry key for the object (FQN format, e.g. `org.example.type.foo`).
|
|
250
|
+
* Identifies the canonical registry entry the object instance was created from.
|
|
251
|
+
*/
|
|
252
|
+
key?: string;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Semantic version of the registry entry the object was created from.
|
|
256
|
+
* Must be a valid semver string (e.g. `1.2.3`).
|
|
257
|
+
*/
|
|
258
|
+
version?: string;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Dictionary of annotations to this entity.
|
|
262
|
+
*
|
|
263
|
+
* NOTE: Optional for backwards compatibility. Values are arbitrary decoded automerge primitives;
|
|
264
|
+
* typed as `any` so `EntityStructure` stays assignable to `DecodedAutomergePrimaryValue`.
|
|
265
|
+
*/
|
|
266
|
+
annotations?: { readonly [key: string]: any };
|
|
233
267
|
};
|
|
234
268
|
|
|
235
269
|
/**
|
|
236
270
|
* Automerge object system properties.
|
|
237
271
|
* (Is automerge specific.)
|
|
238
272
|
*/
|
|
239
|
-
export type
|
|
273
|
+
export type EntitySystem = {
|
|
240
274
|
/**
|
|
241
|
-
* Entity kind.
|
|
275
|
+
* Entity kind. `'type'` covers persisted ECHO type definitions (instances of
|
|
276
|
+
* the `Type.Type` meta-schema); `'object'` / `'relation'` cover regular ECHO
|
|
277
|
+
* instances.
|
|
242
278
|
*/
|
|
243
|
-
kind?: 'object' | 'relation';
|
|
279
|
+
kind?: 'object' | 'relation' | 'type';
|
|
244
280
|
|
|
245
281
|
/**
|
|
246
|
-
* Object reference ('protobuf' protocol) type
|
|
282
|
+
* Object reference ('protobuf' protocol) type — DXN of the schema this
|
|
283
|
+
* entity instantiates.
|
|
284
|
+
*
|
|
285
|
+
* - For `kind === 'object'` / `'relation'` instances, this is the URI of the
|
|
286
|
+
* user-defined schema the entity was created from (e.g. `dxn:type:org.example.Person:1.0.0`).
|
|
287
|
+
* - For `kind === 'type'` entities (persisted Type.Type meta-instances) this
|
|
288
|
+
* is always the URI of the `TypeSchema` meta-schema itself
|
|
289
|
+
* (`dxn:org.dxos.type.schema:0.1.0`). The kind that the meta-instance
|
|
290
|
+
* _describes_ (object/relation/type) lives in `data.jsonSchema.entityKind`.
|
|
247
291
|
*/
|
|
248
292
|
type?: EncodedReference;
|
|
249
293
|
|
|
@@ -276,6 +320,6 @@ export const PROPERTY_ID = 'id';
|
|
|
276
320
|
|
|
277
321
|
/**
|
|
278
322
|
* Data namespace.
|
|
279
|
-
* The key on {@link
|
|
323
|
+
* The key on {@link EntityStructure} that contains the user-defined data.
|
|
280
324
|
*/
|
|
281
325
|
export const DATA_NAMESPACE = 'data';
|
package/src/edge-peer.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type SpaceId } from '@dxos/keys';
|
|
6
|
+
import { EdgeService } from '@dxos/protocols';
|
|
7
|
+
import { compositeKey } from '@dxos/util';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns true if the given peerId belongs to an EDGE replicator (Automerge or Subduction).
|
|
11
|
+
*
|
|
12
|
+
* When `spaceId` is provided, the match is scoped to that space (peerId must start with
|
|
13
|
+
* `<service>:<spaceId>`). When omitted, only the leading service segment is checked
|
|
14
|
+
* (peerId must start with `<service>:`), which is useful when the caller doesn't have a
|
|
15
|
+
* spaceId on hand or wants to match any edge replicator regardless of space.
|
|
16
|
+
*/
|
|
17
|
+
export const isEdgePeerId = (peerId: string, spaceId?: SpaceId): boolean => {
|
|
18
|
+
const automergePrefix =
|
|
19
|
+
spaceId !== undefined
|
|
20
|
+
? compositeKey(EdgeService.AUTOMERGE_REPLICATOR, spaceId)
|
|
21
|
+
: `${EdgeService.AUTOMERGE_REPLICATOR}:`;
|
|
22
|
+
const subductionPrefix =
|
|
23
|
+
spaceId !== undefined
|
|
24
|
+
? compositeKey(EdgeService.SUBDUCTION_REPLICATOR, spaceId)
|
|
25
|
+
: `${EdgeService.SUBDUCTION_REPLICATOR}:`;
|
|
26
|
+
return peerId.startsWith(automergePrefix) || peerId.startsWith(subductionPrefix);
|
|
27
|
+
};
|
package/src/index.ts
CHANGED
package/src/query/ast.ts
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
import * as Match from 'effect/Match';
|
|
6
6
|
import * as Schema from 'effect/Schema';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { EID, EntityId, URI } from '@dxos/keys';
|
|
9
9
|
|
|
10
10
|
import { ForeignKey } from '../foreign-key';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
// Type identifier URI — either a DXN (typename) or an EID (stored-schema-as-object).
|
|
13
|
+
// Matches the URI written into an object's `system.type` (see `getSchemaURI`). Null
|
|
14
|
+
// matches any type.
|
|
15
|
+
const TypenameSpecifier = Schema.Union(URI.Schema, Schema.Null);
|
|
15
16
|
|
|
16
17
|
// NOTE: This pattern with 3 definitions per schema is need to make the types opaque, and circular references in AST to not cause compiler errors.
|
|
17
18
|
|
|
@@ -26,7 +27,7 @@ const FilterObject_ = Schema.Struct({
|
|
|
26
27
|
|
|
27
28
|
typename: TypenameSpecifier,
|
|
28
29
|
|
|
29
|
-
id: Schema.optional(Schema.Array(
|
|
30
|
+
id: Schema.optional(Schema.Array(EntityId)),
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Filter by property.
|
|
@@ -42,6 +43,17 @@ const FilterObject_ = Schema.Struct({
|
|
|
42
43
|
*/
|
|
43
44
|
foreignKeys: Schema.optional(Schema.Array(ForeignKey)),
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Match objects whose meta `key` equals this fully-qualified registry key (FQN format).
|
|
48
|
+
*/
|
|
49
|
+
metaKey: Schema.optional(Schema.String),
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Semver range matched against the object's meta `version`.
|
|
53
|
+
* Only consulted when {@link metaKey} is set. Objects with no `version` do not satisfy a version-constrained filter.
|
|
54
|
+
*/
|
|
55
|
+
metaVersion: Schema.optional(Schema.String),
|
|
56
|
+
|
|
45
57
|
// NOTE: Make sure to update `FilterStep.isNoop` if you change this.
|
|
46
58
|
});
|
|
47
59
|
export interface FilterObject extends Schema.Schema.Type<typeof FilterObject_> {}
|
|
@@ -107,6 +119,20 @@ const FilterRange_ = Schema.Struct({
|
|
|
107
119
|
export interface FilterRange extends Schema.Schema.Type<typeof FilterRange_> {}
|
|
108
120
|
export const FilterRange: Schema.Schema<FilterRange> = FilterRange_;
|
|
109
121
|
|
|
122
|
+
/**
|
|
123
|
+
* Filter by system timestamp (createdAt / updatedAt).
|
|
124
|
+
* Timestamps are unix milliseconds stored in the object meta index.
|
|
125
|
+
*/
|
|
126
|
+
const FilterTimestamp_ = Schema.Struct({
|
|
127
|
+
type: Schema.Literal('timestamp'),
|
|
128
|
+
field: Schema.Literal('createdAt', 'updatedAt'),
|
|
129
|
+
operator: Schema.Literal('gt', 'gte', 'lt', 'lte'),
|
|
130
|
+
value: Schema.Number,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
export interface FilterTimestamp extends Schema.Schema.Type<typeof FilterTimestamp_> {}
|
|
134
|
+
export const FilterTimestamp: Schema.Schema<FilterTimestamp> = FilterTimestamp_;
|
|
135
|
+
|
|
110
136
|
/**
|
|
111
137
|
* Text search.
|
|
112
138
|
*/
|
|
@@ -152,6 +178,21 @@ const FilterOr_ = Schema.Struct({
|
|
|
152
178
|
export interface FilterOr extends Schema.Schema.Type<typeof FilterOr_> {}
|
|
153
179
|
export const FilterOr: Schema.Schema<FilterOr> = FilterOr_;
|
|
154
180
|
|
|
181
|
+
/**
|
|
182
|
+
* Filter objects that are children of the specified parents.
|
|
183
|
+
* With transitive=true (default), matches grandchildren and beyond.
|
|
184
|
+
*/
|
|
185
|
+
const FilterChildOf_ = Schema.Struct({
|
|
186
|
+
type: Schema.Literal('child-of'),
|
|
187
|
+
/** Parent DXNs to match children of. */
|
|
188
|
+
parents: Schema.Array(EID.Schema),
|
|
189
|
+
/** Whether to match transitively (grandchildren, etc.). Defaults to true. */
|
|
190
|
+
transitive: Schema.Boolean,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export interface FilterChildOf extends Schema.Schema.Type<typeof FilterChildOf_> {}
|
|
194
|
+
export const FilterChildOf: Schema.Schema<FilterChildOf> = FilterChildOf_;
|
|
195
|
+
|
|
155
196
|
/**
|
|
156
197
|
* Union of filters.
|
|
157
198
|
*/
|
|
@@ -162,7 +203,9 @@ export const Filter = Schema.Union(
|
|
|
162
203
|
FilterContains,
|
|
163
204
|
FilterTag,
|
|
164
205
|
FilterRange,
|
|
206
|
+
FilterTimestamp,
|
|
165
207
|
FilterTextSearch,
|
|
208
|
+
FilterChildOf,
|
|
166
209
|
FilterNot,
|
|
167
210
|
FilterAnd,
|
|
168
211
|
FilterOr,
|
|
@@ -360,7 +403,7 @@ export const QueryFromClause_ = Schema.Struct({
|
|
|
360
403
|
query: Schema.suspend(() => Query),
|
|
361
404
|
from: Schema.Union(
|
|
362
405
|
Schema.TaggedStruct('scope', {
|
|
363
|
-
|
|
406
|
+
scopes: Schema.Array(Schema.suspend(() => Scope)),
|
|
364
407
|
}),
|
|
365
408
|
Schema.TaggedStruct('query', {
|
|
366
409
|
query: Schema.suspend(() => Query),
|
|
@@ -394,34 +437,55 @@ export const QueryOptions = Schema.Struct({
|
|
|
394
437
|
* Nested select statements will use this option to filter deleted objects.
|
|
395
438
|
*/
|
|
396
439
|
deleted: Schema.optional(Schema.Literal('include', 'exclude', 'only')),
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Diagnostics-only label for logs / tooling (not used by execution semantics).
|
|
443
|
+
*/
|
|
444
|
+
debugLabel: Schema.optional(Schema.String),
|
|
397
445
|
});
|
|
398
446
|
|
|
399
447
|
export interface QueryOptions extends Schema.Schema.Type<typeof QueryOptions> {}
|
|
400
448
|
|
|
401
449
|
/**
|
|
402
|
-
*
|
|
450
|
+
* Selects from a space (automerge documents).
|
|
451
|
+
* When `spaceId` is omitted, targets the owning space — i.e. the space of whichever
|
|
452
|
+
* database executes the query. This lets callers reference "this space" without
|
|
453
|
+
* having to look up its id.
|
|
454
|
+
* When `includeAllFeeds` is true, also selects from all feeds belonging to that space.
|
|
403
455
|
*/
|
|
404
|
-
export const
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
*/
|
|
410
|
-
spaceIds: Schema.optional(Schema.Array(Schema.String)),
|
|
456
|
+
export const SpaceScope = Schema.TaggedStruct('space', {
|
|
457
|
+
spaceId: Schema.optional(Schema.String),
|
|
458
|
+
includeAllFeeds: Schema.optional(Schema.Boolean),
|
|
459
|
+
});
|
|
460
|
+
export interface SpaceScope extends Schema.Schema.Type<typeof SpaceScope> {}
|
|
411
461
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
462
|
+
/**
|
|
463
|
+
* Selects from a specific feed (by its underlying queue DXN).
|
|
464
|
+
*/
|
|
465
|
+
export const FeedScope = Schema.TaggedStruct('feed', {
|
|
466
|
+
feedUri: Schema.String,
|
|
467
|
+
});
|
|
468
|
+
export interface FeedScope extends Schema.Schema.Type<typeof FeedScope> {}
|
|
416
469
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
470
|
+
/**
|
|
471
|
+
* Selects from a code-shipped object registry.
|
|
472
|
+
*
|
|
473
|
+
* - `'local'` — the in-process registry attached to the hypergraph.
|
|
474
|
+
* - `'remote'` — a future remote registry service (not yet implemented).
|
|
475
|
+
*
|
|
476
|
+
* To include both, add two separate `RegistryScope` entries to the `scopes` array.
|
|
477
|
+
*/
|
|
478
|
+
export const RegistryScope = Schema.TaggedStruct('registry', {
|
|
479
|
+
location: Schema.Literal('local', 'remote'),
|
|
423
480
|
});
|
|
424
|
-
export interface
|
|
481
|
+
export interface RegistryScope extends Schema.Schema.Type<typeof RegistryScope> {}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Specifies the scope of the data to query from.
|
|
485
|
+
* A `from` clause may carry multiple scopes; results are unioned across them.
|
|
486
|
+
*/
|
|
487
|
+
export const Scope = Schema.Union(SpaceScope, FeedScope, RegistryScope);
|
|
488
|
+
export type Scope = Schema.Schema.Type<typeof Scope>;
|
|
425
489
|
|
|
426
490
|
export const visit = (query: Query, visitor: (node: Query) => void) => {
|
|
427
491
|
visitor(query);
|