@dxos/echo 0.8.4-main.d05673bc65 → 0.8.4-main.dfabb4ec29
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 +2 -2
- package/dist/lib/neutral/Annotation.mjs +5 -3
- package/dist/lib/neutral/Database.mjs +8 -4
- package/dist/lib/neutral/Entity.mjs +16 -14
- package/dist/lib/neutral/Err.mjs +1 -1
- package/dist/lib/neutral/Extension.mjs +18 -0
- package/dist/lib/neutral/Extension.mjs.map +7 -0
- package/dist/lib/neutral/Feed.mjs +21 -17
- package/dist/lib/neutral/Filter.mjs +21 -13
- package/dist/lib/neutral/Format.mjs +3 -3
- package/dist/lib/neutral/JsonSchema.mjs +8 -8
- package/dist/lib/neutral/Key.mjs +1 -1
- package/dist/lib/neutral/Migration.mjs +17 -0
- package/dist/lib/neutral/Migration.mjs.map +7 -0
- package/dist/lib/neutral/Obj.mjs +16 -13
- package/dist/lib/neutral/Order.mjs +1 -1
- package/dist/lib/neutral/Query.mjs +19 -16
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +7 -7
- package/dist/lib/neutral/Relation.mjs +15 -14
- package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
- package/dist/lib/neutral/Tag.mjs +14 -13
- package/dist/lib/neutral/Type.mjs +10 -10
- package/dist/lib/neutral/{chunk-FZO7LQO7.mjs → chunk-44HT3MEC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-OENWMTE6.mjs → chunk-5SL5LDLD.mjs} +4 -2
- package/dist/lib/neutral/chunk-5SL5LDLD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-YWXWXIE5.mjs → chunk-6VIJV543.mjs} +2 -2
- package/dist/lib/neutral/{chunk-YWXWXIE5.mjs.map → chunk-6VIJV543.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7RVZT53K.mjs} +1 -1
- package/dist/lib/neutral/{chunk-BNCCGLJN.mjs → chunk-BICZKPQG.mjs} +1 -1
- package/dist/lib/neutral/{chunk-NEGC54NE.mjs → chunk-FHYIM4RD.mjs} +17 -19
- package/dist/lib/neutral/chunk-FHYIM4RD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-RMLF7JOZ.mjs → chunk-FZHVQEHN.mjs} +6 -22
- package/dist/lib/neutral/{chunk-RMLF7JOZ.mjs.map → chunk-FZHVQEHN.mjs.map} +3 -3
- package/dist/lib/neutral/chunk-GWFFC34K.mjs +50 -0
- package/dist/lib/neutral/chunk-GWFFC34K.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-724GQYEN.mjs → chunk-HPNQTEEQ.mjs} +4 -4
- package/dist/lib/neutral/{chunk-UFDK26FO.mjs → chunk-LVGOVFDV.mjs} +12 -8
- package/dist/lib/neutral/chunk-LVGOVFDV.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-43Y5DOS6.mjs → chunk-MPAI2MHO.mjs} +16 -66
- package/dist/lib/neutral/chunk-MPAI2MHO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WYOKA6AE.mjs → chunk-N4B7FHQT.mjs} +2 -2
- package/dist/lib/neutral/{chunk-WYOKA6AE.mjs.map → chunk-N4B7FHQT.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-BOZZPUXE.mjs → chunk-O5LRY6CO.mjs} +12 -65
- package/dist/lib/neutral/chunk-O5LRY6CO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UTBRYVQC.mjs → chunk-QGMIH2SN.mjs} +2 -2
- package/dist/lib/neutral/{chunk-VA2F47ZC.mjs → chunk-QXIANHKU.mjs} +68 -14
- package/dist/lib/neutral/chunk-QXIANHKU.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-NXMFBIT5.mjs → chunk-RF7ZBZ4A.mjs} +59 -4
- package/dist/lib/neutral/chunk-RF7ZBZ4A.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-DYDJBZEG.mjs → chunk-S7IMFVTB.mjs} +51 -21
- package/dist/lib/neutral/chunk-S7IMFVTB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TQQZLKB7.mjs → chunk-SJKBWMJY.mjs} +193 -469
- package/dist/lib/neutral/chunk-SJKBWMJY.mjs.map +7 -0
- package/dist/lib/neutral/chunk-SUZMWP3Y.mjs +36 -0
- package/dist/lib/neutral/chunk-SUZMWP3Y.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-NQRLRYJM.mjs → chunk-SW5CUSBY.mjs} +119 -12
- package/dist/lib/neutral/chunk-SW5CUSBY.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-SEMVAGBM.mjs → chunk-TNBK56IN.mjs} +19 -24
- package/dist/lib/neutral/chunk-TNBK56IN.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-B5OXLWZL.mjs → chunk-TRPZU2HV.mjs} +2 -2
- package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-TTCSATUD.mjs} +1 -1
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
- package/dist/lib/neutral/{chunk-KTAWP7GI.mjs → chunk-VGKLHHRT.mjs} +42 -7
- package/dist/lib/neutral/chunk-VGKLHHRT.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-FXEG7EOK.mjs → chunk-VYAGNFSJ.mjs} +3 -3
- package/dist/lib/neutral/{chunk-CIRHIEMW.mjs → chunk-WRVRDZDA.mjs} +18 -46
- package/dist/lib/neutral/chunk-WRVRDZDA.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-ZISMEVKD.mjs} +1 -1
- package/dist/lib/neutral/{chunk-UBEZSGXY.mjs.map → chunk-ZISMEVKD.mjs.map} +2 -2
- package/dist/lib/neutral/index.mjs +38 -28
- package/dist/lib/neutral/internal/index.mjs +15 -9
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +185 -129
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/types/src/Annotation.d.ts +1 -1
- package/dist/types/src/Annotation.d.ts.map +1 -1
- package/dist/types/src/Collection.d.ts.map +1 -1
- package/dist/types/src/Database.d.ts +13 -1
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +2 -1
- package/dist/types/src/Dataset.d.ts.map +1 -1
- package/dist/types/src/Entity.d.ts +17 -11
- package/dist/types/src/Entity.d.ts.map +1 -1
- package/dist/types/src/Err.d.ts +18 -18
- package/dist/types/src/Err.d.ts.map +1 -1
- package/dist/types/src/Extension.d.ts +80 -0
- package/dist/types/src/Extension.d.ts.map +1 -0
- package/dist/types/src/Extension.test.d.ts +2 -0
- package/dist/types/src/Extension.test.d.ts.map +1 -0
- package/dist/types/src/Feed.d.ts +37 -20
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts +33 -4
- package/dist/types/src/Filter.d.ts.map +1 -1
- package/dist/types/src/Filter.test.d.ts +2 -0
- package/dist/types/src/Filter.test.d.ts.map +1 -0
- package/dist/types/src/Json.d.ts +33 -0
- package/dist/types/src/Json.d.ts.map +1 -0
- package/dist/types/src/Json.test.d.ts +2 -0
- package/dist/types/src/Json.test.d.ts.map +1 -0
- package/dist/types/src/JsonSchema.d.ts +1 -1
- package/dist/types/src/Migration.d.ts +57 -0
- package/dist/types/src/Migration.d.ts.map +1 -0
- package/dist/types/src/Obj.d.ts +41 -27
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Order.d.ts.map +1 -1
- package/dist/types/src/Query.d.ts +13 -2
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +17 -18
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Tag.d.ts +2 -2
- package/dist/types/src/Tag.d.ts.map +1 -1
- package/dist/types/src/Type.d.ts +3 -3
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +1 -1
- package/dist/types/src/View.d.ts.map +1 -1
- package/dist/types/src/exemplars.test.d.ts +2 -0
- package/dist/types/src/exemplars.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/annotations.d.ts +12 -2
- package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/util.d.ts +1 -1
- package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/version.d.ts.map +1 -1
- package/dist/types/src/internal/Format/date.d.ts.map +1 -1
- package/dist/types/src/internal/Format/format.d.ts.map +1 -1
- package/dist/types/src/internal/Format/number.d.ts.map +1 -1
- package/dist/types/src/internal/Format/object.d.ts.map +1 -1
- package/dist/types/src/internal/Format/types.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +28 -28
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/ids.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/json-serializer.d.ts +4 -3
- package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/set-value.d.ts +1 -1
- package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
- package/dist/types/src/internal/Query.d.ts +10 -0
- package/dist/types/src/internal/Query.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref.d.ts +14 -1
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
- package/dist/types/src/internal/Type/echo-schema.d.ts +2 -2
- package/dist/types/src/internal/Type/echo-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
- package/dist/types/src/internal/common/api/meta.d.ts +3 -3
- package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/change-context.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/errors.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/reactive-array.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/reactive.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/reactive.test.d.ts +2 -0
- package/dist/types/src/internal/common/proxy/reactive.test.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/entity.d.ts +4 -4
- package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/version.d.ts +1 -1
- package/dist/types/src/internal/index.d.ts +1 -0
- package/dist/types/src/internal/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts +8 -8
- package/dist/types/src/testing/test-data.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +53 -53
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/dist/types/src/testing/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +24 -14
- package/src/Annotation.ts +1 -0
- package/src/Collection.ts +5 -0
- package/src/Database.ts +49 -14
- package/src/Entity.ts +18 -12
- package/src/Extension.test.ts +235 -0
- package/src/Extension.ts +122 -0
- package/src/Feed.ts +79 -32
- package/src/Filter.test.ts +90 -0
- package/src/Filter.ts +66 -3
- package/src/Json.test.ts +175 -0
- package/src/Json.ts +102 -0
- package/src/Migration.ts +94 -0
- package/src/Obj.test.ts +105 -13
- package/src/Obj.ts +153 -33
- package/src/Query.test.ts +198 -8
- package/src/Query.ts +46 -1
- package/src/Relation.ts +24 -20
- package/src/Type.ts +1 -1
- package/src/View.ts +5 -0
- package/src/exemplars.test.ts +21 -0
- package/src/index.ts +4 -0
- package/src/internal/Annotation/annotations.test.ts +51 -2
- package/src/internal/Annotation/annotations.ts +33 -14
- package/src/internal/Annotation/sorting.ts +0 -1
- package/src/internal/Entity/api.ts +0 -1
- package/src/internal/Entity/object.ts +0 -1
- package/src/internal/Entity/version.ts +0 -1
- package/src/internal/Format/date.test.ts +0 -1
- package/src/internal/Format/format.test.ts +0 -1
- package/src/internal/JsonSchema/json-schema-type.ts +1 -1
- package/src/internal/JsonSchema/json-schema.test.ts +1 -2
- package/src/internal/JsonSchema/json-schema.ts +1 -2
- package/src/internal/Obj/clone.ts +1 -1
- package/src/internal/Obj/create-object.test.ts +2 -4
- package/src/internal/Obj/create-object.ts +2 -3
- package/src/internal/Obj/deleted.ts +1 -1
- package/src/internal/Obj/json-serializer.test.ts +4 -5
- package/src/internal/Obj/json-serializer.ts +22 -15
- package/src/internal/Obj/set-value.test.ts +24 -24
- package/src/internal/Obj/set-value.ts +1 -1
- package/src/internal/Query.ts +137 -0
- package/src/internal/Ref/ref-array.ts +0 -1
- package/src/internal/Ref/ref.test.ts +0 -1
- package/src/internal/Ref/ref.ts +18 -1
- package/src/internal/Type/compose.test.ts +0 -1
- package/src/internal/Type/echo-schema.ts +3 -4
- package/src/internal/Type/persistent-schema.ts +2 -2
- package/src/internal/common/README.md +1 -1
- package/src/internal/common/api/meta.ts +3 -3
- package/src/internal/common/proxy/change-context.ts +1 -1
- package/src/internal/common/proxy/change.test.ts +94 -94
- package/src/internal/common/proxy/errors.ts +2 -2
- package/src/internal/common/proxy/handler.test.ts +0 -2
- package/src/internal/common/proxy/make-object.ts +0 -1
- package/src/internal/common/proxy/ownership.ts +0 -1
- package/src/internal/common/proxy/reactive-array.ts +1 -1
- package/src/internal/common/proxy/reactive.test.ts +54 -0
- package/src/internal/common/proxy/reactive.ts +11 -3
- package/src/internal/common/proxy/typed-handler.test.ts +0 -1
- package/src/internal/common/proxy/typed-handler.ts +8 -10
- package/src/internal/common/proxy/typed-object.test.ts +2 -3
- package/src/internal/common/types/entity.ts +1 -1
- package/src/internal/common/types/meta.ts +0 -1
- package/src/internal/index.ts +1 -0
- package/src/testing/api.test.ts +0 -1
- package/src/testing/test-data.ts +157 -98
- package/dist/lib/neutral/chunk-43Y5DOS6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BOZZPUXE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-CIRHIEMW.mjs.map +0 -7
- package/dist/lib/neutral/chunk-DYDJBZEG.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KTAWP7GI.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NEGC54NE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NQRLRYJM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NXMFBIT5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OENWMTE6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-SEMVAGBM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TQQZLKB7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UFDK26FO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VA2F47ZC.mjs.map +0 -7
- /package/dist/lib/neutral/{chunk-FZO7LQO7.mjs.map → chunk-44HT3MEC.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-ANHVGJI4.mjs.map → chunk-7RVZT53K.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-BNCCGLJN.mjs.map → chunk-BICZKPQG.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-724GQYEN.mjs.map → chunk-HPNQTEEQ.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UTBRYVQC.mjs.map → chunk-QGMIH2SN.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-B5OXLWZL.mjs.map → chunk-TRPZU2HV.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UI6MWK5W.mjs.map → chunk-TTCSATUD.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-OMUPQMLR.mjs.map → chunk-V72DY6LU.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-FXEG7EOK.mjs.map → chunk-VYAGNFSJ.mjs.map} +0 -0
package/src/Relation.ts
CHANGED
|
@@ -15,8 +15,8 @@ import { assumeType } from '@dxos/util';
|
|
|
15
15
|
|
|
16
16
|
import type * as Database from './Database';
|
|
17
17
|
import * as Entity from './Entity';
|
|
18
|
-
import * as entityInternal from './internal/Entity';
|
|
19
18
|
import * as internal from './internal';
|
|
19
|
+
import * as entityInternal from './internal/Entity';
|
|
20
20
|
import * as Obj from './Obj';
|
|
21
21
|
import type * as Type from './Type';
|
|
22
22
|
|
|
@@ -67,7 +67,7 @@ export const Unknown: Type.Relation<Unknown, Obj.Any, Obj.Any> = Schema.Struct({
|
|
|
67
67
|
// NOTE: The EchoRelationSchema annotation is required for Ref.Ref(Relation.Unknown) to work.
|
|
68
68
|
// The typename/version/source/target only satisfy ECHO schema machinery for reference targets.
|
|
69
69
|
internal.EchoRelationSchema({
|
|
70
|
-
typename: 'org.dxos.schema.
|
|
70
|
+
typename: 'org.dxos.schema.anyRelation',
|
|
71
71
|
version: '0.0.0',
|
|
72
72
|
source: Obj.Unknown,
|
|
73
73
|
target: Obj.Unknown,
|
|
@@ -237,7 +237,9 @@ export const getSource = <T extends Unknown | Snapshot>(relation: T): SourceOf<T
|
|
|
237
237
|
assertArgument(isRelation(relation), 'Expected a relation');
|
|
238
238
|
assumeType<internal.InternalObjectProps>(relation);
|
|
239
239
|
const obj = (relation as internal.InternalObjectProps)[internal.RelationSourceId];
|
|
240
|
-
|
|
240
|
+
if (obj === undefined) {
|
|
241
|
+
throw new Error(`Relation source could not be resolved.`);
|
|
242
|
+
}
|
|
241
243
|
return obj as SourceOf<T>;
|
|
242
244
|
};
|
|
243
245
|
|
|
@@ -250,7 +252,9 @@ export const getTarget = <T extends Unknown | Snapshot>(relation: T): TargetOf<T
|
|
|
250
252
|
assertArgument(isRelation(relation), 'Expected a relation');
|
|
251
253
|
assumeType<internal.InternalObjectProps>(relation);
|
|
252
254
|
const obj = (relation as internal.InternalObjectProps)[internal.RelationTargetId];
|
|
253
|
-
|
|
255
|
+
if (obj === undefined) {
|
|
256
|
+
throw new Error(`Relation target could not be resolved.`);
|
|
257
|
+
}
|
|
254
258
|
return obj as TargetOf<T>;
|
|
255
259
|
};
|
|
256
260
|
|
|
@@ -260,7 +264,7 @@ export const getTarget = <T extends Unknown | Snapshot>(relation: T): TargetOf<T
|
|
|
260
264
|
|
|
261
265
|
/**
|
|
262
266
|
* Makes all properties mutable recursively.
|
|
263
|
-
* Used to provide a mutable view of a relation within `Relation.
|
|
267
|
+
* Used to provide a mutable view of a relation within `Relation.update`.
|
|
264
268
|
*/
|
|
265
269
|
export type Mutable<T> = internal.Mutable<T>;
|
|
266
270
|
|
|
@@ -268,10 +272,10 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
268
272
|
* Perform mutations on an echo relation within a controlled context.
|
|
269
273
|
*
|
|
270
274
|
* All mutations within the callback are batched and trigger a single notification
|
|
271
|
-
* when the callback completes. Direct mutations outside of `Relation.
|
|
275
|
+
* when the callback completes. Direct mutations outside of `Relation.update` will throw
|
|
272
276
|
* an error for echo relations.
|
|
273
277
|
*
|
|
274
|
-
* @param relation - The echo relation to mutate. Use `Obj.
|
|
278
|
+
* @param relation - The echo relation to mutate. Use `Obj.update` for objects.
|
|
275
279
|
* @param callback - The callback that performs mutations on the relation.
|
|
276
280
|
*
|
|
277
281
|
* @example
|
|
@@ -282,15 +286,15 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
282
286
|
* role: 'Engineer',
|
|
283
287
|
* });
|
|
284
288
|
*
|
|
285
|
-
* // Mutate within Relation.
|
|
286
|
-
* Relation.
|
|
287
|
-
*
|
|
289
|
+
* // Mutate within Relation.update
|
|
290
|
+
* Relation.update(worksFor, (obj) => {
|
|
291
|
+
* obj.role = 'Senior Engineer';
|
|
288
292
|
* });
|
|
289
293
|
* ```
|
|
290
294
|
*
|
|
291
|
-
* Note: Only accepts relations. Use `Obj.
|
|
295
|
+
* Note: Only accepts relations. Use `Obj.update` for objects.
|
|
292
296
|
*/
|
|
293
|
-
export const
|
|
297
|
+
export const update = <T extends Unknown>(relation: T, callback: internal.ChangeCallback<T>): void => {
|
|
294
298
|
internal.change(relation, callback);
|
|
295
299
|
};
|
|
296
300
|
|
|
@@ -333,7 +337,7 @@ export const getValue = (rel: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
333
337
|
|
|
334
338
|
/**
|
|
335
339
|
* Set a deeply nested property on a relation.
|
|
336
|
-
* Must be called within a `Relation.
|
|
340
|
+
* Must be called within a `Relation.update` callback.
|
|
337
341
|
*
|
|
338
342
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
339
343
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -395,13 +399,13 @@ export const Meta = internal.MetaId;
|
|
|
395
399
|
export type ReadonlyMeta = internal.ReadonlyMeta;
|
|
396
400
|
|
|
397
401
|
/**
|
|
398
|
-
* Mutable meta type returned by `Relation.getMeta` inside a `Relation.
|
|
402
|
+
* Mutable meta type returned by `Relation.getMeta` inside a `Relation.update` callback.
|
|
399
403
|
*/
|
|
400
404
|
export type Meta = internal.Meta;
|
|
401
405
|
|
|
402
406
|
/**
|
|
403
407
|
* Get the metadata for a relation.
|
|
404
|
-
* Returns mutable meta when passed a mutable relation (inside `Relation.
|
|
408
|
+
* Returns mutable meta when passed a mutable relation (inside `Relation.update` callback).
|
|
405
409
|
* Returns read-only meta when passed a regular relation or snapshot.
|
|
406
410
|
*/
|
|
407
411
|
// TODO(wittjosiah): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.
|
|
@@ -419,7 +423,7 @@ export const getKeys = (entity: Unknown | Snapshot, source: string): ForeignKey[
|
|
|
419
423
|
|
|
420
424
|
/**
|
|
421
425
|
* Delete all keys from the relation for the specified source.
|
|
422
|
-
* Must be called within a `Relation.
|
|
426
|
+
* Must be called within a `Relation.update` callback.
|
|
423
427
|
*
|
|
424
428
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
425
429
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -428,7 +432,7 @@ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => in
|
|
|
428
432
|
|
|
429
433
|
/**
|
|
430
434
|
* Add a tag to the relation.
|
|
431
|
-
* Must be called within a `Relation.
|
|
435
|
+
* Must be called within a `Relation.update` callback.
|
|
432
436
|
*
|
|
433
437
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
434
438
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -437,7 +441,7 @@ export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.
|
|
|
437
441
|
|
|
438
442
|
/**
|
|
439
443
|
* Remove a tag from the relation.
|
|
440
|
-
* Must be called within a `Relation.
|
|
444
|
+
* Must be called within a `Relation.update` callback.
|
|
441
445
|
*
|
|
442
446
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
443
447
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -462,7 +466,7 @@ export const getLabel = (entity: Unknown | Snapshot): string | undefined => inte
|
|
|
462
466
|
|
|
463
467
|
/**
|
|
464
468
|
* Set the label of the relation.
|
|
465
|
-
* Must be called within a `Relation.
|
|
469
|
+
* Must be called within a `Relation.update` callback.
|
|
466
470
|
*
|
|
467
471
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
468
472
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -477,7 +481,7 @@ export const getDescription = (entity: Unknown | Snapshot): string | undefined =
|
|
|
477
481
|
|
|
478
482
|
/**
|
|
479
483
|
* Set the description of the relation.
|
|
480
|
-
* Must be called within a `Relation.
|
|
484
|
+
* Must be called within a `Relation.update` callback.
|
|
481
485
|
*
|
|
482
486
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
483
487
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
package/src/Type.ts
CHANGED
|
@@ -12,8 +12,8 @@ import { type DXN } from '@dxos/keys';
|
|
|
12
12
|
import { type ToMutable } from '@dxos/util';
|
|
13
13
|
|
|
14
14
|
import type * as Entity from './Entity';
|
|
15
|
-
import * as typeInternal from './internal/Type';
|
|
16
15
|
import * as internal from './internal';
|
|
16
|
+
import * as typeInternal from './internal/Type';
|
|
17
17
|
import type * as ObjModule from './Obj';
|
|
18
18
|
import type * as RelationModule from './Relation';
|
|
19
19
|
|
package/src/View.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { QueryAST } from '@dxos/echo-protocol';
|
|
|
10
10
|
import { JsonPath } from '@dxos/effect';
|
|
11
11
|
import { PublicKey } from '@dxos/keys';
|
|
12
12
|
|
|
13
|
+
import * as Annotation from './Annotation';
|
|
13
14
|
import * as Filter from './Filter';
|
|
14
15
|
import * as internal from './internal';
|
|
15
16
|
import * as Obj from './Obj';
|
|
@@ -79,6 +80,10 @@ const ViewSchema = Schema.Struct({
|
|
|
79
80
|
version: '0.1.0',
|
|
80
81
|
}),
|
|
81
82
|
internal.SystemTypeAnnotation.set(true),
|
|
83
|
+
Annotation.IconAnnotation.set({
|
|
84
|
+
icon: 'ph--funnel--regular',
|
|
85
|
+
hue: 'green',
|
|
86
|
+
}),
|
|
82
87
|
);
|
|
83
88
|
|
|
84
89
|
export interface View extends Schema.Schema.Type<typeof ViewSchema> {}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import * as Obj from './Obj';
|
|
8
|
+
import { TestSchema } from './testing';
|
|
9
|
+
import type * as Type from './Type';
|
|
10
|
+
|
|
11
|
+
describe('Exemplars', () => {
|
|
12
|
+
test('factory', ({ expect }) => {
|
|
13
|
+
const factory = <S extends Type.AnyObj>(schema: S) => {
|
|
14
|
+
return (props: Obj.MakeProps<S>) => Obj.make(schema, props);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const makePerson = factory(TestSchema.Person);
|
|
18
|
+
const person = makePerson({ name: 'John Doe' });
|
|
19
|
+
expect(person.name).toBe('John Doe');
|
|
20
|
+
});
|
|
21
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -9,13 +9,16 @@ export { DXN } from '@dxos/keys';
|
|
|
9
9
|
export * as Annotation from './Annotation';
|
|
10
10
|
export * as Database from './Database';
|
|
11
11
|
export * as Entity from './Entity';
|
|
12
|
+
// TODO(burdon): Rename to Error (less problematic than Obj/Object).
|
|
12
13
|
export * as Err from './Err';
|
|
13
14
|
export * as Feed from './Feed';
|
|
14
15
|
export * as Filter from './Filter';
|
|
15
16
|
export * as Format from './Format';
|
|
16
17
|
export * as Hypergraph from './Hypergraph';
|
|
18
|
+
export * as Json from './Json';
|
|
17
19
|
export * as JsonSchema from './JsonSchema';
|
|
18
20
|
export * as Key from './Key';
|
|
21
|
+
export * as Migration from './Migration';
|
|
19
22
|
export * as Obj from './Obj';
|
|
20
23
|
export * as Order from './Order';
|
|
21
24
|
export * as Query from './Query';
|
|
@@ -28,3 +31,4 @@ export * as Type from './Type';
|
|
|
28
31
|
export * as Collection from './Collection';
|
|
29
32
|
export * as View from './View';
|
|
30
33
|
export * as Dataset from './Dataset';
|
|
34
|
+
export * as Extension from './Extension';
|
|
@@ -6,7 +6,6 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
import { describe, test } from 'vitest';
|
|
7
7
|
|
|
8
8
|
import { EchoObjectSchema } from '../Entity';
|
|
9
|
-
|
|
10
9
|
import { LabelAnnotation, TypenameSchema, VersionSchema, getLabelWithSchema } from './annotations';
|
|
11
10
|
|
|
12
11
|
// TODO(dmaretskyi): Use one of the testing schemas.
|
|
@@ -32,7 +31,7 @@ describe('annotations', () => {
|
|
|
32
31
|
test('should validate typename', ({ expect }) => {
|
|
33
32
|
// Valid (reverse-DNS format).
|
|
34
33
|
expect(TypenameSchema.make('org.dxos.type.foo')).to.exist;
|
|
35
|
-
expect(TypenameSchema.make('org.dxos.type.
|
|
34
|
+
expect(TypenameSchema.make('org.dxos.type.fooBar')).to.exist;
|
|
36
35
|
expect(TypenameSchema.make('org.dxos.type.foobar')).to.exist;
|
|
37
36
|
|
|
38
37
|
// Invalid.
|
|
@@ -82,6 +81,56 @@ describe('annotations', () => {
|
|
|
82
81
|
expect(getLabelWithSchema(TestObject, obj)).toBeUndefined();
|
|
83
82
|
});
|
|
84
83
|
|
|
84
|
+
test('should skip empty string and fallback to next path', ({ expect }) => {
|
|
85
|
+
const obj: TestObject = {
|
|
86
|
+
name: '',
|
|
87
|
+
fallbackName: 'Fallback Name',
|
|
88
|
+
other: 'Other',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
expect(getLabelWithSchema(TestObject, obj)).toEqual('Fallback Name');
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test('should skip whitespace-only string and fallback to next path', ({ expect }) => {
|
|
95
|
+
const obj: TestObject = {
|
|
96
|
+
name: ' ',
|
|
97
|
+
fallbackName: 'Fallback Name',
|
|
98
|
+
other: 'Other',
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
expect(getLabelWithSchema(TestObject, obj)).toEqual('Fallback Name');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should return undefined if all paths are empty strings', ({ expect }) => {
|
|
105
|
+
const obj: TestObject = {
|
|
106
|
+
name: '',
|
|
107
|
+
fallbackName: '',
|
|
108
|
+
other: 'Other',
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
expect(getLabelWithSchema(TestObject, obj)).toBeUndefined();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should return undefined if all paths are whitespace-only', ({ expect }) => {
|
|
115
|
+
const obj: TestObject = {
|
|
116
|
+
name: ' ',
|
|
117
|
+
fallbackName: '\t\n',
|
|
118
|
+
other: 'Other',
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
expect(getLabelWithSchema(TestObject, obj)).toBeUndefined();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('should preserve original string with leading/trailing whitespace when valid', ({ expect }) => {
|
|
125
|
+
const obj: TestObject = {
|
|
126
|
+
name: ' Valid Name ',
|
|
127
|
+
fallbackName: 'Fallback Name',
|
|
128
|
+
other: 'Other',
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
expect(getLabelWithSchema(TestObject, obj)).toEqual(' Valid Name ');
|
|
132
|
+
});
|
|
133
|
+
|
|
85
134
|
test('should return label from echo object', ({ expect }) => {
|
|
86
135
|
const obj: TestEchoSchema = {
|
|
87
136
|
id: 'test',
|
|
@@ -15,7 +15,6 @@ import { type Primitive } from '@dxos/util';
|
|
|
15
15
|
|
|
16
16
|
import { type Mutable } from '../common/proxy';
|
|
17
17
|
import { type AnyProperties, EntityKind, TypeId, getSchema } from '../common/types';
|
|
18
|
-
|
|
19
18
|
import { type AnnotationHelper, createAnnotationHelper } from './util';
|
|
20
19
|
|
|
21
20
|
/**
|
|
@@ -90,14 +89,15 @@ export const getTypeDXNFromSpecifier = (input: Schema.Schema.All | string): DXN
|
|
|
90
89
|
* Fully qualified globally unique typename.
|
|
91
90
|
* Example: `org.dxos.type.message`
|
|
92
91
|
*/
|
|
93
|
-
// TODO(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
// TODO(wittjosiah): Factor out to DXN spec.
|
|
93
|
+
export const TypenameSchema = Schema.String.pipe(
|
|
94
|
+
Schema.pattern(
|
|
95
|
+
/^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z]([a-zA-Z0-9]{0,62})?)$/,
|
|
96
|
+
),
|
|
97
|
+
).annotations({
|
|
98
|
+
description: 'Fully qualified globally unique typename in reverse-DNS form.',
|
|
99
|
+
example: 'org.dxos.type.message',
|
|
100
|
+
});
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
103
|
* Semantic version format: `major.minor.patch`
|
|
@@ -338,6 +338,7 @@ export const LabelAnnotation = createAnnotationHelper<string[]>(LabelAnnotationI
|
|
|
338
338
|
/**
|
|
339
339
|
* Returns the label for a given object based on {@link LabelAnnotationId}.
|
|
340
340
|
* Lower-level version that requires explicit schema parameter.
|
|
341
|
+
* Skips empty strings and whitespace-only strings, continuing to the next field.
|
|
341
342
|
*/
|
|
342
343
|
// TODO(burdon): Convert to JsonPath?
|
|
343
344
|
export const getLabelWithSchema = <S extends Schema.Schema.Any>(
|
|
@@ -353,7 +354,13 @@ export const getLabelWithSchema = <S extends Schema.Schema.Any>(
|
|
|
353
354
|
);
|
|
354
355
|
const value = getField(object, accessor as JsonPath);
|
|
355
356
|
switch (typeof value) {
|
|
356
|
-
case 'string':
|
|
357
|
+
case 'string': {
|
|
358
|
+
const trimmed = value.trim();
|
|
359
|
+
if (trimmed.length > 0) {
|
|
360
|
+
return value;
|
|
361
|
+
}
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
357
364
|
case 'number':
|
|
358
365
|
case 'boolean':
|
|
359
366
|
case 'bigint':
|
|
@@ -436,7 +443,6 @@ export const setDescriptionWithSchema = <S extends Schema.Schema.Any>(
|
|
|
436
443
|
* Identifies if a property should be included in a form or not.
|
|
437
444
|
* By default, all properties are included in forms, so this is opt-out.
|
|
438
445
|
*/
|
|
439
|
-
// TODO(burdon): UI concern.
|
|
440
446
|
export const FormInputAnnotationId = Symbol.for('@dxos/schema/annotation/FormInput');
|
|
441
447
|
export const FormInputAnnotation = createAnnotationHelper<boolean>(FormInputAnnotationId);
|
|
442
448
|
|
|
@@ -475,7 +481,7 @@ export const makeUserAnnotation = <T>(props: MakeAnnoationsProps<T>): Annotation
|
|
|
475
481
|
|
|
476
482
|
const getFromAst = (ast: SchemaAST.AST) =>
|
|
477
483
|
SchemaAST.getAnnotation<PropertyMetaAnnotation>(PropertyMetaAnnotationId)(ast).pipe(
|
|
478
|
-
Option.
|
|
484
|
+
Option.flatMap((meta) => Option.fromNullable(meta[props.id])),
|
|
479
485
|
Option.map(Schema.decodeUnknownSync(props.schema)),
|
|
480
486
|
);
|
|
481
487
|
|
|
@@ -526,6 +532,19 @@ export const IconAnnotation = makeUserAnnotation<IconAnnotation>({
|
|
|
526
532
|
schema: IconAnnotationSchema,
|
|
527
533
|
});
|
|
528
534
|
|
|
535
|
+
/**
|
|
536
|
+
* Indicates that this entity's icon should be resolved from a property whose value is a `Ref`
|
|
537
|
+
* to another entity. Consumers (e.g. graph node builders) resolve the ref target and use that
|
|
538
|
+
* target's schema `IconAnnotation` in place of the static one declared on this schema.
|
|
539
|
+
*
|
|
540
|
+
* Useful for wrapper schemas that delegate their visual identity to a referenced sub-entity
|
|
541
|
+
* (e.g. a generic `Game` whose icon should come from its `variant` ref's typed state).
|
|
542
|
+
*/
|
|
543
|
+
export const IconFromRefAnnotation = makeUserAnnotation<string>({
|
|
544
|
+
id: 'org.dxos.annotation.icon.from-ref',
|
|
545
|
+
schema: Schema.String,
|
|
546
|
+
});
|
|
547
|
+
|
|
529
548
|
/**
|
|
530
549
|
* Get the label of an entity.
|
|
531
550
|
* Accepts both reactive entities and snapshots.
|
|
@@ -539,7 +558,7 @@ export const getLabel = (entity: AnyProperties): string | undefined => {
|
|
|
539
558
|
|
|
540
559
|
/**
|
|
541
560
|
* Set the label of an entity.
|
|
542
|
-
* Must be called within an Obj.
|
|
561
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
543
562
|
*/
|
|
544
563
|
export const setLabel = (entity: Mutable<AnyProperties>, label: string) => {
|
|
545
564
|
const schema = getSchema(entity);
|
|
@@ -561,7 +580,7 @@ export const getDescription = (entity: AnyProperties): string | undefined => {
|
|
|
561
580
|
|
|
562
581
|
/**
|
|
563
582
|
* Set the description of an entity.
|
|
564
|
-
* Must be called within an Obj.
|
|
583
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
565
584
|
*/
|
|
566
585
|
export const setDescription = (entity: Mutable<AnyProperties>, description: string) => {
|
|
567
586
|
const schema = getSchema(entity);
|
|
@@ -9,7 +9,6 @@ import { invariant } from '@dxos/invariant';
|
|
|
9
9
|
|
|
10
10
|
import { type TypeAnnotation, TypeAnnotationId, type TypeMeta, makeTypeJsonSchemaAnnotation } from '../Annotation';
|
|
11
11
|
import { EntityKind } from '../common/types';
|
|
12
|
-
|
|
13
12
|
import { type EchoTypeSchema, makeEchoTypeSchema } from './entity';
|
|
14
13
|
|
|
15
14
|
/**
|
|
@@ -6,9 +6,9 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
|
|
7
7
|
import { JsonPath, type JsonProp } from '@dxos/effect';
|
|
8
8
|
|
|
9
|
-
import { FormatAnnotation, TypeFormat } from '../Format';
|
|
10
9
|
import { type Mutable } from '../common/proxy';
|
|
11
10
|
import { EntityKindSchema } from '../common/types';
|
|
11
|
+
import { FormatAnnotation, TypeFormat } from '../Format';
|
|
12
12
|
|
|
13
13
|
//
|
|
14
14
|
// JSON Schema
|
|
@@ -21,13 +21,12 @@ import {
|
|
|
21
21
|
getTypeAnnotation,
|
|
22
22
|
getTypeIdentifierAnnotation,
|
|
23
23
|
} from '../Annotation';
|
|
24
|
+
import { EntityKind } from '../common/types';
|
|
24
25
|
import { EchoObjectSchema } from '../Entity';
|
|
25
26
|
import { Email, FormatAnnotation, TypeFormat } from '../Format';
|
|
26
27
|
import { JsonSchemaType, getNormalizedEchoAnnotations, getSchemaProperty, setSchemaProperty } from '../JsonSchema';
|
|
27
28
|
import { Ref, createSchemaReference, getReferenceAst, getSchemaReference } from '../Ref';
|
|
28
29
|
import { PersistentSchema } from '../Type';
|
|
29
|
-
import { EntityKind } from '../common/types';
|
|
30
|
-
|
|
31
30
|
import { toEffectSchema, toJsonSchema } from './json-schema';
|
|
32
31
|
|
|
33
32
|
const EXAMPLE_NAMESPACE = '@example';
|
|
@@ -23,9 +23,8 @@ import {
|
|
|
23
23
|
TypeIdentifierAnnotationId,
|
|
24
24
|
makeTypeJsonSchemaAnnotation,
|
|
25
25
|
} from '../Annotation';
|
|
26
|
-
import { type JsonSchemaReferenceInfo, createEchoReferenceSchema } from '../Ref';
|
|
27
26
|
import { ANY_OBJECT_TYPENAME, ANY_OBJECT_VERSION, EntityKind, EntityKindSchema } from '../common/types';
|
|
28
|
-
|
|
27
|
+
import { type JsonSchemaReferenceInfo, createEchoReferenceSchema } from '../Ref';
|
|
29
28
|
import { CustomAnnotations, DecodedAnnotations, EchoAnnotations } from './annotations';
|
|
30
29
|
import {
|
|
31
30
|
ECHO_ANNOTATIONS_NS_DEPRECATED_KEY,
|
|
@@ -7,8 +7,8 @@ import { deepMapValues } from '@dxos/util';
|
|
|
7
7
|
|
|
8
8
|
import type * as Obj from '../../Obj';
|
|
9
9
|
import { makeObject } from '../common/proxy';
|
|
10
|
-
import { Ref } from '../Ref';
|
|
11
10
|
import { getMeta, getSchema } from '../common/types';
|
|
11
|
+
import { Ref } from '../Ref';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Clones an object or relation.
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { inspect } from 'util';
|
|
6
|
-
|
|
7
5
|
import * as Schema from 'effect/Schema';
|
|
6
|
+
import { inspect } from 'util';
|
|
8
7
|
import { describe, expect, test } from 'vitest';
|
|
9
8
|
|
|
10
9
|
import { DXN } from '@dxos/keys';
|
|
@@ -12,9 +11,8 @@ import { DXN } from '@dxos/keys';
|
|
|
12
11
|
import { Relation } from '../../index';
|
|
13
12
|
import { TestSchema } from '../../testing';
|
|
14
13
|
import { getSchemaDXN, getTypeDXN, isInstanceOf } from '../Annotation';
|
|
15
|
-
import { ATTR_RELATION_SOURCE, ATTR_RELATION_TARGET } from '../Entity';
|
|
16
14
|
import { ATTR_META, ATTR_TYPE, getSchema } from '../common/types';
|
|
17
|
-
|
|
15
|
+
import { ATTR_RELATION_SOURCE, ATTR_RELATION_TARGET } from '../Entity';
|
|
18
16
|
import { createObject } from './create-object';
|
|
19
17
|
import { objectToJSON } from './json-serializer';
|
|
20
18
|
|
|
@@ -9,6 +9,8 @@ import { assertArgument, failedInvariant } from '@dxos/invariant';
|
|
|
9
9
|
import { ObjectId } from '@dxos/keys';
|
|
10
10
|
|
|
11
11
|
import { getSchemaDXN, getTypeAnnotation, setTypename } from '../Annotation';
|
|
12
|
+
import { defineHiddenProperty } from '../common/proxy';
|
|
13
|
+
import { EntityKind, KindId, MetaId, setSchema } from '../common/types';
|
|
12
14
|
import {
|
|
13
15
|
RelationSourceDXNId,
|
|
14
16
|
RelationSourceId,
|
|
@@ -17,9 +19,6 @@ import {
|
|
|
17
19
|
assertObjectModel,
|
|
18
20
|
getObjectDXN,
|
|
19
21
|
} from '../Entity';
|
|
20
|
-
import { defineHiddenProperty } from '../common/proxy';
|
|
21
|
-
import { EntityKind, KindId, MetaId, setSchema } from '../common/types';
|
|
22
|
-
|
|
23
22
|
import { attachedTypedObjectInspector } from './inspect';
|
|
24
23
|
import { attachTypedJsonSerializer } from './json-serializer';
|
|
25
24
|
|
|
@@ -10,19 +10,18 @@ import * as Obj from '../../Obj';
|
|
|
10
10
|
import { TestSchema } from '../../testing';
|
|
11
11
|
import { getSchemaDXN, getSchemaTypename, getTypeDXN, getTypename } from '../Annotation';
|
|
12
12
|
import { getMetaChecked } from '../common/api';
|
|
13
|
-
import { RelationSourceId, RelationTargetId, getObjectDXN } from '../Entity';
|
|
14
13
|
import { makeObject } from '../common/proxy';
|
|
15
|
-
import { Ref, StaticRefResolver } from '../Ref';
|
|
16
14
|
import { ATTR_TYPE, EntityKind, KindId, MetaId, TypeId, getSchema } from '../common/types';
|
|
17
|
-
|
|
15
|
+
import { RelationSourceId, RelationTargetId, getObjectDXN } from '../Entity';
|
|
16
|
+
import { Ref, StaticRefResolver } from '../Ref';
|
|
18
17
|
import { createObject } from './create-object';
|
|
19
18
|
import { objectFromJSON, objectToJSON } from './json-serializer';
|
|
20
19
|
|
|
21
20
|
describe('Object JSON serializer', () => {
|
|
22
21
|
test('should serialize and deserialize object', async () => {
|
|
23
22
|
const contact = makeObject(TestSchema.Person, { name: 'Alice' });
|
|
24
|
-
Obj.
|
|
25
|
-
getMetaChecked(
|
|
23
|
+
Obj.update(contact, (contact) => {
|
|
24
|
+
getMetaChecked(contact).keys.push({ id: '12345', source: 'example.com' });
|
|
26
25
|
});
|
|
27
26
|
|
|
28
27
|
const task = createObject(TestSchema.Task, {
|
|
@@ -13,6 +13,19 @@ import { assumeType, deepMapValues, visitValues } from '@dxos/util';
|
|
|
13
13
|
import type * as Database from '../../Database';
|
|
14
14
|
import type * as Obj from '../../Obj';
|
|
15
15
|
import { getTypeDXN, setTypename } from '../Annotation';
|
|
16
|
+
import { attachTypedJsonSerializer, defineHiddenProperty, typedJsonSerializer } from '../common/proxy';
|
|
17
|
+
import {
|
|
18
|
+
ATTR_META,
|
|
19
|
+
ATTR_PARENT,
|
|
20
|
+
ATTR_TYPE,
|
|
21
|
+
type AnyEntity,
|
|
22
|
+
EntityKind,
|
|
23
|
+
KindId,
|
|
24
|
+
MetaId,
|
|
25
|
+
ObjectMetaSchema,
|
|
26
|
+
ParentId,
|
|
27
|
+
setSchema,
|
|
28
|
+
} from '../common/types';
|
|
16
29
|
import {
|
|
17
30
|
ATTR_DELETED,
|
|
18
31
|
ATTR_RELATION_SOURCE,
|
|
@@ -27,20 +40,7 @@ import {
|
|
|
27
40
|
SelfDXNId,
|
|
28
41
|
assertObjectModel,
|
|
29
42
|
} from '../Entity';
|
|
30
|
-
import { attachTypedJsonSerializer, defineHiddenProperty, typedJsonSerializer } from '../common/proxy';
|
|
31
43
|
import { Ref, type RefResolver, refFromEncodedReference, setRefResolver } from '../Ref';
|
|
32
|
-
import {
|
|
33
|
-
ATTR_META,
|
|
34
|
-
ATTR_PARENT,
|
|
35
|
-
ATTR_TYPE,
|
|
36
|
-
type AnyEntity,
|
|
37
|
-
EntityKind,
|
|
38
|
-
KindId,
|
|
39
|
-
MetaId,
|
|
40
|
-
ObjectMetaSchema,
|
|
41
|
-
ParentId,
|
|
42
|
-
setSchema,
|
|
43
|
-
} from '../common/types';
|
|
44
44
|
|
|
45
45
|
// Re-export for backward compatibility.
|
|
46
46
|
export { attachTypedJsonSerializer };
|
|
@@ -80,7 +80,12 @@ export const objectToJSON = <T extends AnyEntity>(obj: T): SerializedObject<T> =
|
|
|
80
80
|
*/
|
|
81
81
|
export const objectFromJSON = async (
|
|
82
82
|
jsonData: unknown,
|
|
83
|
-
{
|
|
83
|
+
{
|
|
84
|
+
refResolver,
|
|
85
|
+
dxn,
|
|
86
|
+
database,
|
|
87
|
+
parent,
|
|
88
|
+
}: { refResolver?: RefResolver; dxn?: DXN; database?: Database.Database; parent?: Obj.Unknown } = {},
|
|
84
89
|
): Promise<AnyEntity> => {
|
|
85
90
|
assumeType<ObjectJSON>(jsonData);
|
|
86
91
|
assertArgument(typeof jsonData === 'object' && jsonData !== null, 'jsonData', 'expect object');
|
|
@@ -138,7 +143,9 @@ export const objectFromJSON = async (
|
|
|
138
143
|
|
|
139
144
|
if (jsonData[ATTR_PARENT]) {
|
|
140
145
|
const parentDxn = DXN.parse(jsonData[ATTR_PARENT]);
|
|
141
|
-
const
|
|
146
|
+
const resolvedParent = (await refResolver?.resolve(parentDxn)) as Obj.Unknown | undefined;
|
|
147
|
+
defineHiddenProperty(obj, ParentId, resolvedParent);
|
|
148
|
+
} else if (parent) {
|
|
142
149
|
defineHiddenProperty(obj, ParentId, parent);
|
|
143
150
|
}
|
|
144
151
|
|