@dxos/echo 0.8.2-staging.7ac8446 → 0.8.3-main.672df60
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/README.md +120 -0
- package/dist/lib/browser/index.mjs +274 -32
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +276 -28
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +274 -32
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/Obj.d.ts +61 -0
- package/dist/types/src/Obj.d.ts.map +1 -0
- package/dist/types/src/Ref.d.ts +15 -0
- package/dist/types/src/Ref.d.ts.map +1 -0
- package/dist/types/src/Relation.d.ts +32 -0
- package/dist/types/src/Relation.d.ts.map +1 -0
- package/dist/types/src/Type.d.ts +80 -42
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/{Database.d.ts → experimental/database.d.ts} +1 -1
- package/dist/types/src/experimental/database.d.ts.map +1 -0
- package/dist/types/src/experimental/index.d.ts +1 -0
- package/dist/types/src/experimental/index.d.ts.map +1 -0
- package/dist/types/src/{Queue.d.ts → experimental/queue.d.ts} +1 -1
- package/dist/types/src/experimental/queue.d.ts.map +1 -0
- package/dist/types/src/{Space.d.ts → experimental/space.d.ts} +1 -1
- package/dist/types/src/experimental/space.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -5
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/{api.test.d.ts.map → test/api.test.d.ts.map} +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -15
- package/src/Obj.ts +120 -0
- package/src/Ref.ts +26 -0
- package/src/Relation.ts +74 -0
- package/src/Type.ts +103 -75
- package/src/{Database.ts → experimental/database.ts} +1 -1
- package/src/experimental/index.ts +7 -0
- package/src/{Queue.ts → experimental/queue.ts} +1 -1
- package/src/index.ts +6 -7
- package/src/test/api.test.ts +128 -0
- package/dist/types/src/Database.d.ts.map +0 -1
- package/dist/types/src/Queue.d.ts.map +0 -1
- package/dist/types/src/Space.d.ts.map +0 -1
- package/src/api.test.ts +0 -94
- /package/dist/types/src/{api.test.d.ts → test/api.test.d.ts} +0 -0
- /package/src/{Space.ts → experimental/space.ts} +0 -0
package/dist/types/src/Type.d.ts
CHANGED
|
@@ -1,49 +1,87 @@
|
|
|
1
1
|
import { type Schema } from 'effect';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import type { EncodedReference } from '@dxos/echo-protocol';
|
|
3
|
+
import * as EchoSchema from '@dxos/echo-schema';
|
|
4
|
+
import type * as Keys from '@dxos/keys';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @category api namespace
|
|
9
|
-
* @since 0.9.0
|
|
6
|
+
* ECHO schema.
|
|
10
7
|
*/
|
|
11
|
-
export
|
|
8
|
+
export type Schema = EchoSchema.EchoSchema;
|
|
9
|
+
/**
|
|
10
|
+
* EchoObject schema.
|
|
11
|
+
*/
|
|
12
|
+
export declare const Obj: (meta: EchoSchema.TypeMeta) => <Self extends Schema.Schema.Any>(self: Self) => EchoSchema.EchoTypeSchema<Self>;
|
|
13
|
+
/**
|
|
14
|
+
* EchoRelation schema.
|
|
15
|
+
*/
|
|
16
|
+
export declare const Relation: <Source extends Schema.Schema.AnyNoContext, Target extends Schema.Schema.AnyNoContext>(options: {
|
|
17
|
+
typename: string;
|
|
18
|
+
version: string;
|
|
19
|
+
source: Source;
|
|
20
|
+
target: Target;
|
|
21
|
+
}) => <Self extends Schema.Schema.Any>(self: Self) => EchoSchema.EchoTypeSchema<Self, EchoSchema.RelationSourceTargetRefs<Schema.Schema.Type<Source>, Schema.Schema.Type<Target>>>;
|
|
22
|
+
/**
|
|
23
|
+
* Ref schema.
|
|
24
|
+
*/
|
|
25
|
+
export declare const Ref: <S extends Obj.Any>(schema: S) => EchoSchema.Ref$<Schema.Schema.Type<S>>;
|
|
26
|
+
export declare namespace Obj {
|
|
27
|
+
/**
|
|
28
|
+
* Type that represents an arbitrary schema type of an object.
|
|
29
|
+
* NOTE: This is not an instance type.
|
|
30
|
+
*/
|
|
31
|
+
type Any = Schema.Schema.AnyNoContext;
|
|
32
|
+
}
|
|
33
|
+
export declare namespace Relation {
|
|
34
|
+
/**
|
|
35
|
+
* Type that represents an arbitrary schema type of a relation.
|
|
36
|
+
* NOTE: This is not an instance type.
|
|
37
|
+
*/
|
|
38
|
+
type Any = Schema.Schema.AnyNoContext;
|
|
39
|
+
/**
|
|
40
|
+
* Get relation target type.
|
|
41
|
+
*/
|
|
42
|
+
type Target<A> = A extends EchoSchema.RelationSourceTargetRefs<infer T, infer _S> ? T : never;
|
|
43
|
+
/**
|
|
44
|
+
* Get relation source type.
|
|
45
|
+
*/
|
|
46
|
+
type Source<A> = A extends EchoSchema.RelationSourceTargetRefs<infer _T, infer S> ? S : never;
|
|
47
|
+
}
|
|
48
|
+
export declare namespace Ref {
|
|
12
49
|
/**
|
|
13
|
-
*
|
|
50
|
+
* Type that represents an arbitrary schema type of a reference.
|
|
51
|
+
* NOTE: This is not an instance type.
|
|
14
52
|
*/
|
|
15
|
-
type
|
|
16
|
-
type Abstract<T = any> = BaseSchema<T>;
|
|
17
|
-
type ImmutableType<T> = ImmutableSchema<T>;
|
|
18
|
-
type MutableType<T> = EchoSchema<T>;
|
|
53
|
+
type Any = Schema.Schema<EchoSchema.Ref<any>, EncodedReference>;
|
|
19
54
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
* @
|
|
29
|
-
*
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Gets the full DXN of the schema.
|
|
57
|
+
* Will include the version if it's a `type` DXN.
|
|
58
|
+
* @example "dxn:example.com/type/Person:0.1.0"
|
|
59
|
+
* @example "dxn:echo:SSSSSSSSSS:XXXXXXXXXXXXX"
|
|
60
|
+
*/
|
|
61
|
+
export declare const getDXN: (schema: Obj.Any | Relation.Any) => Keys.DXN | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* @param schema - Schema to get the typename from.
|
|
64
|
+
* @returns The typename of the schema. Example: `example.com/type/Person`.
|
|
65
|
+
*/
|
|
66
|
+
export declare const getTypename: (schema: Obj.Any | Relation.Any) => string;
|
|
67
|
+
/**
|
|
68
|
+
* Gets the version of the schema.
|
|
69
|
+
* @example 0.1.0
|
|
70
|
+
*/
|
|
71
|
+
export declare const getVersion: (schema: Obj.Any | Relation.Any) => string;
|
|
72
|
+
/**
|
|
73
|
+
* ECHO type metadata.
|
|
74
|
+
*/
|
|
75
|
+
export type Meta = EchoSchema.TypeAnnotation;
|
|
76
|
+
/**
|
|
77
|
+
* Gets the meta data of the schema.
|
|
78
|
+
*/
|
|
79
|
+
export declare const getMeta: (schema: Obj.Any | Relation.Any) => Meta | undefined;
|
|
80
|
+
export { EntityKind as Kind } from '@dxos/echo-schema';
|
|
81
|
+
/**
|
|
82
|
+
* @returns True if the schema is mutable.
|
|
83
|
+
*/
|
|
84
|
+
export declare const isMutable: (schema: Obj.Any | Relation.Any) => boolean;
|
|
85
|
+
export { SpaceId, ObjectId, DXN } from '@dxos/keys';
|
|
86
|
+
export { Expando, JsonSchemaType as JsonSchema, toJsonSchema, Format, } from '@dxos/echo-schema';
|
|
49
87
|
//# sourceMappingURL=Type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Type.d.ts","sourceRoot":"","sources":["../../../src/Type.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"Type.d.ts","sourceRoot":"","sources":["../../../src/Type.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,KAAK,IAAI,MAAM,YAAY,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,GAAG,gHAAwB,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;kLAA0B,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,GAAG,EAAE,CAAC,CAAC,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAkB,CAAC;AAE5G,yBAAiB,GAAG,CAAC;IACnB;;;OAGG;IAEH,KAAY,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;CAC9C;AAED,yBAAiB,QAAQ,CAAC;IACxB;;;OAGG;IAEH,KAAY,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC;IAE7C;;OAEG;IACH,KAAY,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAErG;;OAEG;IACH,KAAY,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,wBAAwB,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;CACtG;AAED,yBAAiB,GAAG,CAAC;IACnB;;;OAGG;IACH,KAAY,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAC;CACxE;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,QAAQ,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAG,IAAI,CAAC,GAAG,GAAG,SAElE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAG,MAI5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAG,MAI3D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,cAAc,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,QAAQ,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAG,IAAI,GAAG,SAE/D,CAAC;AAEF,OAAO,EAAE,UAAU,IAAI,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,QAAQ,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,KAAG,OAE1D,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAEL,OAAO,EACP,cAAc,IAAI,UAAU,EAC5B,YAAY,EACZ,MAAM,GACP,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../../src/experimental/database.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,yBAAiB,QAAQ,CAAC,GAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/experimental/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../../src/experimental/queue.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,yBAAiB,KAAK,CAAC,GAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"space.d.ts","sourceRoot":"","sources":["../../../../src/experimental/space.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,WAAW,KAAK,CAAC,GAAE"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DXN } from '@dxos/keys';
|
|
2
|
-
export { DXN };
|
|
3
|
-
export * as Database from './Database';
|
|
4
|
-
export * as Queue from './Queue';
|
|
5
|
-
export * as Space from './Space';
|
|
6
1
|
export * as Type from './Type';
|
|
2
|
+
export * as Obj from './Obj';
|
|
3
|
+
export * as Relation from './Relation';
|
|
4
|
+
export * as Ref from './Ref';
|
|
5
|
+
export { type Live } from '@dxos/live-object';
|
|
6
|
+
export { Filter, Query } from '@dxos/echo-schema';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAE7B,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.test.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"api.test.d.ts","sourceRoot":"","sources":["../../../../src/test/api.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.
|
|
1
|
+
{"version":"5.8.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3-main.672df60",
|
|
4
4
|
"description": "ECHO API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -21,20 +21,19 @@
|
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@preact/signals-core": "^1.
|
|
25
|
-
"effect": "3.
|
|
26
|
-
"@dxos/debug": "0.8.
|
|
27
|
-
"@dxos/echo-
|
|
28
|
-
"@dxos/echo-schema": "0.8.
|
|
29
|
-
"@dxos/echo-
|
|
30
|
-
"@dxos/
|
|
31
|
-
"@dxos/invariant": "0.8.
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/
|
|
36
|
-
"@dxos/util": "0.8.
|
|
37
|
-
"@dxos/log": "0.8.2-staging.7ac8446"
|
|
24
|
+
"@preact/signals-core": "^1.9.0",
|
|
25
|
+
"effect": "3.14.21",
|
|
26
|
+
"@dxos/debug": "0.8.3-main.672df60",
|
|
27
|
+
"@dxos/echo-protocol": "0.8.3-main.672df60",
|
|
28
|
+
"@dxos/echo-schema": "0.8.3-main.672df60",
|
|
29
|
+
"@dxos/echo-signals": "0.8.3-main.672df60",
|
|
30
|
+
"@dxos/effect": "0.8.3-main.672df60",
|
|
31
|
+
"@dxos/invariant": "0.8.3-main.672df60",
|
|
32
|
+
"@dxos/keys": "0.8.3-main.672df60",
|
|
33
|
+
"@dxos/live-object": "0.8.3-main.672df60",
|
|
34
|
+
"@dxos/node-std": "0.8.3-main.672df60",
|
|
35
|
+
"@dxos/log": "0.8.3-main.672df60",
|
|
36
|
+
"@dxos/util": "0.8.3-main.672df60"
|
|
38
37
|
},
|
|
39
38
|
"publishConfig": {
|
|
40
39
|
"access": "public"
|
package/src/Obj.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Schema } from 'effect';
|
|
6
|
+
|
|
7
|
+
import * as EchoSchema from '@dxos/echo-schema';
|
|
8
|
+
import { assertArgument, invariant } from '@dxos/invariant';
|
|
9
|
+
import type { DXN } from '@dxos/keys';
|
|
10
|
+
import * as LiveObject from '@dxos/live-object';
|
|
11
|
+
|
|
12
|
+
import type * as Ref from './Ref';
|
|
13
|
+
import type * as Type from './Type';
|
|
14
|
+
|
|
15
|
+
export type Any = EchoSchema.AnyEchoObject;
|
|
16
|
+
|
|
17
|
+
export const make = LiveObject.live;
|
|
18
|
+
|
|
19
|
+
// TODO(dmaretskyi): Currently broken
|
|
20
|
+
export const isObject = (obj: unknown): obj is Any => {
|
|
21
|
+
return LiveObject.isLiveObject(obj);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Check that object or relation is an instance of a schema.
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const person = Obj.make(Person, { name: 'John' });
|
|
29
|
+
* const isPerson = Obj.instanceOf(Person);
|
|
30
|
+
* isPerson(person); // true
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export const instanceOf: {
|
|
34
|
+
<S extends Type.Relation.Any | Type.Obj.Any>(schema: S): (value: unknown) => value is S;
|
|
35
|
+
<S extends Type.Relation.Any | Type.Obj.Any>(schema: S, value: unknown): value is S;
|
|
36
|
+
} = ((...args: any[]) => {
|
|
37
|
+
if (args.length === 1) {
|
|
38
|
+
return (obj: unknown) => EchoSchema.isInstanceOf(args[0], obj);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return EchoSchema.isInstanceOf(args[0], args[1]);
|
|
42
|
+
}) as any;
|
|
43
|
+
|
|
44
|
+
export const getSchema = EchoSchema.getSchema;
|
|
45
|
+
|
|
46
|
+
// TODO(dmaretskyi): Allow returning undefined.
|
|
47
|
+
export const getDXN = (obj: Any): DXN => {
|
|
48
|
+
assertArgument(!Schema.isSchema(obj), 'Object should not be a schema.');
|
|
49
|
+
const dxn = EchoSchema.getObjectDXN(obj);
|
|
50
|
+
invariant(dxn != null, 'Invalid object.');
|
|
51
|
+
return dxn;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @returns The DXN of the object's type.
|
|
56
|
+
* @example dxn:example.com/type/Contact:1.0.0
|
|
57
|
+
*/
|
|
58
|
+
// TODO(dmaretskyi): Allow returning undefined.
|
|
59
|
+
export const getSchemaDXN = (obj: Any): DXN => {
|
|
60
|
+
const type = EchoSchema.getType(obj);
|
|
61
|
+
invariant(type != null, 'Invalid object.');
|
|
62
|
+
return type;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @returns The typename of the object's type.
|
|
67
|
+
* @example `example.com/type/Contact`
|
|
68
|
+
*/
|
|
69
|
+
export const getTypename = (obj: Any): string | undefined => {
|
|
70
|
+
const schema = getSchema(obj);
|
|
71
|
+
if (schema == null) {
|
|
72
|
+
// Try to extract typename from DXN.
|
|
73
|
+
return getSchemaDXN(obj)?.asTypeDXN()?.type;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return EchoSchema.getSchemaTypename(schema);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// TODO(dmaretskyi): Allow returning undefined.
|
|
80
|
+
export const getMeta = (obj: Any): EchoSchema.ObjectMeta => {
|
|
81
|
+
const meta = EchoSchema.getMeta(obj);
|
|
82
|
+
invariant(meta != null, 'Invalid object.');
|
|
83
|
+
return meta;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// TODO(dmaretskyi): Default to `false`.
|
|
87
|
+
export const isDeleted = (obj: Any): boolean => {
|
|
88
|
+
const deleted = EchoSchema.isDeleted(obj);
|
|
89
|
+
invariant(typeof deleted === 'boolean', 'Invalid object.');
|
|
90
|
+
return deleted;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export const getLabel = (obj: Any): string | undefined => {
|
|
94
|
+
const schema = getSchema(obj);
|
|
95
|
+
if (schema != null) {
|
|
96
|
+
return EchoSchema.getLabel(schema, obj);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* JSON representation of an object.
|
|
102
|
+
*/
|
|
103
|
+
export type JSON = EchoSchema.ObjectJSON;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Converts object to it's JSON representation.
|
|
107
|
+
*
|
|
108
|
+
* The same algorithm is used when calling the standard `JSON.stringify(obj)` function.
|
|
109
|
+
*/
|
|
110
|
+
export const toJSON = (obj: Any): JSON => EchoSchema.objectToJSON(obj);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Creates an object from it's json representation.
|
|
114
|
+
* Performs schema validation.
|
|
115
|
+
* References and schema will be resolvable if the `refResolver` is provided.
|
|
116
|
+
*
|
|
117
|
+
* The function need to be async to support resolving the schema as well as the relation endpoints.
|
|
118
|
+
*/
|
|
119
|
+
export const fromJSON: (json: unknown, options?: { refResolver?: Ref.Resolver }) => Promise<Any> =
|
|
120
|
+
EchoSchema.objectFromJSON;
|
package/src/Ref.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as EchoSchema from '@dxos/echo-schema';
|
|
6
|
+
|
|
7
|
+
import type * as Obj from './Obj';
|
|
8
|
+
|
|
9
|
+
export type Any = EchoSchema.Ref<Obj.Any>;
|
|
10
|
+
|
|
11
|
+
export const make = EchoSchema.Ref.make;
|
|
12
|
+
|
|
13
|
+
export const isRef: (value: unknown) => value is Any = EchoSchema.Ref.isRef;
|
|
14
|
+
|
|
15
|
+
// TODO(dmaretskyi): Consider just allowing `make` to accept DXN.
|
|
16
|
+
export const fromDXN = EchoSchema.Ref.fromDXN;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extract reference target.
|
|
20
|
+
*/
|
|
21
|
+
export type Target<R extends Any> = R extends EchoSchema.Ref<infer T> ? T : never;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Reference resolver.
|
|
25
|
+
*/
|
|
26
|
+
export type Resolver = EchoSchema.RefResolver;
|
package/src/Relation.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as EchoSchema from '@dxos/echo-schema';
|
|
6
|
+
import { assertArgument, invariant } from '@dxos/invariant';
|
|
7
|
+
import { DXN } from '@dxos/keys';
|
|
8
|
+
import * as LiveObject from '@dxos/live-object';
|
|
9
|
+
import { assumeType } from '@dxos/util';
|
|
10
|
+
|
|
11
|
+
export type Any = EchoSchema.AnyEchoObject & EchoSchema.RelationSourceTargetRefs;
|
|
12
|
+
|
|
13
|
+
export const Source = EchoSchema.RelationSourceId;
|
|
14
|
+
export const Target = EchoSchema.RelationTargetId;
|
|
15
|
+
|
|
16
|
+
export const make = LiveObject.live;
|
|
17
|
+
|
|
18
|
+
export const isRelation = (value: unknown): value is Any => {
|
|
19
|
+
if (typeof value !== 'object' || value === null) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (EchoSchema.ATTR_RELATION_SOURCE in value || EchoSchema.ATTR_RELATION_TARGET in value) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const kind = (value as any)[EchoSchema.EntityKindId];
|
|
27
|
+
return kind === EchoSchema.EntityKind.Relation;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @returns Relation source DXN.
|
|
32
|
+
* @throws If the object is not a relation.
|
|
33
|
+
*/
|
|
34
|
+
export const getSourceDXN = (value: Any): DXN => {
|
|
35
|
+
assertArgument(isRelation(value), 'Expected a relation');
|
|
36
|
+
assumeType<EchoSchema.InternalObjectProps>(value);
|
|
37
|
+
const dxn = value[EchoSchema.RelationSourceDXNId];
|
|
38
|
+
invariant(dxn instanceof DXN);
|
|
39
|
+
return dxn;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @returns Relation target DXN.
|
|
44
|
+
* @throws If the object is not a relation.
|
|
45
|
+
*/
|
|
46
|
+
export const getTargetDXN = (value: Any): DXN => {
|
|
47
|
+
assertArgument(isRelation(value), 'Expected a relation');
|
|
48
|
+
assumeType<EchoSchema.InternalObjectProps>(value);
|
|
49
|
+
const dxn = value[EchoSchema.RelationTargetDXNId];
|
|
50
|
+
invariant(dxn instanceof DXN);
|
|
51
|
+
return dxn;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @returns Relation source.
|
|
56
|
+
* @throws If the object is not a relation.
|
|
57
|
+
*/
|
|
58
|
+
export const getSource = <T extends Any>(relation: T): EchoSchema.RelationSource<T> => {
|
|
59
|
+
assertArgument(isRelation(relation), 'Expected a relation');
|
|
60
|
+
const obj = relation[EchoSchema.RelationSourceId];
|
|
61
|
+
invariant(obj !== undefined, `Invalid source: ${relation.id}`);
|
|
62
|
+
return obj;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @returns Relation target.
|
|
67
|
+
* @throws If the object is not a relation.
|
|
68
|
+
*/
|
|
69
|
+
export const getTarget = <T extends Any>(relation: T): EchoSchema.RelationTarget<T> => {
|
|
70
|
+
assertArgument(isRelation(relation), 'Expected a relation');
|
|
71
|
+
const obj = relation[EchoSchema.RelationTargetId];
|
|
72
|
+
invariant(obj !== undefined, `Invalid target: ${relation.id}`);
|
|
73
|
+
return obj;
|
|
74
|
+
};
|