@dxos/echo-protocol 0.8.4-staging.ac66bdf99f → 0.9.0
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 +75 -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 +75 -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 +118 -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 +88 -37
- package/src/edge-peer.ts +27 -0
- package/src/index.ts +1 -0
- package/src/query/ast.ts +65 -26
- 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.
|
|
3
|
+
"version": "0.9.0",
|
|
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.
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/
|
|
28
|
+
"effect": "3.21.3",
|
|
29
|
+
"@dxos/crypto": "0.9.0",
|
|
30
|
+
"@dxos/protocols": "0.9.0",
|
|
31
|
+
"@dxos/util": "0.9.0",
|
|
32
|
+
"@dxos/keys": "0.9.0",
|
|
33
|
+
"@dxos/invariant": "0.9.0"
|
|
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: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
|
|
|
@@ -267,6 +311,13 @@ export type ObjectSystem = {
|
|
|
267
311
|
* Only for relations.
|
|
268
312
|
*/
|
|
269
313
|
target?: EncodedReference;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Unix ms timestamp recorded at object creation time.
|
|
317
|
+
* Set once when the ObjectStructure is first written; never modified after that.
|
|
318
|
+
* Survives compaction / migrations (unlike automerge change timestamps).
|
|
319
|
+
*/
|
|
320
|
+
createdAt?: number;
|
|
270
321
|
};
|
|
271
322
|
|
|
272
323
|
/**
|
|
@@ -276,6 +327,6 @@ export const PROPERTY_ID = 'id';
|
|
|
276
327
|
|
|
277
328
|
/**
|
|
278
329
|
* Data namespace.
|
|
279
|
-
* The key on {@link
|
|
330
|
+
* The key on {@link EntityStructure} that contains the user-defined data.
|
|
280
331
|
*/
|
|
281
332
|
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_> {}
|
|
@@ -173,7 +185,7 @@ export const FilterOr: Schema.Schema<FilterOr> = FilterOr_;
|
|
|
173
185
|
const FilterChildOf_ = Schema.Struct({
|
|
174
186
|
type: Schema.Literal('child-of'),
|
|
175
187
|
/** Parent DXNs to match children of. */
|
|
176
|
-
parents: Schema.Array(
|
|
188
|
+
parents: Schema.Array(EID.Schema),
|
|
177
189
|
/** Whether to match transitively (grandchildren, etc.). Defaults to true. */
|
|
178
190
|
transitive: Schema.Boolean,
|
|
179
191
|
});
|
|
@@ -344,6 +356,12 @@ const Order_ = Schema.Union(
|
|
|
344
356
|
kind: Schema.Literal('rank'),
|
|
345
357
|
direction: OrderDirection,
|
|
346
358
|
}),
|
|
359
|
+
Schema.Struct({
|
|
360
|
+
// Order by system timestamp (createdAt / updatedAt) from the object meta index.
|
|
361
|
+
kind: Schema.Literal('timestamp'),
|
|
362
|
+
field: Schema.Literal('createdAt', 'updatedAt'),
|
|
363
|
+
direction: OrderDirection,
|
|
364
|
+
}),
|
|
347
365
|
);
|
|
348
366
|
|
|
349
367
|
export type Order = Schema.Schema.Type<typeof Order_>;
|
|
@@ -391,7 +409,7 @@ export const QueryFromClause_ = Schema.Struct({
|
|
|
391
409
|
query: Schema.suspend(() => Query),
|
|
392
410
|
from: Schema.Union(
|
|
393
411
|
Schema.TaggedStruct('scope', {
|
|
394
|
-
|
|
412
|
+
scopes: Schema.Array(Schema.suspend(() => Scope)),
|
|
395
413
|
}),
|
|
396
414
|
Schema.TaggedStruct('query', {
|
|
397
415
|
query: Schema.suspend(() => Query),
|
|
@@ -425,34 +443,55 @@ export const QueryOptions = Schema.Struct({
|
|
|
425
443
|
* Nested select statements will use this option to filter deleted objects.
|
|
426
444
|
*/
|
|
427
445
|
deleted: Schema.optional(Schema.Literal('include', 'exclude', 'only')),
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Diagnostics-only label for logs / tooling (not used by execution semantics).
|
|
449
|
+
*/
|
|
450
|
+
debugLabel: Schema.optional(Schema.String),
|
|
428
451
|
});
|
|
429
452
|
|
|
430
453
|
export interface QueryOptions extends Schema.Schema.Type<typeof QueryOptions> {}
|
|
431
454
|
|
|
432
455
|
/**
|
|
433
|
-
*
|
|
456
|
+
* Selects from a space (automerge documents).
|
|
457
|
+
* When `spaceId` is omitted, targets the owning space — i.e. the space of whichever
|
|
458
|
+
* database executes the query. This lets callers reference "this space" without
|
|
459
|
+
* having to look up its id.
|
|
460
|
+
* When `includeAllFeeds` is true, also selects from all feeds belonging to that space.
|
|
434
461
|
*/
|
|
435
|
-
export const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
*/
|
|
441
|
-
spaceIds: Schema.optional(Schema.Array(Schema.String)),
|
|
462
|
+
export const SpaceScope = Schema.TaggedStruct('space', {
|
|
463
|
+
spaceId: Schema.optional(Schema.String),
|
|
464
|
+
includeAllFeeds: Schema.optional(Schema.Boolean),
|
|
465
|
+
});
|
|
466
|
+
export interface SpaceScope extends Schema.Schema.Type<typeof SpaceScope> {}
|
|
442
467
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
468
|
+
/**
|
|
469
|
+
* Selects from a specific feed (by its underlying queue DXN).
|
|
470
|
+
*/
|
|
471
|
+
export const FeedScope = Schema.TaggedStruct('feed', {
|
|
472
|
+
feedUri: Schema.String,
|
|
473
|
+
});
|
|
474
|
+
export interface FeedScope extends Schema.Schema.Type<typeof FeedScope> {}
|
|
447
475
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
476
|
+
/**
|
|
477
|
+
* Selects from a code-shipped object registry.
|
|
478
|
+
*
|
|
479
|
+
* - `'local'` — the in-process registry attached to the hypergraph.
|
|
480
|
+
* - `'remote'` — a future remote registry service (not yet implemented).
|
|
481
|
+
*
|
|
482
|
+
* To include both, add two separate `RegistryScope` entries to the `scopes` array.
|
|
483
|
+
*/
|
|
484
|
+
export const RegistryScope = Schema.TaggedStruct('registry', {
|
|
485
|
+
location: Schema.Literal('local', 'remote'),
|
|
454
486
|
});
|
|
455
|
-
export interface
|
|
487
|
+
export interface RegistryScope extends Schema.Schema.Type<typeof RegistryScope> {}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Specifies the scope of the data to query from.
|
|
491
|
+
* A `from` clause may carry multiple scopes; results are unioned across them.
|
|
492
|
+
*/
|
|
493
|
+
export const Scope = Schema.Union(SpaceScope, FeedScope, RegistryScope);
|
|
494
|
+
export type Scope = Schema.Schema.Type<typeof Scope>;
|
|
456
495
|
|
|
457
496
|
export const visit = (query: Query, visitor: (node: Query) => void) => {
|
|
458
497
|
visitor(query);
|