@dxos/echo 0.8.4-staging.ac66bdf99f → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +102 -5
- package/README.md +7 -7
- package/dist/lib/neutral/Annotation.mjs +37 -6
- package/dist/lib/neutral/Database.mjs +6 -17
- package/dist/lib/neutral/Entity.mjs +31 -20
- package/dist/lib/neutral/Err.mjs +3 -3
- package/dist/lib/neutral/Feed.mjs +23 -19
- package/dist/lib/neutral/Filter.mjs +13 -15
- package/dist/lib/neutral/Format.mjs +23 -3
- package/dist/lib/neutral/JsonSchema.mjs +7 -8
- package/dist/lib/neutral/Key.mjs +9 -5
- package/dist/lib/neutral/Migration.mjs +11 -10
- package/dist/lib/neutral/Obj.mjs +29 -20
- package/dist/lib/neutral/Order.mjs +7 -3
- package/dist/lib/neutral/Query.mjs +17 -17
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +10 -9
- package/dist/lib/neutral/Registry.mjs +14 -0
- package/dist/lib/neutral/Relation.mjs +28 -25
- package/dist/lib/neutral/Scope.mjs +12 -0
- package/dist/lib/neutral/Tag.mjs +17 -14
- package/dist/lib/neutral/Type.mjs +54 -26
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-35INCYOE.mjs} +1 -1
- package/dist/lib/neutral/chunk-35INCYOE.mjs.map +7 -0
- package/dist/lib/neutral/chunk-3PBP4V4O.mjs +101 -0
- package/dist/lib/neutral/chunk-3PBP4V4O.mjs.map +7 -0
- package/dist/lib/neutral/chunk-4ZUHOTCG.mjs +184 -0
- package/dist/lib/neutral/chunk-4ZUHOTCG.mjs.map +7 -0
- package/dist/lib/neutral/chunk-5SMDBFVB.mjs +108 -0
- package/dist/lib/neutral/chunk-5SMDBFVB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OS35K56T.mjs → chunk-5SUJPHAE.mjs} +3 -3
- package/dist/lib/neutral/{chunk-OS35K56T.mjs.map → chunk-5SUJPHAE.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-GZQTCRJB.mjs → chunk-6M2Z6WBH.mjs} +22 -2
- package/dist/lib/neutral/chunk-6M2Z6WBH.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-V36VO5SS.mjs → chunk-6YDI3J37.mjs} +32 -40
- package/dist/lib/neutral/chunk-6YDI3J37.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-MOR5ERFM.mjs → chunk-7FPIAJIV.mjs} +701 -1256
- package/dist/lib/neutral/chunk-7FPIAJIV.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7LOUAPYZ.mjs} +9 -5
- package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-JUXPFOEI.mjs → chunk-7PI7C4EF.mjs} +48 -88
- package/dist/lib/neutral/chunk-7PI7C4EF.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-BBFJWWAV.mjs} +6 -6
- package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-EVK6XBXO.mjs} +16 -2
- package/dist/lib/neutral/chunk-EVK6XBXO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-7RO7CPBZ.mjs → chunk-IGK6FN65.mjs} +2 -2
- package/dist/lib/neutral/{chunk-HBUZJNZO.mjs → chunk-LWXVKPPW.mjs} +94 -99
- package/dist/lib/neutral/chunk-LWXVKPPW.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-BVOFLCVF.mjs → chunk-MZ7K3MLL.mjs} +9 -6
- package/dist/lib/neutral/chunk-MZ7K3MLL.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TBKX6JQO.mjs → chunk-O6BH7EPN.mjs} +30 -3
- package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-EAMSSLZC.mjs → chunk-QQIYS74I.mjs} +83 -46
- package/dist/lib/neutral/chunk-QQIYS74I.mjs.map +7 -0
- package/dist/lib/neutral/chunk-R5W6DXR4.mjs +678 -0
- package/dist/lib/neutral/chunk-R5W6DXR4.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WAK4DMFV.mjs → chunk-RIVWNMSF.mjs} +12 -7
- package/dist/lib/neutral/chunk-RIVWNMSF.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-T6W2LEZU.mjs → chunk-SBVFRTST.mjs} +73 -38
- package/dist/lib/neutral/chunk-SBVFRTST.mjs.map +7 -0
- package/dist/lib/neutral/chunk-T6E37YIP.mjs +251 -0
- package/dist/lib/neutral/chunk-T6E37YIP.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-DQYLD2RB.mjs → chunk-TFEWTY5A.mjs} +155 -129
- package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-B4BASU6W.mjs → chunk-TYGKCRMK.mjs} +85 -76
- package/dist/lib/neutral/chunk-TYGKCRMK.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-4OIBYSXE.mjs → chunk-UUP46KUQ.mjs} +78 -32
- package/dist/lib/neutral/chunk-UUP46KUQ.mjs.map +7 -0
- package/dist/lib/neutral/chunk-WISOH2XH.mjs +36 -0
- package/dist/lib/neutral/chunk-WISOH2XH.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-G3IQMKF7.mjs → chunk-WTQJHC75.mjs} +111 -112
- package/dist/lib/neutral/chunk-WTQJHC75.mjs.map +7 -0
- package/dist/lib/neutral/chunk-WU3GIANS.mjs +31 -0
- package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TU3GW67D.mjs → chunk-ZGNNFYHS.mjs} +40 -40
- package/dist/lib/neutral/chunk-ZGNNFYHS.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +47 -41
- package/dist/lib/neutral/internal/index.mjs +137 -72
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +261 -178
- package/dist/lib/neutral/testing/index.mjs.map +4 -4
- package/dist/types/src/Annotation.d.ts +108 -4
- package/dist/types/src/Annotation.d.ts.map +1 -1
- package/dist/types/src/Annotation.test.d.ts +2 -0
- package/dist/types/src/Annotation.test.d.ts.map +1 -0
- package/dist/types/src/Collection.d.ts +2 -3
- package/dist/types/src/Collection.d.ts.map +1 -1
- package/dist/types/src/Database.d.ts +56 -49
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +16 -6
- package/dist/types/src/Dataset.d.ts.map +1 -1
- package/dist/types/src/Entity.d.ts +101 -28
- package/dist/types/src/Entity.d.ts.map +1 -1
- package/dist/types/src/Err.d.ts +27 -27
- package/dist/types/src/Err.d.ts.map +1 -1
- package/dist/types/src/Feed.d.ts +66 -19
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts +38 -12
- package/dist/types/src/Filter.d.ts.map +1 -1
- package/dist/types/src/Format.d.ts +0 -2
- package/dist/types/src/Format.d.ts.map +1 -1
- package/dist/types/src/Hypergraph.d.ts +14 -9
- package/dist/types/src/Hypergraph.d.ts.map +1 -1
- 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 +2 -2
- package/dist/types/src/JsonSchema.d.ts.map +1 -1
- package/dist/types/src/Key.d.ts +1 -1
- package/dist/types/src/Key.d.ts.map +1 -1
- package/dist/types/src/Migration.d.ts +26 -11
- package/dist/types/src/Migration.d.ts.map +1 -1
- package/dist/types/src/Obj.d.ts +104 -61
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Order.d.ts +10 -0
- package/dist/types/src/Order.d.ts.map +1 -1
- package/dist/types/src/Query.d.ts +34 -12
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/QueryResult.d.ts +21 -0
- package/dist/types/src/QueryResult.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +15 -7
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Registry.d.ts +131 -0
- package/dist/types/src/Registry.d.ts.map +1 -0
- package/dist/types/src/Relation.d.ts +73 -41
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Scope.d.ts +35 -0
- package/dist/types/src/Scope.d.ts.map +1 -0
- package/dist/types/src/Tag.d.ts +21 -5
- package/dist/types/src/Tag.d.ts.map +1 -1
- package/dist/types/src/Type.d.ts +362 -95
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +9 -12
- 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 +4 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/annotations.d.ts +79 -38
- package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/dictionary.d.ts +24 -0
- package/dist/types/src/internal/Annotation/dictionary.d.ts.map +1 -0
- package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +14 -0
- package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -0
- package/dist/types/src/internal/Annotation/index.d.ts +4 -2
- package/dist/types/src/internal/Annotation/index.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 +14 -5
- package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/api.d.ts +17 -3
- package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/entity.d.ts +72 -8
- package/dist/types/src/internal/Entity/entity.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/guard.d.ts +10 -0
- package/dist/types/src/internal/Entity/guard.d.ts.map +1 -0
- package/dist/types/src/internal/Entity/index.d.ts +2 -0
- package/dist/types/src/internal/Entity/index.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/model.d.ts +21 -17
- package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/object.d.ts +3 -3
- package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/relation.d.ts +30 -7
- package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/type-kind.d.ts +24 -0
- package/dist/types/src/internal/Entity/type-kind.d.ts.map +1 -0
- package/dist/types/src/internal/Entity/type-uri.d.ts +24 -0
- package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -0
- 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 +3 -2
- package/dist/types/src/internal/Format/format.d.ts.map +1 -1
- package/dist/types/src/internal/Format/index.d.ts +2 -2
- package/dist/types/src/internal/Format/index.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 +3 -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 +34 -34
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts +3 -2
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/atoms.d.ts +38 -0
- package/dist/types/src/internal/Obj/atoms.d.ts.map +1 -0
- 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 +12 -12
- 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/index.d.ts +1 -1
- package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/json-serializer.d.ts +8 -8
- 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/Obj/typed-object.d.ts +1 -1
- package/dist/types/src/internal/Query/index.d.ts +2 -0
- package/dist/types/src/internal/Query/index.d.ts.map +1 -0
- package/dist/types/src/internal/{Query.d.ts → Query/pretty.d.ts} +1 -1
- package/dist/types/src/internal/Query/pretty.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/atoms.d.ts +10 -0
- package/dist/types/src/internal/Ref/atoms.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
- package/dist/types/src/internal/Ref/ref.d.ts +50 -19
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/utils.d.ts +8 -0
- package/dist/types/src/internal/Ref/utils.d.ts.map +1 -0
- package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
- package/dist/types/src/internal/Type/index.d.ts +1 -2
- package/dist/types/src/internal/Type/index.d.ts.map +1 -1
- package/dist/types/src/internal/Type/manipulation.d.ts +0 -1
- package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
- package/dist/types/src/internal/Type/type-schema.d.ts +52 -0
- package/dist/types/src/internal/Type/type-schema.d.ts.map +1 -0
- package/dist/types/src/internal/common/api/meta.d.ts +14 -11
- 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 +11 -5
- 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 +18 -2
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/base.d.ts +4 -4
- package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/entity.d.ts +62 -5
- package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/index.d.ts +1 -1
- package/dist/types/src/internal/common/types/index.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/meta.d.ts +33 -12
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/model-symbols.d.ts +15 -4
- package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/typename.d.ts +7 -0
- package/dist/types/src/internal/common/types/typename.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/version.d.ts +1 -1
- package/dist/types/src/internal/common/types/well-known-types.d.ts +11 -0
- package/dist/types/src/internal/common/types/well-known-types.d.ts.map +1 -0
- package/dist/types/src/internal/index.d.ts +2 -2
- package/dist/types/src/internal/index.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -0
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/registry.d.ts +9 -0
- package/dist/types/src/testing/registry.d.ts.map +1 -0
- 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 +83 -89
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/dist/types/src/testing/util.d.ts +5 -3
- package/dist/types/src/testing/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -24
- package/src/Annotation.test.ts +439 -0
- package/src/Annotation.ts +158 -4
- package/src/Collection.ts +5 -9
- package/src/Database.ts +93 -100
- package/src/Dataset.ts +10 -2
- package/src/Entity.test.ts +116 -6
- package/src/Entity.ts +134 -32
- package/src/Err.ts +4 -4
- package/src/Feed.ts +92 -44
- package/src/Filter.ts +70 -40
- package/src/Format.ts +0 -4
- package/src/Hypergraph.ts +14 -9
- package/src/Json.test.ts +175 -0
- package/src/Json.ts +103 -0
- package/src/Key.ts +1 -1
- package/src/Migration.ts +39 -19
- package/src/Obj.test.ts +122 -20
- package/src/Obj.ts +168 -91
- package/src/Order.ts +22 -0
- package/src/Query.test.ts +183 -154
- package/src/Query.ts +172 -85
- package/src/QueryResult.ts +26 -0
- package/src/Ref.ts +22 -4
- package/src/Registry.ts +155 -0
- package/src/Relation.test.ts +10 -10
- package/src/Relation.ts +116 -69
- package/src/Scope.ts +50 -0
- package/src/Tag.md +88 -0
- package/src/Tag.ts +49 -6
- package/src/Type.test.ts +223 -18
- package/src/Type.ts +609 -131
- package/src/View.ts +14 -23
- package/src/exemplars.test.ts +21 -0
- package/src/index.ts +4 -4
- package/src/internal/Annotation/annotations.test.ts +31 -11
- package/src/internal/Annotation/annotations.ts +143 -111
- package/src/internal/Annotation/dictionary.ts +47 -0
- package/src/internal/Annotation/entity-dictionary.ts +74 -0
- package/src/internal/Annotation/index.ts +4 -2
- package/src/internal/Annotation/util.ts +17 -8
- package/src/internal/Entity/api.ts +54 -7
- package/src/internal/Entity/entity.ts +196 -47
- package/src/internal/Entity/guard.ts +26 -0
- package/src/internal/Entity/index.ts +2 -0
- package/src/internal/Entity/model.ts +38 -28
- package/src/internal/Entity/object.ts +21 -5
- package/src/internal/Entity/relation.ts +68 -34
- package/src/internal/Entity/type-kind.ts +75 -0
- package/src/internal/Entity/type-uri.ts +92 -0
- package/src/internal/Entity/util.ts +9 -9
- package/src/internal/Format/date.ts +0 -4
- package/src/internal/Format/format.test.ts +21 -0
- package/src/internal/Format/index.ts +2 -3
- package/src/internal/Format/object.ts +21 -4
- package/src/internal/Format/types.ts +1 -1
- package/src/internal/JsonSchema/annotations.ts +1 -1
- package/src/internal/JsonSchema/json-schema-type.ts +4 -4
- package/src/internal/JsonSchema/json-schema.test.ts +71 -145
- package/src/internal/JsonSchema/json-schema.ts +49 -35
- package/src/internal/Obj/atoms.ts +244 -0
- package/src/internal/Obj/clone.ts +9 -4
- package/src/internal/Obj/create-object.test.ts +12 -10
- package/src/internal/Obj/create-object.ts +68 -22
- package/src/internal/Obj/index.ts +1 -1
- package/src/internal/Obj/inspect.ts +5 -3
- package/src/internal/Obj/json-serializer.test.ts +101 -22
- package/src/internal/Obj/json-serializer.ts +89 -33
- package/src/internal/Obj/set-value.test.ts +22 -45
- package/src/internal/Obj/set-value.ts +12 -19
- package/src/internal/Obj/snapshot.ts +13 -4
- package/src/internal/Obj/typed-object.test.ts +9 -11
- package/src/internal/Obj/typed-object.ts +1 -1
- package/src/internal/Query/index.ts +5 -0
- package/src/internal/{Query.ts → Query/pretty.ts} +40 -12
- package/src/internal/Ref/atoms.ts +20 -0
- package/src/internal/Ref/ref-array.ts +3 -3
- package/src/internal/Ref/ref.test.ts +18 -27
- package/src/internal/Ref/ref.ts +137 -59
- package/src/internal/Ref/utils.ts +45 -0
- package/src/internal/Type/compose.test.ts +3 -1
- package/src/internal/Type/index.ts +1 -2
- package/src/internal/Type/manipulation.ts +0 -25
- package/src/internal/Type/type-schema.ts +60 -0
- package/src/internal/common/README.md +2 -2
- package/src/internal/common/api/meta.ts +19 -17
- package/src/internal/common/proxy/change-context.ts +1 -1
- package/src/internal/common/proxy/change.test.ts +91 -83
- package/src/internal/common/proxy/errors.ts +2 -2
- package/src/internal/common/proxy/handler.test.ts +1 -1
- package/src/internal/common/proxy/json-serializer.ts +27 -16
- package/src/internal/common/proxy/make-object.ts +44 -20
- package/src/internal/common/proxy/ownership.ts +2 -2
- 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 -2
- package/src/internal/common/proxy/schema.test.ts +48 -86
- package/src/internal/common/proxy/typed-handler.test.ts +12 -11
- package/src/internal/common/proxy/typed-handler.ts +78 -16
- package/src/internal/common/proxy/typed-object.test.ts +16 -28
- package/src/internal/common/types/base.ts +4 -4
- package/src/internal/common/types/entity.ts +80 -1
- package/src/internal/common/types/index.ts +6 -1
- package/src/internal/common/types/meta.ts +62 -20
- package/src/internal/common/types/model-symbols.ts +24 -4
- package/src/internal/common/types/typename.ts +39 -3
- package/src/internal/common/types/well-known-types.ts +15 -0
- package/src/internal/index.ts +6 -4
- package/src/testing/api.test.ts +15 -9
- package/src/testing/index.ts +1 -0
- package/src/testing/registry.ts +44 -0
- package/src/testing/test-data.ts +159 -99
- package/src/testing/test-schema.ts +22 -58
- package/src/testing/util.ts +14 -11
- package/dist/lib/neutral/Extension.mjs +0 -18
- package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
- package/dist/lib/neutral/chunk-2KHZ36F5.mjs +0 -361
- package/dist/lib/neutral/chunk-2KHZ36F5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-4OIBYSXE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-4P3IXBLT.mjs +0 -45
- package/dist/lib/neutral/chunk-4P3IXBLT.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
- package/dist/lib/neutral/chunk-B4BASU6W.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BNCCGLJN.mjs +0 -7
- package/dist/lib/neutral/chunk-BNCCGLJN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BVOFLCVF.mjs.map +0 -7
- package/dist/lib/neutral/chunk-DQYLD2RB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-EAMSSLZC.mjs.map +0 -7
- package/dist/lib/neutral/chunk-G3IQMKF7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GZQTCRJB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-HBUZJNZO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-JUXPFOEI.mjs.map +0 -7
- package/dist/lib/neutral/chunk-MOR5ERFM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OMUPQMLR.mjs.map +0 -7
- package/dist/lib/neutral/chunk-PHU22NLC.mjs +0 -136
- package/dist/lib/neutral/chunk-PHU22NLC.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ROG4RXXL.mjs +0 -97
- package/dist/lib/neutral/chunk-ROG4RXXL.mjs.map +0 -7
- package/dist/lib/neutral/chunk-T6W2LEZU.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TBKX6JQO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TU3GW67D.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UBEZSGXY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UI6MWK5W.mjs.map +0 -7
- package/dist/lib/neutral/chunk-V36VO5SS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WAK4DMFV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-YAHXAYOW.mjs +0 -56
- package/dist/lib/neutral/chunk-YAHXAYOW.mjs.map +0 -7
- package/dist/lib/neutral/chunk-YS6Q3XAD.mjs +0 -50
- package/dist/lib/neutral/chunk-YS6Q3XAD.mjs.map +0 -7
- package/dist/types/src/Extension.d.ts +0 -80
- package/dist/types/src/Extension.d.ts.map +0 -1
- package/dist/types/src/Extension.test.d.ts +0 -2
- package/dist/types/src/Extension.test.d.ts.map +0 -1
- package/dist/types/src/SchemaRegistry.d.ts +0 -84
- package/dist/types/src/SchemaRegistry.d.ts.map +0 -1
- package/dist/types/src/internal/Obj/ids.d.ts +0 -6
- package/dist/types/src/internal/Obj/ids.d.ts.map +0 -1
- package/dist/types/src/internal/Query.d.ts.map +0 -1
- package/dist/types/src/internal/Type/echo-schema.d.ts +0 -181
- package/dist/types/src/internal/Type/echo-schema.d.ts.map +0 -1
- package/dist/types/src/internal/Type/persistent-schema.d.ts +0 -20
- package/dist/types/src/internal/Type/persistent-schema.d.ts.map +0 -1
- package/src/Extension.test.ts +0 -235
- package/src/Extension.ts +0 -122
- package/src/SchemaRegistry.ts +0 -106
- package/src/internal/Obj/ids.ts +0 -12
- package/src/internal/Type/echo-schema.ts +0 -423
- package/src/internal/Type/persistent-schema.ts +0 -33
- /package/dist/lib/neutral/{Extension.mjs.map → Registry.mjs.map} +0 -0
- /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Scope.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-7RO7CPBZ.mjs.map → chunk-IGK6FN65.mjs.map} +0 -0
package/src/internal/Ref/ref.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import type * as Atom from '@effect-atom/atom/Atom';
|
|
5
6
|
import * as Effect from 'effect/Effect';
|
|
6
7
|
import * as Equal from 'effect/Equal';
|
|
7
8
|
import * as Hash from 'effect/Hash';
|
|
@@ -16,12 +17,19 @@ import { Event } from '@dxos/async';
|
|
|
16
17
|
import { type CustomInspectFunction, inspectCustom } from '@dxos/debug';
|
|
17
18
|
import { EncodedReference } from '@dxos/echo-protocol';
|
|
18
19
|
import { assertArgument, invariant } from '@dxos/invariant';
|
|
19
|
-
import { DXN,
|
|
20
|
+
import { DXN, EID, EntityId, type URI } from '@dxos/keys';
|
|
20
21
|
|
|
21
22
|
import * as Database from '../../Database';
|
|
22
|
-
import
|
|
23
|
-
import
|
|
23
|
+
import type * as Type from '../../Type';
|
|
24
|
+
import {
|
|
25
|
+
ReferenceAnnotationId,
|
|
26
|
+
getSchemaURI,
|
|
27
|
+
getTypeAnnotation,
|
|
28
|
+
getTypeIdentifierAnnotation,
|
|
29
|
+
} from '../Annotation/annotations';
|
|
30
|
+
import { type AnyEntity, type AnyProperties, type UnknownTypeSchema, getStaticTypeSchema } from '../common/types';
|
|
24
31
|
import { type JsonSchemaType } from '../JsonSchema';
|
|
32
|
+
import * as RefAtoms from './atoms';
|
|
25
33
|
|
|
26
34
|
/**
|
|
27
35
|
* The `$id` and `$ref` fields for an ECHO reference schema.
|
|
@@ -31,7 +39,9 @@ export const JSON_SCHEMA_ECHO_REF_ID = '/schemas/echo/ref';
|
|
|
31
39
|
export const getSchemaReference = (property: JsonSchemaType): { typename: string } | undefined => {
|
|
32
40
|
const { $id, reference: { schema: { $ref } = {} } = {} } = property;
|
|
33
41
|
if ($id === JSON_SCHEMA_ECHO_REF_ID && $ref) {
|
|
34
|
-
|
|
42
|
+
const parsed = DXN.tryMake($ref);
|
|
43
|
+
const typename = parsed ? DXN.getName(parsed) : undefined;
|
|
44
|
+
return typename ? { typename } : undefined;
|
|
35
45
|
}
|
|
36
46
|
};
|
|
37
47
|
|
|
@@ -40,7 +50,7 @@ export const createSchemaReference = (typename: string): Types.DeepMutable<JsonS
|
|
|
40
50
|
$id: JSON_SCHEMA_ECHO_REF_ID,
|
|
41
51
|
reference: {
|
|
42
52
|
schema: {
|
|
43
|
-
$ref: DXN.
|
|
53
|
+
$ref: DXN.make(typename),
|
|
44
54
|
},
|
|
45
55
|
},
|
|
46
56
|
};
|
|
@@ -82,7 +92,27 @@ export interface RefSchema<T extends AnyEntity> extends Schema.SchemaClass<Ref<T
|
|
|
82
92
|
* Type of the `Ref` function and extra methods attached to it.
|
|
83
93
|
*/
|
|
84
94
|
export interface RefFn {
|
|
85
|
-
|
|
95
|
+
// A reference target is a `Type.AnyEntity` entity (the canonical Option B
|
|
96
|
+
// input) or one of the well-known "any object" / "any relation" branded
|
|
97
|
+
// schemas (`Obj.Unknown` / `Relation.Unknown`). Arbitrary raw schemas are
|
|
98
|
+
// rejected.
|
|
99
|
+
//
|
|
100
|
+
// Referencing a type-kind entity (a meta-schema, e.g. `Type.Type`) yields a
|
|
101
|
+
// reference to a stored schema record; its loaded target is any registered
|
|
102
|
+
// entity (`Type.AnyEntity`), since a stored object/relation schema is itself a
|
|
103
|
+
// `Type.Type` record. Referencing an object/relation type yields a reference
|
|
104
|
+
// to an instance of that type.
|
|
105
|
+
<S extends Type.AnyEntity | UnknownTypeSchema<any, any> = Type.AnyEntity>(
|
|
106
|
+
schema: S,
|
|
107
|
+
): RefSchema<
|
|
108
|
+
S extends Type.AnyType
|
|
109
|
+
? Type.AnyEntity
|
|
110
|
+
: S extends Type.AnyObj | Type.AnyRelation
|
|
111
|
+
? Type.InstanceType<S>
|
|
112
|
+
: S extends UnknownTypeSchema<infer A, any>
|
|
113
|
+
? A
|
|
114
|
+
: never
|
|
115
|
+
>;
|
|
86
116
|
|
|
87
117
|
/**
|
|
88
118
|
* @returns True if the object is a reference.
|
|
@@ -92,7 +122,7 @@ export interface RefFn {
|
|
|
92
122
|
/**
|
|
93
123
|
* @returns True if the reference points to the given object id.
|
|
94
124
|
*/
|
|
95
|
-
|
|
125
|
+
hasEntityId: (id: EntityId) => (ref: Ref<any>) => boolean;
|
|
96
126
|
|
|
97
127
|
/**
|
|
98
128
|
* @returns True if the schema is a reference schema.
|
|
@@ -111,15 +141,19 @@ export interface RefFn {
|
|
|
111
141
|
make: <T extends AnyEntity>(object: T) => Ref<T>;
|
|
112
142
|
|
|
113
143
|
/**
|
|
114
|
-
* Constructs a reference that points to the object specified by the provided
|
|
144
|
+
* Constructs a reference that points to the object specified by the provided URI
|
|
145
|
+
* (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
|
|
115
146
|
*/
|
|
116
|
-
|
|
147
|
+
fromURI: (uri: URI.URI) => Ref<any>;
|
|
117
148
|
}
|
|
118
149
|
|
|
119
150
|
/**
|
|
120
151
|
* Schema builder for references.
|
|
121
152
|
*/
|
|
122
|
-
export const Ref: RefFn =
|
|
153
|
+
export const Ref: RefFn = (input: any): RefSchema<any> => {
|
|
154
|
+
// `Type.Type` entities carry their source schema on the hidden slot; the
|
|
155
|
+
// branded `Obj.Unknown` / `Relation.Unknown` schemas are used directly.
|
|
156
|
+
const schema = getStaticTypeSchema(input) ?? input;
|
|
123
157
|
assertArgument(Schema.isSchema(schema), 'schema', 'Must call with an instance of effect-schema');
|
|
124
158
|
const annotation = getTypeAnnotation(schema);
|
|
125
159
|
if (annotation == null) {
|
|
@@ -135,9 +169,9 @@ export const Ref: RefFn = <S extends Schema.Schema.Any>(schema: S): RefSchema<Sc
|
|
|
135
169
|
*/
|
|
136
170
|
export interface Ref<T> extends Pipeable.Pipeable {
|
|
137
171
|
/**
|
|
138
|
-
* Target object DXN.
|
|
172
|
+
* Target URI (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
|
|
139
173
|
*/
|
|
140
|
-
get
|
|
174
|
+
get uri(): URI.URI;
|
|
141
175
|
|
|
142
176
|
/**
|
|
143
177
|
* Returns true if the reference has a target available (inlined or resolver set).
|
|
@@ -164,6 +198,16 @@ export interface Ref<T> extends Pipeable.Pipeable {
|
|
|
164
198
|
|
|
165
199
|
tryLoad(): Promise<T | undefined>;
|
|
166
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Subscribe to the ref's resolution event.
|
|
203
|
+
* The callback fires when the target object becomes available in the working set
|
|
204
|
+
* (e.g. when its document is loaded after sibling-client mutation).
|
|
205
|
+
* Note: the resolver only schedules a notification when the target is requested
|
|
206
|
+
* via {@link target} while it is not yet loaded.
|
|
207
|
+
* @returns Function that unsubscribes the callback.
|
|
208
|
+
*/
|
|
209
|
+
onResolved(callback: () => void): () => void;
|
|
210
|
+
|
|
167
211
|
/**
|
|
168
212
|
* Do not inline the target object in the reference.
|
|
169
213
|
* Makes .target unavailable unless the reference is connected to a database context.
|
|
@@ -177,6 +221,13 @@ export interface Ref<T> extends Pipeable.Pipeable {
|
|
|
177
221
|
*/
|
|
178
222
|
noInline(): Ref<T>;
|
|
179
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Read-only atom for the ref target.
|
|
226
|
+
* Resolves once when the target loads; does NOT subscribe to target object mutations.
|
|
227
|
+
* Use `Obj.atom(ref)` if you need reactive snapshots that update on every object mutation.
|
|
228
|
+
*/
|
|
229
|
+
get atom(): Atom.Atom<T | undefined>;
|
|
230
|
+
|
|
180
231
|
/**
|
|
181
232
|
* Serializes the reference to a JSON object.
|
|
182
233
|
* The serialization format is compatible with the IPLD-style encoded references.
|
|
@@ -205,7 +256,10 @@ Ref.isRef = (obj: any): obj is Ref<any> => {
|
|
|
205
256
|
return obj && typeof obj === 'object' && RefTypeId in obj;
|
|
206
257
|
};
|
|
207
258
|
|
|
208
|
-
Ref.
|
|
259
|
+
Ref.hasEntityId = (id: EntityId) => (ref: Ref<any>) => {
|
|
260
|
+
const uri = EID.tryParse(ref.uri);
|
|
261
|
+
return uri !== undefined && EID.isLocal(uri) && EID.getEntityId(uri) === id;
|
|
262
|
+
};
|
|
209
263
|
|
|
210
264
|
Ref.isRefSchema = (schema: Schema.Schema<any, any>): schema is RefSchema<any> => {
|
|
211
265
|
return Ref.isRefSchemaAST(schema.ast);
|
|
@@ -220,16 +274,16 @@ Ref.make = <T extends AnyProperties>(obj: T): Ref<T> => {
|
|
|
220
274
|
throw new TypeError('Expected: ECHO object.');
|
|
221
275
|
}
|
|
222
276
|
|
|
223
|
-
// TODO(dmaretskyi): Extract to `
|
|
277
|
+
// TODO(dmaretskyi): Extract to `getObjectEchoUri` function.
|
|
224
278
|
const id = obj.id;
|
|
225
|
-
invariant(
|
|
226
|
-
const
|
|
227
|
-
return new RefImpl(
|
|
279
|
+
invariant(EntityId.isValid(id), 'Invalid object ID');
|
|
280
|
+
const uri = EID.make({ entityId: id });
|
|
281
|
+
return new RefImpl(uri, obj);
|
|
228
282
|
};
|
|
229
283
|
|
|
230
|
-
Ref.
|
|
231
|
-
assertArgument(
|
|
232
|
-
return new RefImpl(
|
|
284
|
+
Ref.fromURI = (uri: URI.URI): Ref<any> => {
|
|
285
|
+
assertArgument(typeof uri === 'string', 'uri', 'Expected URI string');
|
|
286
|
+
return new RefImpl(uri);
|
|
233
287
|
};
|
|
234
288
|
|
|
235
289
|
/**
|
|
@@ -245,18 +299,18 @@ export type JsonSchemaReferenceInfo = {
|
|
|
245
299
|
*/
|
|
246
300
|
// TODO(burdon): Move to json schema and make private?
|
|
247
301
|
export const createEchoReferenceSchema = (
|
|
248
|
-
|
|
302
|
+
echoUri: string | undefined,
|
|
249
303
|
typename: string | undefined,
|
|
250
304
|
version: string | undefined,
|
|
251
305
|
): Schema.SchemaClass<Ref<any>, EncodedReference> => {
|
|
252
|
-
if (!
|
|
253
|
-
throw new TypeError('Either
|
|
306
|
+
if (!echoUri && !typename) {
|
|
307
|
+
throw new TypeError('Either echoUri or typename must be provided.');
|
|
254
308
|
}
|
|
255
309
|
|
|
256
310
|
const referenceInfo: JsonSchemaReferenceInfo = {
|
|
257
311
|
schema: {
|
|
258
312
|
// TODO(dmaretskyi): Include version?
|
|
259
|
-
$ref:
|
|
313
|
+
$ref: echoUri ?? DXN.make(typename!),
|
|
260
314
|
},
|
|
261
315
|
schemaVersion: version,
|
|
262
316
|
};
|
|
@@ -269,7 +323,7 @@ export const createEchoReferenceSchema = (
|
|
|
269
323
|
return (value) =>
|
|
270
324
|
Effect.gen(function* () {
|
|
271
325
|
if (Ref.isRef(value)) {
|
|
272
|
-
return EncodedReference.
|
|
326
|
+
return EncodedReference.fromURI((value as Ref<any>).uri);
|
|
273
327
|
} else if (EncodedReference.isEncodedReference(value)) {
|
|
274
328
|
return value;
|
|
275
329
|
}
|
|
@@ -284,7 +338,7 @@ export const createEchoReferenceSchema = (
|
|
|
284
338
|
// TODO(dmaretskyi): This branch seems to be taken by Schema.is
|
|
285
339
|
if (Ref.isRef(value)) {
|
|
286
340
|
if (Option.isSome(dbService)) {
|
|
287
|
-
return dbService.value.db.makeRef(value.
|
|
341
|
+
return dbService.value.db.makeRef(value.uri);
|
|
288
342
|
} else {
|
|
289
343
|
return value;
|
|
290
344
|
}
|
|
@@ -294,9 +348,9 @@ export const createEchoReferenceSchema = (
|
|
|
294
348
|
return yield* Effect.fail(new ParseResult.Unexpected(value, 'reference'));
|
|
295
349
|
}
|
|
296
350
|
if (Option.isSome(dbService)) {
|
|
297
|
-
return dbService.value.db.makeRef(EncodedReference.
|
|
351
|
+
return dbService.value.db.makeRef(EncodedReference.toURI(value));
|
|
298
352
|
} else {
|
|
299
|
-
return Ref.
|
|
353
|
+
return Ref.fromURI(EncodedReference.toURI(value));
|
|
300
354
|
}
|
|
301
355
|
});
|
|
302
356
|
},
|
|
@@ -330,23 +384,32 @@ export interface RefResolver {
|
|
|
330
384
|
/**
|
|
331
385
|
* Resolve ref synchronously from the objects in the working set.
|
|
332
386
|
*
|
|
333
|
-
* @param
|
|
387
|
+
* @param uri
|
|
334
388
|
* @param load If true the resolver should attempt to load the object from disk.
|
|
335
389
|
* @param onLoad Callback to call when the object is loaded.
|
|
336
390
|
*/
|
|
337
|
-
resolveSync(
|
|
391
|
+
resolveSync(uri: URI.URI, load: boolean, onLoad?: () => void): AnyProperties | undefined;
|
|
338
392
|
|
|
339
393
|
/**
|
|
340
394
|
* Resolver ref asynchronously.
|
|
341
395
|
*/
|
|
342
|
-
resolve(
|
|
396
|
+
resolve(uri: URI.URI): Promise<AnyProperties | undefined>;
|
|
343
397
|
|
|
344
398
|
// TODO(dmaretskyi): Combine with `resolve`.
|
|
345
|
-
resolveSchema(
|
|
399
|
+
resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined>;
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Resolve the source `Type.AnyEntity` entity for a type URI. Used by
|
|
403
|
+
* deserialization paths (`Obj.fromJSON`) to set the back-reference accessed
|
|
404
|
+
* via `Obj.getType` / `Entity.getType`. Optional — resolvers that only
|
|
405
|
+
* carry raw schemas may leave this unimplemented; the deserializer falls
|
|
406
|
+
* back to leaving the type entity unset.
|
|
407
|
+
*/
|
|
408
|
+
resolveType?(uri: URI.URI): Promise<unknown | undefined>;
|
|
346
409
|
}
|
|
347
410
|
|
|
348
411
|
export class RefImpl<T> implements Ref<T> {
|
|
349
|
-
#
|
|
412
|
+
#uri: URI.URI;
|
|
350
413
|
#resolver?: RefResolver = undefined;
|
|
351
414
|
#resolved = new Event<void>();
|
|
352
415
|
|
|
@@ -363,16 +426,16 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
363
426
|
this.#resolved.emit();
|
|
364
427
|
};
|
|
365
428
|
|
|
366
|
-
constructor(
|
|
367
|
-
this.#
|
|
429
|
+
constructor(uri: URI.URI, target?: T) {
|
|
430
|
+
this.#uri = uri;
|
|
368
431
|
this.#target = target;
|
|
369
432
|
}
|
|
370
433
|
|
|
371
434
|
/**
|
|
372
435
|
* @inheritdoc
|
|
373
436
|
*/
|
|
374
|
-
get
|
|
375
|
-
return this.#
|
|
437
|
+
get uri(): URI.URI {
|
|
438
|
+
return this.#uri;
|
|
376
439
|
}
|
|
377
440
|
|
|
378
441
|
/**
|
|
@@ -391,7 +454,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
391
454
|
}
|
|
392
455
|
|
|
393
456
|
invariant(this.#resolver, 'Resolver is not set');
|
|
394
|
-
return this.#resolver.resolveSync(this.#
|
|
457
|
+
return this.#resolver.resolveSync(this.#uri, true, this.#resolverCallback) as T | undefined;
|
|
395
458
|
}
|
|
396
459
|
|
|
397
460
|
/**
|
|
@@ -402,7 +465,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
402
465
|
return this.#target;
|
|
403
466
|
}
|
|
404
467
|
invariant(this.#resolver, 'Resolver is not set');
|
|
405
|
-
const obj = await this.#resolver.resolve(this.#
|
|
468
|
+
const obj = await this.#resolver.resolve(this.#uri);
|
|
406
469
|
if (obj == null) {
|
|
407
470
|
throw new Error('Object not found');
|
|
408
471
|
}
|
|
@@ -417,7 +480,14 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
417
480
|
return this.#target;
|
|
418
481
|
}
|
|
419
482
|
invariant(this.#resolver, 'Resolver is not set');
|
|
420
|
-
return (await this.#resolver.resolve(this.#
|
|
483
|
+
return (await this.#resolver.resolve(this.#uri)) as T | undefined;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* @inheritdoc
|
|
488
|
+
*/
|
|
489
|
+
onResolved(callback: () => void): () => void {
|
|
490
|
+
return this.#resolved.on(callback);
|
|
421
491
|
}
|
|
422
492
|
|
|
423
493
|
/**
|
|
@@ -426,14 +496,14 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
426
496
|
* Clones the reference object.
|
|
427
497
|
*/
|
|
428
498
|
noInline(): RefImpl<T> {
|
|
429
|
-
const ref = new RefImpl<T>(this.#
|
|
499
|
+
const ref = new RefImpl<T>(this.#uri, undefined);
|
|
430
500
|
ref.#resolver = this.#resolver;
|
|
431
501
|
return ref;
|
|
432
502
|
}
|
|
433
503
|
|
|
434
504
|
encode(): EncodedReference {
|
|
435
505
|
return {
|
|
436
|
-
'/': this.#
|
|
506
|
+
'/': this.#uri,
|
|
437
507
|
...(this.#target ? { target: this.#target } : {}),
|
|
438
508
|
};
|
|
439
509
|
}
|
|
@@ -453,7 +523,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
453
523
|
return `Ref(${this.#target.toString()})`;
|
|
454
524
|
}
|
|
455
525
|
|
|
456
|
-
return `Ref(${this.#
|
|
526
|
+
return `Ref(${this.#uri.toString()})`;
|
|
457
527
|
}
|
|
458
528
|
|
|
459
529
|
[inspectCustom]: CustomInspectFunction = (depth, options, inspect) => {
|
|
@@ -469,12 +539,16 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
469
539
|
* so without this, each access would create a separate cache entry.
|
|
470
540
|
*/
|
|
471
541
|
[Hash.symbol](): number {
|
|
472
|
-
return Hash.hash(this.#
|
|
542
|
+
return Hash.hash(this.#uri.toString());
|
|
473
543
|
}
|
|
474
544
|
|
|
475
545
|
/** Effect Equal trait. See {@link Hash.symbol} for rationale. */
|
|
476
546
|
[Equal.symbol](that: Equal.Equal): boolean {
|
|
477
|
-
return that instanceof RefImpl && this.#
|
|
547
|
+
return that instanceof RefImpl && this.#uri === that.uri;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
get atom(): Atom.Atom<T | undefined> {
|
|
551
|
+
return RefAtoms.refSimpleFamily(this);
|
|
478
552
|
}
|
|
479
553
|
|
|
480
554
|
/**
|
|
@@ -521,8 +595,8 @@ const refVariance: Ref<any>[typeof RefTypeId] = {
|
|
|
521
595
|
};
|
|
522
596
|
|
|
523
597
|
export const refFromEncodedReference = (encodedReference: EncodedReference, resolver?: RefResolver): Ref<any> => {
|
|
524
|
-
const
|
|
525
|
-
const ref = new RefImpl(
|
|
598
|
+
const uri = EncodedReference.toURI(encodedReference);
|
|
599
|
+
const ref = new RefImpl(uri);
|
|
526
600
|
|
|
527
601
|
// TODO(dmaretskyi): Handle inline target in the encoded reference.
|
|
528
602
|
|
|
@@ -533,23 +607,26 @@ export const refFromEncodedReference = (encodedReference: EncodedReference, reso
|
|
|
533
607
|
};
|
|
534
608
|
|
|
535
609
|
export class StaticRefResolver implements RefResolver {
|
|
536
|
-
public objects = new Map<
|
|
537
|
-
public schemas = new Map<
|
|
610
|
+
public objects = new Map<EntityId, AnyProperties>();
|
|
611
|
+
public schemas = new Map<URI.URI, Schema.Schema.AnyNoContext>();
|
|
538
612
|
|
|
539
613
|
addObject(obj: AnyProperties): this {
|
|
540
614
|
this.objects.set(obj.id, obj);
|
|
541
615
|
return this;
|
|
542
616
|
}
|
|
543
617
|
|
|
544
|
-
addSchema(
|
|
545
|
-
const
|
|
546
|
-
invariant(
|
|
547
|
-
|
|
618
|
+
addSchema(input: Type.AnyEntity): this {
|
|
619
|
+
const schema = getStaticTypeSchema(input);
|
|
620
|
+
invariant(schema, 'Type entity is missing its source schema');
|
|
621
|
+
const uri = getSchemaURI(schema);
|
|
622
|
+
invariant(uri, 'Schema has no URI');
|
|
623
|
+
this.schemas.set(uri, schema);
|
|
548
624
|
return this;
|
|
549
625
|
}
|
|
550
626
|
|
|
551
|
-
resolveSync(
|
|
552
|
-
const
|
|
627
|
+
resolveSync(uri: URI.URI, _load: boolean, _onLoad?: () => void): AnyProperties | undefined {
|
|
628
|
+
const echoUri = EID.tryParse(uri);
|
|
629
|
+
const id = echoUri ? EID.getEntityId(echoUri) : undefined;
|
|
553
630
|
if (id == null) {
|
|
554
631
|
return undefined;
|
|
555
632
|
}
|
|
@@ -557,8 +634,9 @@ export class StaticRefResolver implements RefResolver {
|
|
|
557
634
|
return this.objects.get(id);
|
|
558
635
|
}
|
|
559
636
|
|
|
560
|
-
async resolve(
|
|
561
|
-
const
|
|
637
|
+
async resolve(uri: URI.URI): Promise<AnyProperties | undefined> {
|
|
638
|
+
const echoUri = EID.tryParse(uri);
|
|
639
|
+
const id = echoUri ? EID.getEntityId(echoUri) : undefined;
|
|
562
640
|
if (id == null) {
|
|
563
641
|
return undefined;
|
|
564
642
|
}
|
|
@@ -566,7 +644,7 @@ export class StaticRefResolver implements RefResolver {
|
|
|
566
644
|
return this.objects.get(id);
|
|
567
645
|
}
|
|
568
646
|
|
|
569
|
-
async resolveSchema(
|
|
570
|
-
return this.schemas.get(
|
|
647
|
+
async resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined> {
|
|
648
|
+
return this.schemas.get(uri);
|
|
571
649
|
}
|
|
572
650
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type * as Atom from '@effect-atom/atom/Atom';
|
|
6
|
+
|
|
7
|
+
import type { Ref } from './ref';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal helper for loading ref targets in atoms.
|
|
11
|
+
* Handles the common pattern of checking for loaded target and triggering async load.
|
|
12
|
+
*/
|
|
13
|
+
export const loadRefTarget = <T, R>(
|
|
14
|
+
ref: Ref<T>,
|
|
15
|
+
get: Atom.Context,
|
|
16
|
+
onTargetAvailable: (target: T) => R,
|
|
17
|
+
): R | undefined => {
|
|
18
|
+
// Accessing `ref.target` registers a resolution callback when the target is
|
|
19
|
+
// not yet loaded, so resolution can be observed via `ref.onResolved` below.
|
|
20
|
+
const currentTarget = ref.target;
|
|
21
|
+
if (currentTarget) {
|
|
22
|
+
return onTargetAvailable(currentTarget);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Subscribe to the ref's resolution event in case the target loads later.
|
|
26
|
+
const unsubscribe = ref.onResolved(() => {
|
|
27
|
+
const target = ref.target;
|
|
28
|
+
if (target) {
|
|
29
|
+
get.setSelf(onTargetAvailable(target));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
get.addFinalizer(unsubscribe);
|
|
33
|
+
|
|
34
|
+
// Also try async load (e.g. for objects that need disk loading).
|
|
35
|
+
void ref
|
|
36
|
+
.load()
|
|
37
|
+
.then((loadedTarget) => {
|
|
38
|
+
get.setSelf(onTargetAvailable(loadedTarget));
|
|
39
|
+
})
|
|
40
|
+
.catch(() => {
|
|
41
|
+
// Loading failed; the resolution subscription above will pick up cross-client updates.
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return undefined;
|
|
45
|
+
};
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import * as Schema from 'effect/Schema';
|
|
6
6
|
import { describe, test } from 'vitest';
|
|
7
7
|
|
|
8
|
+
import { DXN } from '@dxos/keys';
|
|
9
|
+
|
|
8
10
|
import { FieldPath } from '../Annotation';
|
|
9
11
|
import { EchoObjectSchema } from '../Entity';
|
|
10
12
|
import { FormatAnnotation, TypeFormat } from '../Format';
|
|
@@ -16,7 +18,7 @@ describe('schema composition', () => {
|
|
|
16
18
|
const BaseType = Schema.Struct({
|
|
17
19
|
name: Schema.String,
|
|
18
20
|
email: Schema.String,
|
|
19
|
-
}).pipe(EchoObjectSchema(
|
|
21
|
+
}).pipe(EchoObjectSchema(DXN.make('com.example.person', '0.1.0')));
|
|
20
22
|
|
|
21
23
|
const OverlaySchema = Schema.Struct({
|
|
22
24
|
email: Schema.String.pipe(FieldPath('$.email'), FormatAnnotation.set(TypeFormat.Email)),
|
|
@@ -6,9 +6,6 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
7
7
|
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
|
-
import { DXN } from '@dxos/keys';
|
|
10
|
-
|
|
11
|
-
import { type TypeAnnotation, TypeAnnotationId, TypeIdentifierAnnotationId } from '../Annotation';
|
|
12
9
|
|
|
13
10
|
// TODO(ZaymonFC): Do this one at a time. This might be dangerous.
|
|
14
11
|
export const addFieldsToSchema = (
|
|
@@ -68,25 +65,3 @@ export const updateFieldNameInSchema = (
|
|
|
68
65
|
),
|
|
69
66
|
);
|
|
70
67
|
};
|
|
71
|
-
|
|
72
|
-
export const setTypenameInSchema = (
|
|
73
|
-
schema: Schema.Schema.AnyNoContext,
|
|
74
|
-
typename: string,
|
|
75
|
-
): Schema.Schema.AnyNoContext => {
|
|
76
|
-
const existingAnnotation = schema.ast.annotations[TypeAnnotationId] as TypeAnnotation;
|
|
77
|
-
invariant(existingAnnotation, `Missing ${String(TypeAnnotationId)}`);
|
|
78
|
-
|
|
79
|
-
return schema.annotations({
|
|
80
|
-
...schema.ast.annotations,
|
|
81
|
-
[TypeAnnotationId]: {
|
|
82
|
-
kind: existingAnnotation.kind,
|
|
83
|
-
typename,
|
|
84
|
-
version: existingAnnotation.version,
|
|
85
|
-
} satisfies TypeAnnotation,
|
|
86
|
-
[SchemaAST.JSONSchemaAnnotationId]: {
|
|
87
|
-
...(schema.ast.annotations[SchemaAST.JSONSchemaAnnotationId] ?? {}),
|
|
88
|
-
$id: schema.ast.annotations[TypeIdentifierAnnotationId] ?? DXN.fromTypename(typename).toString(),
|
|
89
|
-
typename,
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
|
|
7
|
+
import { IconAnnotation, LabelAnnotation } from '../Annotation';
|
|
8
|
+
import { EntityKind, KindId, SchemaKindId, StaticTypeSchemaSlot } from '../common/types';
|
|
9
|
+
import { EchoTypeKindSchema, TypeMetaSchemaDXN } from '../Entity';
|
|
10
|
+
import { JsonSchemaType } from '../JsonSchema';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Raw struct backing {@link TypeSchema}. Exposed only so `TypeSchema`
|
|
14
|
+
* (the TS type) can derive its data fields via `Schema.Schema.Type<typeof ...>`;
|
|
15
|
+
* runtime callers should use {@link TypeSchema} (the piped, branded entity).
|
|
16
|
+
*
|
|
17
|
+
* `typename` and `version` are NOT data fields — they live in `EntityMeta.key` /
|
|
18
|
+
* `EntityMeta.version` (the canonical registry-provenance pair, queryable via
|
|
19
|
+
* `Filter.key(...)`). The same `jsonSchema` payload also embeds them so a
|
|
20
|
+
* standalone JSON-Schema export remains self-describing, but the schema-registry
|
|
21
|
+
* reads/writes them through meta.
|
|
22
|
+
*/
|
|
23
|
+
const TypeSchemaStruct = Schema.Struct({
|
|
24
|
+
name: Schema.optional(Schema.String),
|
|
25
|
+
jsonSchema: JsonSchemaType,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Persistent representation of a schema.
|
|
30
|
+
*/
|
|
31
|
+
export const TypeSchema = TypeSchemaStruct.pipe(
|
|
32
|
+
LabelAnnotation.set(['name']),
|
|
33
|
+
IconAnnotation.set({
|
|
34
|
+
icon: 'ph--database--regular',
|
|
35
|
+
hue: 'green',
|
|
36
|
+
}),
|
|
37
|
+
EchoTypeKindSchema(TypeMetaSchemaDXN),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Persistent representation of a schema — the runtime shape that
|
|
42
|
+
* `db.addType(Type.makeObjectFromJsonSchema(...))` produces
|
|
43
|
+
* and `Filter.type(Type.Type).run()` returns.
|
|
44
|
+
*
|
|
45
|
+
* Structurally identical to a static `Type.Type` entity: the entity-handler's
|
|
46
|
+
* `get` trap exposes `[SchemaKindId]` (derived from `system.kind` and
|
|
47
|
+
* `data.jsonSchema.entityKind`) and rebuilds `[StaticTypeSchemaSlot]` lazily
|
|
48
|
+
* from `jsonSchema`, so a persisted instance satisfies the public `Type<A>`
|
|
49
|
+
* interface without casting.
|
|
50
|
+
*/
|
|
51
|
+
export type TypeSchema = Schema.Schema.Type<typeof TypeSchemaStruct> & {
|
|
52
|
+
/** Object identifier — injected by `EchoTypeKindSchema` and stamped at construction. */
|
|
53
|
+
readonly id: string;
|
|
54
|
+
/** Entity-kind discriminator (object/relation/type) carried on every entity instance. */
|
|
55
|
+
readonly [KindId]: EntityKind.Type;
|
|
56
|
+
/** Kind of schema described by this meta-instance — always `EntityKind.Type` for `Type.Type` itself. */
|
|
57
|
+
readonly [SchemaKindId]: EntityKind.Type;
|
|
58
|
+
/** Effect Schema rebuilt lazily from `jsonSchema`; satisfies `Type.getSchema(...)` without an extra cast. */
|
|
59
|
+
readonly [StaticTypeSchemaSlot]: Schema.Schema.AnyNoContext;
|
|
60
|
+
};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- [x] Unify FOUR different nests of test schema.
|
|
8
8
|
- [x] Remove @deprecated from internal methods and mark @internal (e.g., getSchemaDXN).
|
|
9
9
|
- NOTE: Internal methods should not use the import \* from Obj/Type APIs.
|
|
10
|
-
- [x] import
|
|
10
|
+
- [x] import EntityId => @dxos/keys
|
|
11
11
|
- [x] Entity.Any = Obj.Any | Relation.Any
|
|
12
12
|
- NOTE: Relation does not extend (in not polymorphic with) Obj.
|
|
13
13
|
- [x] import LabelAnnotation => Annotation.LabelAnnotation
|
|
@@ -99,4 +99,4 @@
|
|
|
99
99
|
- [ ] ReactiveObject should specify id property? Reconcile AnyProperties, ReactiveObject, HasId, WithId, etc.
|
|
100
100
|
- [ ] Can we us S.is(MyType) to detect objects with our types system? (Branding?)
|
|
101
101
|
- [ ] Type.Expando doesn't work with AtomQuery result type (have to use Obj.Any instead).
|
|
102
|
-
- [ ] Obj.Any doesn't work with Obj.
|
|
102
|
+
- [ ] Obj.Any doesn't work with Obj.update callback types (have to use `any` for the mutable parameter).
|