@dxos/echo 0.8.3-main.7f5a14c → 0.8.3-staging.0fa589b
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/dist/lib/browser/chunk-UYPR62ZB.mjs +624 -0
- package/dist/lib/browser/chunk-UYPR62ZB.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +10 -282
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +70 -0
- package/dist/lib/browser/testing/index.mjs.map +7 -0
- package/dist/lib/node/chunk-4HQE2F3L.cjs +644 -0
- package/dist/lib/node/chunk-4HQE2F3L.cjs.map +7 -0
- package/dist/lib/node/index.cjs +9 -282
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +89 -0
- package/dist/lib/node/testing/index.cjs.map +7 -0
- package/dist/lib/node-esm/chunk-BYBICDIO.mjs +624 -0
- package/dist/lib/node-esm/chunk-BYBICDIO.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +10 -282
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +70 -0
- package/dist/lib/node-esm/testing/index.mjs.map +7 -0
- package/dist/types/src/Obj.d.ts +23 -8
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +1 -1
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +36 -10
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Type.d.ts +78 -15
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/query/dsl.d.ts +218 -0
- package/dist/types/src/query/dsl.d.ts.map +1 -0
- package/dist/types/src/query/dsl.test.d.ts +2 -0
- package/dist/types/src/query/dsl.test.d.ts.map +1 -0
- package/dist/types/src/query/index.d.ts +2 -0
- package/dist/types/src/query/index.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/types.d.ts +113 -0
- package/dist/types/src/testing/types.d.ts.map +1 -0
- package/package.json +56 -12
- package/src/Obj.ts +44 -6
- package/src/Ref.ts +1 -1
- package/src/Relation.ts +75 -13
- package/src/Type.ts +113 -14
- package/src/index.ts +1 -1
- package/src/query/dsl.test.ts +323 -0
- package/src/query/dsl.ts +646 -0
- package/src/query/index.ts +5 -0
- package/src/test/api.test.ts +37 -7
- package/src/testing/index.ts +5 -0
- package/src/testing/types.ts +91 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { Type } from '..';
|
|
3
|
+
export declare namespace Testing {
|
|
4
|
+
const _Contact: Type.obj<Schema.SchemaClass<{
|
|
5
|
+
readonly name?: string | undefined;
|
|
6
|
+
readonly email?: string | undefined;
|
|
7
|
+
readonly username?: string | undefined;
|
|
8
|
+
readonly tasks?: import("@dxos/echo-schema").Ref<Task>[] | undefined;
|
|
9
|
+
readonly address?: {
|
|
10
|
+
readonly city?: string | undefined;
|
|
11
|
+
readonly state?: string | undefined;
|
|
12
|
+
readonly zip?: string | undefined;
|
|
13
|
+
readonly coordinates: {
|
|
14
|
+
readonly lat?: number | undefined;
|
|
15
|
+
readonly lng?: number | undefined;
|
|
16
|
+
};
|
|
17
|
+
} | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
readonly name?: string | undefined;
|
|
20
|
+
readonly email?: string | undefined;
|
|
21
|
+
readonly username?: string | undefined;
|
|
22
|
+
readonly tasks?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
23
|
+
readonly address?: {
|
|
24
|
+
readonly coordinates: {
|
|
25
|
+
readonly lat?: number | undefined;
|
|
26
|
+
readonly lng?: number | undefined;
|
|
27
|
+
};
|
|
28
|
+
readonly city?: string | undefined;
|
|
29
|
+
readonly state?: string | undefined;
|
|
30
|
+
readonly zip?: string | undefined;
|
|
31
|
+
} | undefined;
|
|
32
|
+
}, never>>;
|
|
33
|
+
export interface Contact extends Schema.Schema.Type<typeof _Contact> {
|
|
34
|
+
}
|
|
35
|
+
export const Contact: Schema.Schema<Contact, Schema.Schema.Encoded<typeof _Contact>, never>;
|
|
36
|
+
const _Task: Type.obj<Schema.SchemaClass<{
|
|
37
|
+
readonly description?: string | undefined;
|
|
38
|
+
readonly title?: string | undefined;
|
|
39
|
+
readonly assignee?: import("@dxos/echo-schema").Ref<Contact> | undefined;
|
|
40
|
+
readonly completed?: boolean | undefined;
|
|
41
|
+
readonly previous?: import("@dxos/echo-schema").Ref<Task> | undefined;
|
|
42
|
+
readonly subTasks?: import("@dxos/echo-schema").Ref<Task>[] | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
readonly description?: string | undefined;
|
|
45
|
+
readonly title?: string | undefined;
|
|
46
|
+
readonly assignee?: import("@dxos/echo-protocol").EncodedReference | undefined;
|
|
47
|
+
readonly completed?: boolean | undefined;
|
|
48
|
+
readonly previous?: import("@dxos/echo-protocol").EncodedReference | undefined;
|
|
49
|
+
readonly subTasks?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
50
|
+
}, never>>;
|
|
51
|
+
export interface Task extends Schema.Schema.Type<typeof _Task> {
|
|
52
|
+
}
|
|
53
|
+
export const Task: Schema.Schema<Task, Schema.Schema.Encoded<typeof _Task>, never>;
|
|
54
|
+
export enum RecordType {
|
|
55
|
+
UNDEFINED = 0,
|
|
56
|
+
PERSONAL = 1,
|
|
57
|
+
WORK = 2
|
|
58
|
+
}
|
|
59
|
+
export const Container: Type.obj<Schema.SchemaClass<{
|
|
60
|
+
readonly records?: {
|
|
61
|
+
readonly type?: RecordType | undefined;
|
|
62
|
+
readonly description?: string | undefined;
|
|
63
|
+
readonly title?: string | undefined;
|
|
64
|
+
readonly contacts?: import("@dxos/echo-schema").Ref<Contact>[] | undefined;
|
|
65
|
+
}[] | undefined;
|
|
66
|
+
readonly objects?: import("@dxos/echo-schema").Ref<Type.Expando>[] | undefined;
|
|
67
|
+
}, {
|
|
68
|
+
readonly records?: {
|
|
69
|
+
readonly type?: RecordType | undefined;
|
|
70
|
+
readonly description?: string | undefined;
|
|
71
|
+
readonly title?: string | undefined;
|
|
72
|
+
readonly contacts?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
73
|
+
}[] | undefined;
|
|
74
|
+
readonly objects?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
75
|
+
}, never>>;
|
|
76
|
+
export const WorksFor: Type.relation<Schema.Struct<{
|
|
77
|
+
since: Schema.optional<typeof Schema.String>;
|
|
78
|
+
}>, Schema.Schema<Contact, {
|
|
79
|
+
id: string;
|
|
80
|
+
name?: string | undefined;
|
|
81
|
+
email?: string | undefined;
|
|
82
|
+
username?: string | undefined;
|
|
83
|
+
tasks?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
84
|
+
address?: {
|
|
85
|
+
readonly coordinates: {
|
|
86
|
+
readonly lat?: number | undefined;
|
|
87
|
+
readonly lng?: number | undefined;
|
|
88
|
+
};
|
|
89
|
+
readonly city?: string | undefined;
|
|
90
|
+
readonly state?: string | undefined;
|
|
91
|
+
readonly zip?: string | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
}, never>, Schema.Schema<Contact, {
|
|
94
|
+
id: string;
|
|
95
|
+
name?: string | undefined;
|
|
96
|
+
email?: string | undefined;
|
|
97
|
+
username?: string | undefined;
|
|
98
|
+
tasks?: import("@dxos/echo-protocol").EncodedReference[] | undefined;
|
|
99
|
+
address?: {
|
|
100
|
+
readonly coordinates: {
|
|
101
|
+
readonly lat?: number | undefined;
|
|
102
|
+
readonly lng?: number | undefined;
|
|
103
|
+
};
|
|
104
|
+
readonly city?: string | undefined;
|
|
105
|
+
readonly state?: string | undefined;
|
|
106
|
+
readonly zip?: string | undefined;
|
|
107
|
+
} | undefined;
|
|
108
|
+
}, never>>;
|
|
109
|
+
export interface WorksFor extends Schema.Schema.Type<typeof WorksFor> {
|
|
110
|
+
}
|
|
111
|
+
export {};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/testing/types.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG1B,yBAAiB,OAAO,CAAC;IACvB,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAoBb,CAAC;IACF,MAAM,WAAW,OAAQ,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,QAAQ,CAAC;KAAG;IACvE,MAAM,CAAC,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,QAAQ,CAAC,EAAE,KAAK,CAAY,CAAC;IAEvG,MAAM,KAAK;;;;;;;;;;;;;;cAaV,CAAC;IACF,MAAM,WAAW,IAAK,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC;KAAG;IACjE,MAAM,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,CAAS,CAAC;IAE3F,MAAM,MAAM,UAAU;QACpB,SAAS,IAAI;QACb,QAAQ,IAAI;QACZ,IAAI,IAAI;KACT;IAED,MAAM,CAAC,MAAM,SAAS;;;;;;;;;;;;;;;;cAoBrB,CAAC;IAEF,MAAM,CAAC,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cASpB,CAAC;IACF,MAAM,WAAW,QAAS,SAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,QAAQ,CAAC;KAAG;;CACzE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo",
|
|
3
|
-
"version": "0.8.3-
|
|
3
|
+
"version": "0.8.3-staging.0fa589b",
|
|
4
4
|
"description": "ECHO API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -13,9 +13,53 @@
|
|
|
13
13
|
"types": "./dist/types/src/index.d.ts",
|
|
14
14
|
"browser": "./dist/lib/browser/index.mjs",
|
|
15
15
|
"node": "./dist/lib/node-esm/index.mjs"
|
|
16
|
+
},
|
|
17
|
+
"./Type": {
|
|
18
|
+
"types": "./dist/types/src/Type.d.ts",
|
|
19
|
+
"browser": "./dist/lib/browser/Type.mjs",
|
|
20
|
+
"node": "./dist/lib/node-esm/Type.mjs"
|
|
21
|
+
},
|
|
22
|
+
"./Obj": {
|
|
23
|
+
"types": "./dist/types/src/Obj.d.ts",
|
|
24
|
+
"browser": "./dist/lib/browser/Obj.mjs",
|
|
25
|
+
"node": "./dist/lib/node-esm/Obj.mjs"
|
|
26
|
+
},
|
|
27
|
+
"./Relation": {
|
|
28
|
+
"types": "./dist/types/src/Relation.d.ts",
|
|
29
|
+
"browser": "./dist/lib/browser/Relation.mjs",
|
|
30
|
+
"node": "./dist/lib/node-esm/Relation.mjs"
|
|
31
|
+
},
|
|
32
|
+
"./Ref": {
|
|
33
|
+
"types": "./dist/types/src/Ref.d.ts",
|
|
34
|
+
"browser": "./dist/lib/browser/Ref.mjs",
|
|
35
|
+
"node": "./dist/lib/node-esm/Ref.mjs"
|
|
36
|
+
},
|
|
37
|
+
"./testing": {
|
|
38
|
+
"types": "./dist/types/src/testing/types.d.ts",
|
|
39
|
+
"browser": "./dist/lib/browser/testing/index.mjs",
|
|
40
|
+
"node": "./dist/lib/node-esm/testing/index.mjs"
|
|
16
41
|
}
|
|
17
42
|
},
|
|
18
43
|
"types": "dist/types/src/index.d.ts",
|
|
44
|
+
"typesVersions": {
|
|
45
|
+
"*": {
|
|
46
|
+
"Type": [
|
|
47
|
+
"dist/types/src/Type.d.ts"
|
|
48
|
+
],
|
|
49
|
+
"Obj": [
|
|
50
|
+
"dist/types/src/Obj.d.ts"
|
|
51
|
+
],
|
|
52
|
+
"Relation": [
|
|
53
|
+
"dist/types/src/Relation.d.ts"
|
|
54
|
+
],
|
|
55
|
+
"Ref": [
|
|
56
|
+
"dist/types/src/Ref.d.ts"
|
|
57
|
+
],
|
|
58
|
+
"testing": [
|
|
59
|
+
"dist/types/src/testing/index.d.ts"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
},
|
|
19
63
|
"files": [
|
|
20
64
|
"dist",
|
|
21
65
|
"src"
|
|
@@ -23,17 +67,17 @@
|
|
|
23
67
|
"dependencies": {
|
|
24
68
|
"@preact/signals-core": "^1.9.0",
|
|
25
69
|
"effect": "3.14.21",
|
|
26
|
-
"@dxos/debug": "0.8.3-
|
|
27
|
-
"@dxos/echo-protocol": "0.8.3-
|
|
28
|
-
"@dxos/echo-schema": "0.8.3-
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/live-object": "0.8.3-
|
|
34
|
-
"@dxos/log": "0.8.3-
|
|
35
|
-
"@dxos/node-std": "0.8.3-
|
|
36
|
-
"@dxos/util": "0.8.3-
|
|
70
|
+
"@dxos/debug": "0.8.3-staging.0fa589b",
|
|
71
|
+
"@dxos/echo-protocol": "0.8.3-staging.0fa589b",
|
|
72
|
+
"@dxos/echo-schema": "0.8.3-staging.0fa589b",
|
|
73
|
+
"@dxos/effect": "0.8.3-staging.0fa589b",
|
|
74
|
+
"@dxos/echo-signals": "0.8.3-staging.0fa589b",
|
|
75
|
+
"@dxos/invariant": "0.8.3-staging.0fa589b",
|
|
76
|
+
"@dxos/keys": "0.8.3-staging.0fa589b",
|
|
77
|
+
"@dxos/live-object": "0.8.3-staging.0fa589b",
|
|
78
|
+
"@dxos/log": "0.8.3-staging.0fa589b",
|
|
79
|
+
"@dxos/node-std": "0.8.3-staging.0fa589b",
|
|
80
|
+
"@dxos/util": "0.8.3-staging.0fa589b"
|
|
37
81
|
},
|
|
38
82
|
"publishConfig": {
|
|
39
83
|
"access": "public"
|
package/src/Obj.ts
CHANGED
|
@@ -7,16 +7,54 @@ import { Schema } from 'effect';
|
|
|
7
7
|
import * as EchoSchema from '@dxos/echo-schema';
|
|
8
8
|
import { assertArgument, invariant } from '@dxos/invariant';
|
|
9
9
|
import { type DXN } from '@dxos/keys';
|
|
10
|
-
import * as LiveObject from '@dxos/live-object';
|
|
10
|
+
import type * as LiveObject from '@dxos/live-object';
|
|
11
|
+
import { live } from '@dxos/live-object';
|
|
11
12
|
import { assumeType } from '@dxos/util';
|
|
12
13
|
|
|
13
14
|
import type * as Ref from './Ref';
|
|
15
|
+
import type * as Relation from './Relation';
|
|
14
16
|
import type * as Type from './Type';
|
|
15
17
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
+
// NOTE: Don't export: Obj.Any and Obj.Obj form the public API.
|
|
19
|
+
interface ObjBase extends Type.OfKind<EchoSchema.EntityKind.Object> {
|
|
20
|
+
readonly id: EchoSchema.ObjectId;
|
|
21
|
+
}
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Object type with specific properties.
|
|
25
|
+
*/
|
|
26
|
+
export type Obj<Props> = ObjBase & Props;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Base type for all ECHO objects.
|
|
30
|
+
*/
|
|
31
|
+
export interface Any extends ObjBase {}
|
|
32
|
+
|
|
33
|
+
type MakeProps<T> = {
|
|
34
|
+
id?: EchoSchema.ObjectId;
|
|
35
|
+
} & Type.Properties<T>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Creates new object.
|
|
39
|
+
*/
|
|
40
|
+
// TODO(dmaretskyi): Move meta into props.
|
|
41
|
+
export const make = <S extends Type.Obj.Any>(
|
|
42
|
+
schema: S,
|
|
43
|
+
props: NoInfer<MakeProps<Schema.Schema.Type<S>>>,
|
|
44
|
+
meta?: EchoSchema.ObjectMeta,
|
|
45
|
+
): LiveObject.Live<Schema.Schema.Type<S>> => {
|
|
46
|
+
assertArgument(
|
|
47
|
+
EchoSchema.getTypeAnnotation(schema)?.kind === EchoSchema.EntityKind.Object,
|
|
48
|
+
'Expected an object schema',
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (props[EchoSchema.MetaId] != null) {
|
|
52
|
+
meta = props[EchoSchema.MetaId] as any;
|
|
53
|
+
delete props[EchoSchema.MetaId];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return live<Schema.Schema.Type<S>>(schema, props as any, meta);
|
|
57
|
+
};
|
|
20
58
|
|
|
21
59
|
export const isObject = (obj: unknown): obj is Any => {
|
|
22
60
|
assumeType<EchoSchema.InternalObjectProps>(obj);
|
|
@@ -111,7 +149,7 @@ export type JSON = EchoSchema.ObjectJSON;
|
|
|
111
149
|
*
|
|
112
150
|
* The same algorithm is used when calling the standard `JSON.stringify(obj)` function.
|
|
113
151
|
*/
|
|
114
|
-
export const toJSON = (obj: Any): JSON => EchoSchema.objectToJSON(obj);
|
|
152
|
+
export const toJSON = (obj: Any | Relation.Any): JSON => EchoSchema.objectToJSON(obj);
|
|
115
153
|
|
|
116
154
|
/**
|
|
117
155
|
* Creates an object from its json representation, performing schema validation.
|
|
@@ -120,4 +158,4 @@ export const toJSON = (obj: Any): JSON => EchoSchema.objectToJSON(obj);
|
|
|
120
158
|
* The function need to be async to support resolving the schema as well as the relation endpoints.
|
|
121
159
|
*/
|
|
122
160
|
export const fromJSON: (json: unknown, options?: { refResolver?: Ref.Resolver }) => Promise<Any> =
|
|
123
|
-
EchoSchema.objectFromJSON;
|
|
161
|
+
EchoSchema.objectFromJSON as any;
|
package/src/Ref.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as EchoSchema from '@dxos/echo-schema';
|
|
|
6
6
|
|
|
7
7
|
import type * as Obj from './Obj';
|
|
8
8
|
|
|
9
|
-
export type Ref<T
|
|
9
|
+
export type Ref<T> = EchoSchema.Ref<T>;
|
|
10
10
|
export type Any = EchoSchema.Ref<Obj.Any>;
|
|
11
11
|
|
|
12
12
|
export const Array = EchoSchema.RefArray;
|
package/src/Relation.ts
CHANGED
|
@@ -2,18 +2,78 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import { type Schema } from 'effect';
|
|
6
|
+
|
|
7
|
+
import { raise } from '@dxos/debug';
|
|
5
8
|
import * as EchoSchema from '@dxos/echo-schema';
|
|
6
9
|
import { assertArgument, invariant } from '@dxos/invariant';
|
|
7
10
|
import { DXN } from '@dxos/keys';
|
|
8
|
-
import
|
|
11
|
+
import { type Live, live } from '@dxos/live-object';
|
|
9
12
|
import { assumeType } from '@dxos/util';
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
import type * as Obj from './Obj';
|
|
15
|
+
import type * as Type from './Type';
|
|
16
|
+
|
|
17
|
+
// NOTE: Don't export: Relation.Relation and Relation.Any form the public API.
|
|
18
|
+
interface RelationBase<Source, Target>
|
|
19
|
+
extends Type.Relation.Endpoints<Source, Target>,
|
|
20
|
+
Type.OfKind<EchoSchema.EntityKind.Relation> {
|
|
21
|
+
readonly id: EchoSchema.ObjectId;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Relation type with specific properties.
|
|
26
|
+
*/
|
|
27
|
+
export type Relation<Source extends Obj.Any, Target extends Obj.Any, Props> = RelationBase<Source, Target> & Props;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Base type for all ECHO relations.
|
|
31
|
+
*/
|
|
32
|
+
export interface Any extends RelationBase<Obj.Any, Obj.Any> {}
|
|
33
|
+
|
|
34
|
+
// TODO(dmaretskyi): Has to be `unique symbol`.
|
|
35
|
+
export const Source: unique symbol = EchoSchema.RelationSourceId as any;
|
|
36
|
+
export type Source = typeof Source;
|
|
37
|
+
export const Target: unique symbol = EchoSchema.RelationTargetId as any;
|
|
38
|
+
export type Target = typeof Target;
|
|
39
|
+
|
|
40
|
+
type MakeProps<T extends Any> = {
|
|
41
|
+
id?: EchoSchema.ObjectId;
|
|
42
|
+
[Source]: T[Source];
|
|
43
|
+
[Target]: T[Target];
|
|
44
|
+
} & Type.Properties<T>;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Creates new relation.
|
|
48
|
+
* @param schema - Relation schema.
|
|
49
|
+
* @param props - Relation properties. Endpoints are passed as [Relation.Source] and [Relation.Target] keys.
|
|
50
|
+
* @param meta - Relation metadata.
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
// NOTE: Writing the definition this way (with generic over schema) makes typescript perfer to infer the type from the first param (this schema) rather than the second param (the props).
|
|
54
|
+
// TODO(dmaretskyi): Move meta into props.
|
|
55
|
+
export const make = <S extends Type.Relation.Any>(
|
|
56
|
+
schema: S,
|
|
57
|
+
props: NoInfer<MakeProps<Schema.Schema.Type<S>>>,
|
|
58
|
+
meta?: EchoSchema.ObjectMeta,
|
|
59
|
+
): Live<Schema.Schema.Type<S> & Type.OfKind<EchoSchema.EntityKind.Relation>> => {
|
|
60
|
+
assertArgument(
|
|
61
|
+
EchoSchema.getTypeAnnotation(schema)?.kind === EchoSchema.EntityKind.Relation,
|
|
62
|
+
'Expected a relation schema',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (props[EchoSchema.MetaId] != null) {
|
|
66
|
+
meta = props[EchoSchema.MetaId] as any;
|
|
67
|
+
delete props[EchoSchema.MetaId];
|
|
68
|
+
}
|
|
12
69
|
|
|
13
|
-
|
|
14
|
-
|
|
70
|
+
const sourceDXN = EchoSchema.getObjectDXN(props[Source]) ?? raise(new Error('Unresolved relation source'));
|
|
71
|
+
const targetDXN = EchoSchema.getObjectDXN(props[Target]) ?? raise(new Error('Unresolved relation target'));
|
|
72
|
+
(props as any)[EchoSchema.RelationSourceDXNId] = sourceDXN;
|
|
73
|
+
(props as any)[EchoSchema.RelationTargetDXNId] = targetDXN;
|
|
15
74
|
|
|
16
|
-
|
|
75
|
+
return live<Schema.Schema.Type<S>>(schema, props as any, meta);
|
|
76
|
+
};
|
|
17
77
|
|
|
18
78
|
export const isRelation = (value: unknown): value is Any => {
|
|
19
79
|
if (typeof value !== 'object' || value === null) {
|
|
@@ -34,7 +94,7 @@ export const isRelation = (value: unknown): value is Any => {
|
|
|
34
94
|
export const getSourceDXN = (value: Any): DXN => {
|
|
35
95
|
assertArgument(isRelation(value), 'Expected a relation');
|
|
36
96
|
assumeType<EchoSchema.InternalObjectProps>(value);
|
|
37
|
-
const dxn = value[EchoSchema.RelationSourceDXNId];
|
|
97
|
+
const dxn = (value as EchoSchema.InternalObjectProps)[EchoSchema.RelationSourceDXNId];
|
|
38
98
|
invariant(dxn instanceof DXN);
|
|
39
99
|
return dxn;
|
|
40
100
|
};
|
|
@@ -46,7 +106,7 @@ export const getSourceDXN = (value: Any): DXN => {
|
|
|
46
106
|
export const getTargetDXN = (value: Any): DXN => {
|
|
47
107
|
assertArgument(isRelation(value), 'Expected a relation');
|
|
48
108
|
assumeType<EchoSchema.InternalObjectProps>(value);
|
|
49
|
-
const dxn = value[EchoSchema.RelationTargetDXNId];
|
|
109
|
+
const dxn = (value as EchoSchema.InternalObjectProps)[EchoSchema.RelationTargetDXNId];
|
|
50
110
|
invariant(dxn instanceof DXN);
|
|
51
111
|
return dxn;
|
|
52
112
|
};
|
|
@@ -55,20 +115,22 @@ export const getTargetDXN = (value: Any): DXN => {
|
|
|
55
115
|
* @returns Relation source.
|
|
56
116
|
* @throws If the object is not a relation.
|
|
57
117
|
*/
|
|
58
|
-
export const getSource = <T extends Any>(relation: T):
|
|
118
|
+
export const getSource = <T extends Any>(relation: T): Type.Relation.Source<T> => {
|
|
59
119
|
assertArgument(isRelation(relation), 'Expected a relation');
|
|
60
|
-
|
|
120
|
+
assumeType<EchoSchema.InternalObjectProps>(relation);
|
|
121
|
+
const obj = (relation as EchoSchema.InternalObjectProps)[EchoSchema.RelationSourceId];
|
|
61
122
|
invariant(obj !== undefined, `Invalid source: ${relation.id}`);
|
|
62
|
-
return obj
|
|
123
|
+
return obj as Type.Relation.Source<T>;
|
|
63
124
|
};
|
|
64
125
|
|
|
65
126
|
/**
|
|
66
127
|
* @returns Relation target.
|
|
67
128
|
* @throws If the object is not a relation.
|
|
68
129
|
*/
|
|
69
|
-
export const getTarget = <T extends Any>(relation: T):
|
|
130
|
+
export const getTarget = <T extends Any>(relation: T): Type.Relation.Target<T> => {
|
|
70
131
|
assertArgument(isRelation(relation), 'Expected a relation');
|
|
71
|
-
|
|
132
|
+
assumeType<EchoSchema.InternalObjectProps>(relation);
|
|
133
|
+
const obj = (relation as EchoSchema.InternalObjectProps)[EchoSchema.RelationTargetId];
|
|
72
134
|
invariant(obj !== undefined, `Invalid target: ${relation.id}`);
|
|
73
|
-
return obj
|
|
135
|
+
return obj as Type.Relation.Target<T>;
|
|
74
136
|
};
|
package/src/Type.ts
CHANGED
|
@@ -3,23 +3,75 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { type Schema } from 'effect';
|
|
6
|
+
import type { Simplify } from 'effect/Schema';
|
|
6
7
|
|
|
7
8
|
import type { EncodedReference } from '@dxos/echo-protocol';
|
|
8
9
|
import * as EchoSchema from '@dxos/echo-schema';
|
|
10
|
+
import type { ToMutable } from '@dxos/echo-schema';
|
|
9
11
|
import { invariant } from '@dxos/invariant';
|
|
10
12
|
import type * as Keys from '@dxos/keys';
|
|
11
13
|
|
|
14
|
+
import type * as RelationModule from './Relation';
|
|
15
|
+
|
|
16
|
+
export const KindId: unique symbol = EchoSchema.EntityKindId as any;
|
|
17
|
+
export type KindId = typeof KindId;
|
|
18
|
+
|
|
19
|
+
export { EntityKind as Kind } from '@dxos/echo-schema';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Assigns a kind to an Object or Relation instance.
|
|
23
|
+
*/
|
|
24
|
+
// NOTE: Needed to make `isRelation` and `isObject` checks work.
|
|
25
|
+
export interface OfKind<Kind extends EchoSchema.EntityKind> {
|
|
26
|
+
readonly id: Keys.ObjectId;
|
|
27
|
+
readonly [KindId]: Kind;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ObjJsonProps {
|
|
31
|
+
id: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface RelationJsonProps {
|
|
35
|
+
id: string;
|
|
36
|
+
[EchoSchema.ATTR_RELATION_SOURCE]: string;
|
|
37
|
+
[EchoSchema.ATTR_RELATION_TARGET]: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
12
40
|
/**
|
|
13
|
-
*
|
|
41
|
+
* Returns all properties of an object or relation except for the id and kind.
|
|
42
|
+
*/
|
|
43
|
+
export type Properties<T> = Omit<T, 'id' | KindId | RelationModule.Source | RelationModule.Target>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Base ECHO schema type.
|
|
14
47
|
*/
|
|
15
48
|
export type Schema = EchoSchema.EchoSchema;
|
|
16
49
|
|
|
17
50
|
/**
|
|
18
|
-
*
|
|
51
|
+
* Return type of the `Obj` schema constructor.
|
|
52
|
+
*
|
|
53
|
+
* This typedef avoids `TS4023` error (name from external module cannot be used named).
|
|
54
|
+
* See Effect's note on interface types.
|
|
55
|
+
*/
|
|
56
|
+
export interface obj<Self extends Schema.Schema.Any>
|
|
57
|
+
extends Schema.AnnotableClass<
|
|
58
|
+
obj<Self>,
|
|
59
|
+
OfKind<EchoSchema.EntityKind.Object> & ToMutable<Schema.Schema.Type<Self>>,
|
|
60
|
+
Simplify<ObjJsonProps & ToMutable<Schema.Schema.Encoded<Self>>>,
|
|
61
|
+
Schema.Schema.Context<Self>
|
|
62
|
+
>,
|
|
63
|
+
EchoSchema.TypeMeta {}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Object schema.
|
|
19
67
|
*/
|
|
20
|
-
export const Obj
|
|
68
|
+
export const Obj: {
|
|
69
|
+
(opts: EchoSchema.TypeMeta): <Self extends Schema.Schema.Any>(self: Self) => obj<Self>;
|
|
70
|
+
} = EchoSchema.EchoObject as any;
|
|
21
71
|
|
|
22
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Object schema type definitions.
|
|
74
|
+
*/
|
|
23
75
|
export namespace Obj {
|
|
24
76
|
/**
|
|
25
77
|
* Type that represents an arbitrary schema type of an object.
|
|
@@ -30,11 +82,38 @@ export namespace Obj {
|
|
|
30
82
|
}
|
|
31
83
|
|
|
32
84
|
/**
|
|
33
|
-
*
|
|
85
|
+
* Return type of the `Relation` schema constructor.
|
|
86
|
+
*
|
|
87
|
+
* This typedef avoids `TS4023` error (name from external module cannot be used named).
|
|
88
|
+
* See Effect's note on interface types.
|
|
89
|
+
*/
|
|
90
|
+
export interface relation<
|
|
91
|
+
Self extends Schema.Schema.Any,
|
|
92
|
+
SourceSchema extends Schema.Schema.Any,
|
|
93
|
+
TargetSchema extends Schema.Schema.Any,
|
|
94
|
+
> extends Schema.AnnotableClass<
|
|
95
|
+
relation<Self, SourceSchema, TargetSchema>,
|
|
96
|
+
OfKind<EchoSchema.EntityKind.Relation> &
|
|
97
|
+
Relation.Endpoints<Schema.Schema.Type<SourceSchema>, Schema.Schema.Type<TargetSchema>> &
|
|
98
|
+
ToMutable<Schema.Schema.Type<Self>>,
|
|
99
|
+
Simplify<RelationJsonProps & ToMutable<Schema.Schema.Encoded<Self>>>,
|
|
100
|
+
Schema.Schema.Context<Self>
|
|
101
|
+
>,
|
|
102
|
+
EchoSchema.TypeMeta {}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Relation schema.
|
|
34
106
|
*/
|
|
35
|
-
|
|
107
|
+
// TODO(dmaretskyi): I have to redefine the type here so that the definition uses symbols from @dxos/echo/Relation.
|
|
108
|
+
export const Relation: {
|
|
109
|
+
<Source extends Schema.Schema.AnyNoContext, Target extends Schema.Schema.AnyNoContext>(
|
|
110
|
+
opts: EchoSchema.EchoRelationOptions<Source, Target>,
|
|
111
|
+
): <Self extends Schema.Schema.Any>(self: Self) => relation<Self, Source, Target>;
|
|
112
|
+
} = EchoSchema.EchoRelation as any;
|
|
36
113
|
|
|
37
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Relation schema type definitions.
|
|
116
|
+
*/
|
|
38
117
|
export namespace Relation {
|
|
39
118
|
/**
|
|
40
119
|
* Type that represents an arbitrary schema type of a relation.
|
|
@@ -46,18 +125,32 @@ export namespace Relation {
|
|
|
46
125
|
/**
|
|
47
126
|
* Get relation target type.
|
|
48
127
|
*/
|
|
49
|
-
export type Target<A> = A extends
|
|
128
|
+
export type Target<A> = A extends Relation.Endpoints<infer _S, infer T> ? T : never;
|
|
50
129
|
|
|
51
130
|
/**
|
|
52
131
|
* Get relation source type.
|
|
53
132
|
*/
|
|
54
|
-
export type Source<A> = A extends
|
|
133
|
+
export type Source<A> = A extends Relation.Endpoints<infer S, infer _T> ? S : never;
|
|
134
|
+
|
|
135
|
+
export type Endpoints<Source, Target> = {
|
|
136
|
+
[RelationModule.Source]: Source;
|
|
137
|
+
[RelationModule.Target]: Target;
|
|
138
|
+
};
|
|
55
139
|
}
|
|
56
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Return type of the `Ref` schema constructor.
|
|
143
|
+
*
|
|
144
|
+
* This typedef avoids `TS4023` error (name from external module cannot be used named).
|
|
145
|
+
* See Effect's note on interface types.
|
|
146
|
+
*/
|
|
147
|
+
export interface ref<TargetSchema extends Schema.Schema.Any>
|
|
148
|
+
extends EchoSchema.Ref$<Schema.Schema.Type<TargetSchema>> {}
|
|
149
|
+
|
|
57
150
|
/**
|
|
58
151
|
* Ref schema.
|
|
59
152
|
*/
|
|
60
|
-
export const Ref: <S extends Obj.Any>(schema: S) =>
|
|
153
|
+
export const Ref: <S extends Obj.Any>(schema: S) => ref<S> = EchoSchema.Ref;
|
|
61
154
|
|
|
62
155
|
export interface Ref<T> extends Schema.SchemaClass<EchoSchema.Ref<T>, EncodedReference> {}
|
|
63
156
|
|
|
@@ -112,8 +205,6 @@ export const getMeta = (schema: Obj.Any | Relation.Any): Meta | undefined => {
|
|
|
112
205
|
return EchoSchema.getTypeAnnotation(schema);
|
|
113
206
|
};
|
|
114
207
|
|
|
115
|
-
export { EntityKind as Kind } from '@dxos/echo-schema';
|
|
116
|
-
|
|
117
208
|
/**
|
|
118
209
|
* @returns True if the schema is mutable.
|
|
119
210
|
*/
|
|
@@ -121,9 +212,17 @@ export const isMutable = EchoSchema.isMutable;
|
|
|
121
212
|
|
|
122
213
|
export { SpaceId, ObjectId, DXN } from '@dxos/keys';
|
|
123
214
|
|
|
124
|
-
export {
|
|
125
|
-
|
|
215
|
+
export interface Expando extends OfKind<EchoSchema.EntityKind.Object> {
|
|
216
|
+
[key: string]: any;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export const Expando: Schema.Schema<
|
|
126
220
|
Expando,
|
|
221
|
+
Simplify<ObjJsonProps & { [key: string]: any }>,
|
|
222
|
+
never
|
|
223
|
+
> = EchoSchema.Expando as any;
|
|
224
|
+
|
|
225
|
+
export {
|
|
127
226
|
// TODO(burdon): Standardize.
|
|
128
227
|
Format,
|
|
129
228
|
JsonSchemaType as JsonSchema,
|
package/src/index.ts
CHANGED