@dxos/echo 0.8.4-staging.ac66bdf99f → 0.9.1-main.c7dcc2e112
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 +45 -6
- package/dist/lib/neutral/Database.mjs +10 -17
- package/dist/lib/neutral/Entity.mjs +35 -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 +33 -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-4OIBYSXE.mjs → chunk-3JXQUMUI.mjs} +78 -32
- package/dist/lib/neutral/chunk-3JXQUMUI.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-G3IQMKF7.mjs → chunk-4TPQZPLY.mjs} +130 -119
- package/dist/lib/neutral/chunk-4TPQZPLY.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TU3GW67D.mjs → chunk-5GAIWRQB.mjs} +40 -40
- package/dist/lib/neutral/chunk-5GAIWRQB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-B4BASU6W.mjs → chunk-6CEISA3V.mjs} +93 -76
- package/dist/lib/neutral/chunk-6CEISA3V.mjs.map +7 -0
- 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-ANHVGJI4.mjs → chunk-7LOUAPYZ.mjs} +9 -5
- package/dist/lib/neutral/chunk-7LOUAPYZ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WAK4DMFV.mjs → chunk-A53NTBHE.mjs} +12 -7
- package/dist/lib/neutral/chunk-A53NTBHE.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-EAMSSLZC.mjs → chunk-AFANXSGV.mjs} +83 -46
- package/dist/lib/neutral/chunk-AFANXSGV.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-E7IOTOZD.mjs +108 -0
- package/dist/lib/neutral/chunk-E7IOTOZD.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-HGWQR5KH.mjs +259 -0
- package/dist/lib/neutral/chunk-HGWQR5KH.mjs.map +7 -0
- package/dist/lib/neutral/chunk-JZ6LFQU5.mjs +109 -0
- package/dist/lib/neutral/chunk-JZ6LFQU5.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-JUXPFOEI.mjs → chunk-K3S7D5PR.mjs} +48 -88
- package/dist/lib/neutral/chunk-K3S7D5PR.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OS35K56T.mjs → chunk-L3OBWBV2.mjs} +3 -3
- package/dist/lib/neutral/{chunk-OS35K56T.mjs.map → chunk-L3OBWBV2.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-V36VO5SS.mjs → chunk-NOL7O3BL.mjs} +32 -40
- package/dist/lib/neutral/chunk-NOL7O3BL.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-7RO7CPBZ.mjs → chunk-PLDMJJJC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-HBUZJNZO.mjs → chunk-SZ5WB6HF.mjs} +94 -99
- package/dist/lib/neutral/chunk-SZ5WB6HF.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-BVOFLCVF.mjs → chunk-TF5BSLF6.mjs} +9 -6
- package/dist/lib/neutral/chunk-TF5BSLF6.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-MOR5ERFM.mjs → chunk-VQYL2OQF.mjs} +771 -1252
- package/dist/lib/neutral/chunk-VQYL2OQF.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-WU3GIANS.mjs +31 -0
- package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +7 -0
- package/dist/lib/neutral/chunk-WZ32BF53.mjs +702 -0
- package/dist/lib/neutral/chunk-WZ32BF53.mjs.map +7 -0
- package/dist/lib/neutral/chunk-X3NUUON4.mjs +184 -0
- package/dist/lib/neutral/chunk-X3NUUON4.mjs.map +7 -0
- package/dist/lib/neutral/chunk-Z3WMRRAZ.mjs +168 -0
- package/dist/lib/neutral/chunk-Z3WMRRAZ.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +47 -41
- package/dist/lib/neutral/internal/index.mjs +157 -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 +78 -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 +103 -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 +69 -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 +106 -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 +366 -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 +120 -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 +43 -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/index.d.ts +1 -0
- package/dist/types/src/internal/Ref/index.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
- package/dist/types/src/internal/Ref/ref.d.ts +114 -19
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/strong-deps.d.ts +35 -0
- package/dist/types/src/internal/Ref/strong-deps.d.ts.map +1 -0
- 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 +163 -4
- package/src/Collection.ts +5 -9
- package/src/Database.ts +126 -101
- package/src/Dataset.ts +10 -2
- package/src/Entity.test.ts +116 -6
- package/src/Entity.ts +136 -32
- package/src/Err.ts +4 -4
- package/src/Feed.ts +95 -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 +170 -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 +50 -6
- package/src/Type.test.ts +223 -18
- package/src/Type.ts +623 -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 +199 -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 +275 -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 +92 -36
- 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/index.ts +1 -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 +224 -69
- package/src/internal/Ref/strong-deps.ts +107 -0
- 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 +0 -125
- 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-PLDMJJJC.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
|
};
|
|
@@ -71,7 +81,8 @@ export const getReferenceAst = (ast: SchemaAST.AST): RefereneAST | undefined =>
|
|
|
71
81
|
};
|
|
72
82
|
};
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
85
|
+
export const RefTypeId: unique symbol = Symbol.for('@dxos/echo/internal/Ref') as any;
|
|
75
86
|
|
|
76
87
|
/**
|
|
77
88
|
* Reference Schema.
|
|
@@ -82,7 +93,27 @@ export interface RefSchema<T extends AnyEntity> extends Schema.SchemaClass<Ref<T
|
|
|
82
93
|
* Type of the `Ref` function and extra methods attached to it.
|
|
83
94
|
*/
|
|
84
95
|
export interface RefFn {
|
|
85
|
-
|
|
96
|
+
// A reference target is a `Type.AnyEntity` entity (the canonical Option B
|
|
97
|
+
// input) or one of the well-known "any object" / "any relation" branded
|
|
98
|
+
// schemas (`Obj.Unknown` / `Relation.Unknown`). Arbitrary raw schemas are
|
|
99
|
+
// rejected.
|
|
100
|
+
//
|
|
101
|
+
// Referencing a type-kind entity (a meta-schema, e.g. `Type.Type`) yields a
|
|
102
|
+
// reference to a stored schema record; its loaded target is any registered
|
|
103
|
+
// entity (`Type.AnyEntity`), since a stored object/relation schema is itself a
|
|
104
|
+
// `Type.Type` record. Referencing an object/relation type yields a reference
|
|
105
|
+
// to an instance of that type.
|
|
106
|
+
<S extends Type.AnyEntity | UnknownTypeSchema<any, any> = Type.AnyEntity>(
|
|
107
|
+
schema: S,
|
|
108
|
+
): RefSchema<
|
|
109
|
+
S extends Type.AnyType
|
|
110
|
+
? Type.AnyEntity
|
|
111
|
+
: S extends Type.AnyObj | Type.AnyRelation
|
|
112
|
+
? Type.InstanceType<S>
|
|
113
|
+
: S extends UnknownTypeSchema<infer A, any>
|
|
114
|
+
? A
|
|
115
|
+
: never
|
|
116
|
+
>;
|
|
86
117
|
|
|
87
118
|
/**
|
|
88
119
|
* @returns True if the object is a reference.
|
|
@@ -92,7 +123,7 @@ export interface RefFn {
|
|
|
92
123
|
/**
|
|
93
124
|
* @returns True if the reference points to the given object id.
|
|
94
125
|
*/
|
|
95
|
-
|
|
126
|
+
hasEntityId: (id: EntityId) => (ref: Ref<any>) => boolean;
|
|
96
127
|
|
|
97
128
|
/**
|
|
98
129
|
* @returns True if the schema is a reference schema.
|
|
@@ -111,15 +142,19 @@ export interface RefFn {
|
|
|
111
142
|
make: <T extends AnyEntity>(object: T) => Ref<T>;
|
|
112
143
|
|
|
113
144
|
/**
|
|
114
|
-
* Constructs a reference that points to the object specified by the provided
|
|
145
|
+
* Constructs a reference that points to the object specified by the provided URI
|
|
146
|
+
* (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
|
|
115
147
|
*/
|
|
116
|
-
|
|
148
|
+
fromURI: (uri: URI.URI) => Ref<any>;
|
|
117
149
|
}
|
|
118
150
|
|
|
119
151
|
/**
|
|
120
152
|
* Schema builder for references.
|
|
121
153
|
*/
|
|
122
|
-
export const Ref: RefFn =
|
|
154
|
+
export const Ref: RefFn = (input: any): RefSchema<any> => {
|
|
155
|
+
// `Type.Type` entities carry their source schema on the hidden slot; the
|
|
156
|
+
// branded `Obj.Unknown` / `Relation.Unknown` schemas are used directly.
|
|
157
|
+
const schema = getStaticTypeSchema(input) ?? input;
|
|
123
158
|
assertArgument(Schema.isSchema(schema), 'schema', 'Must call with an instance of effect-schema');
|
|
124
159
|
const annotation = getTypeAnnotation(schema);
|
|
125
160
|
if (annotation == null) {
|
|
@@ -135,9 +170,9 @@ export const Ref: RefFn = <S extends Schema.Schema.Any>(schema: S): RefSchema<Sc
|
|
|
135
170
|
*/
|
|
136
171
|
export interface Ref<T> extends Pipeable.Pipeable {
|
|
137
172
|
/**
|
|
138
|
-
* Target object DXN.
|
|
173
|
+
* Target URI (either an `echo:` EID for an object reference or a `dxn:` DXN for a type reference).
|
|
139
174
|
*/
|
|
140
|
-
get
|
|
175
|
+
get uri(): URI.URI;
|
|
141
176
|
|
|
142
177
|
/**
|
|
143
178
|
* Returns true if the reference has a target available (inlined or resolver set).
|
|
@@ -164,6 +199,16 @@ export interface Ref<T> extends Pipeable.Pipeable {
|
|
|
164
199
|
|
|
165
200
|
tryLoad(): Promise<T | undefined>;
|
|
166
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Subscribe to the ref's resolution event.
|
|
204
|
+
* The callback fires when the target object becomes available in the working set
|
|
205
|
+
* (e.g. when its document is loaded after sibling-client mutation).
|
|
206
|
+
* Note: the resolver only schedules a notification when the target is requested
|
|
207
|
+
* via {@link target} while it is not yet loaded.
|
|
208
|
+
* @returns Function that unsubscribes the callback.
|
|
209
|
+
*/
|
|
210
|
+
onResolved(callback: () => void): () => void;
|
|
211
|
+
|
|
167
212
|
/**
|
|
168
213
|
* Do not inline the target object in the reference.
|
|
169
214
|
* Makes .target unavailable unless the reference is connected to a database context.
|
|
@@ -177,6 +222,13 @@ export interface Ref<T> extends Pipeable.Pipeable {
|
|
|
177
222
|
*/
|
|
178
223
|
noInline(): Ref<T>;
|
|
179
224
|
|
|
225
|
+
/**
|
|
226
|
+
* Read-only atom for the ref target.
|
|
227
|
+
* Resolves once when the target loads; does NOT subscribe to target object mutations.
|
|
228
|
+
* Use `Obj.atom(ref)` if you need reactive snapshots that update on every object mutation.
|
|
229
|
+
*/
|
|
230
|
+
get atom(): Atom.Atom<T | undefined>;
|
|
231
|
+
|
|
180
232
|
/**
|
|
181
233
|
* Serializes the reference to a JSON object.
|
|
182
234
|
* The serialization format is compatible with the IPLD-style encoded references.
|
|
@@ -202,10 +254,13 @@ export declare namespace Ref {
|
|
|
202
254
|
}
|
|
203
255
|
|
|
204
256
|
Ref.isRef = (obj: any): obj is Ref<any> => {
|
|
205
|
-
return obj && typeof obj === 'object' && RefTypeId in obj;
|
|
257
|
+
return obj != null && typeof obj === 'object' && RefTypeId in obj;
|
|
206
258
|
};
|
|
207
259
|
|
|
208
|
-
Ref.
|
|
260
|
+
Ref.hasEntityId = (id: EntityId) => (ref: Ref<any>) => {
|
|
261
|
+
const uri = EID.tryParse(ref.uri);
|
|
262
|
+
return uri !== undefined && EID.isLocal(uri) && EID.getEntityId(uri) === id;
|
|
263
|
+
};
|
|
209
264
|
|
|
210
265
|
Ref.isRefSchema = (schema: Schema.Schema<any, any>): schema is RefSchema<any> => {
|
|
211
266
|
return Ref.isRefSchemaAST(schema.ast);
|
|
@@ -220,16 +275,17 @@ Ref.make = <T extends AnyProperties>(obj: T): Ref<T> => {
|
|
|
220
275
|
throw new TypeError('Expected: ECHO object.');
|
|
221
276
|
}
|
|
222
277
|
|
|
223
|
-
// TODO(dmaretskyi): Extract to `
|
|
278
|
+
// TODO(dmaretskyi): Extract to `getObjectEchoUri` function.
|
|
224
279
|
const id = obj.id;
|
|
225
|
-
invariant(
|
|
226
|
-
const
|
|
227
|
-
|
|
280
|
+
invariant(EntityId.isValid(id), 'Invalid object ID');
|
|
281
|
+
const uri = EID.make({ entityId: id });
|
|
282
|
+
const ref = new RefImpl(uri, obj);
|
|
283
|
+
return ref;
|
|
228
284
|
};
|
|
229
285
|
|
|
230
|
-
Ref.
|
|
231
|
-
assertArgument(
|
|
232
|
-
return new RefImpl(
|
|
286
|
+
Ref.fromURI = (uri: URI.URI): Ref<any> => {
|
|
287
|
+
assertArgument(typeof uri === 'string', 'uri', 'Expected URI string');
|
|
288
|
+
return new RefImpl(uri);
|
|
233
289
|
};
|
|
234
290
|
|
|
235
291
|
/**
|
|
@@ -245,18 +301,18 @@ export type JsonSchemaReferenceInfo = {
|
|
|
245
301
|
*/
|
|
246
302
|
// TODO(burdon): Move to json schema and make private?
|
|
247
303
|
export const createEchoReferenceSchema = (
|
|
248
|
-
|
|
304
|
+
echoUri: string | undefined,
|
|
249
305
|
typename: string | undefined,
|
|
250
306
|
version: string | undefined,
|
|
251
307
|
): Schema.SchemaClass<Ref<any>, EncodedReference> => {
|
|
252
|
-
if (!
|
|
253
|
-
throw new TypeError('Either
|
|
308
|
+
if (!echoUri && !typename) {
|
|
309
|
+
throw new TypeError('Either echoUri or typename must be provided.');
|
|
254
310
|
}
|
|
255
311
|
|
|
256
312
|
const referenceInfo: JsonSchemaReferenceInfo = {
|
|
257
313
|
schema: {
|
|
258
314
|
// TODO(dmaretskyi): Include version?
|
|
259
|
-
$ref:
|
|
315
|
+
$ref: echoUri ?? DXN.make(typename!),
|
|
260
316
|
},
|
|
261
317
|
schemaVersion: version,
|
|
262
318
|
};
|
|
@@ -269,7 +325,7 @@ export const createEchoReferenceSchema = (
|
|
|
269
325
|
return (value) =>
|
|
270
326
|
Effect.gen(function* () {
|
|
271
327
|
if (Ref.isRef(value)) {
|
|
272
|
-
return EncodedReference.
|
|
328
|
+
return EncodedReference.fromURI((value as Ref<any>).uri);
|
|
273
329
|
} else if (EncodedReference.isEncodedReference(value)) {
|
|
274
330
|
return value;
|
|
275
331
|
}
|
|
@@ -284,7 +340,7 @@ export const createEchoReferenceSchema = (
|
|
|
284
340
|
// TODO(dmaretskyi): This branch seems to be taken by Schema.is
|
|
285
341
|
if (Ref.isRef(value)) {
|
|
286
342
|
if (Option.isSome(dbService)) {
|
|
287
|
-
return dbService.value.db.makeRef(value.
|
|
343
|
+
return dbService.value.db.makeRef(value.uri);
|
|
288
344
|
} else {
|
|
289
345
|
return value;
|
|
290
346
|
}
|
|
@@ -294,9 +350,9 @@ export const createEchoReferenceSchema = (
|
|
|
294
350
|
return yield* Effect.fail(new ParseResult.Unexpected(value, 'reference'));
|
|
295
351
|
}
|
|
296
352
|
if (Option.isSome(dbService)) {
|
|
297
|
-
return dbService.value.db.makeRef(EncodedReference.
|
|
353
|
+
return dbService.value.db.makeRef(EncodedReference.toURI(value));
|
|
298
354
|
} else {
|
|
299
|
-
return Ref.
|
|
355
|
+
return Ref.fromURI(EncodedReference.toURI(value));
|
|
300
356
|
}
|
|
301
357
|
});
|
|
302
358
|
},
|
|
@@ -326,27 +382,109 @@ const getSchemaExpectedName = (ast: SchemaAST.Annotated): string | undefined =>
|
|
|
326
382
|
);
|
|
327
383
|
};
|
|
328
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Load-source ceiling for a resolution request. Cheaper tiers are always probed first; the
|
|
387
|
+
* ceiling caps how far a request is allowed to reach:
|
|
388
|
+
* - `working-set`: synchronous, in-memory only. A miss settles `unavailable` immediately.
|
|
389
|
+
* - `disk`: probe the working set, then local storage; never the network.
|
|
390
|
+
* - `network`: probe the working set, disk, then fetch from peers.
|
|
391
|
+
*
|
|
392
|
+
* `unavailable` is always relative to the requested ceiling (disk-unavailable ≠ network-unavailable).
|
|
393
|
+
*/
|
|
394
|
+
export type RefSource = 'working-set' | 'disk' | 'network';
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* A stateful, closure-aware handle to an in-flight (or settled) reference resolution.
|
|
398
|
+
*
|
|
399
|
+
* `ready` means the entity is FULLY USABLE: its own body and its strong-dependency closure are all
|
|
400
|
+
* materialized. The body-vs-closure split is internal; `requesting` transparently covers "a
|
|
401
|
+
* dependency is still loading".
|
|
402
|
+
*/
|
|
403
|
+
export interface RefResolverRequest {
|
|
404
|
+
/**
|
|
405
|
+
* `pending` is a one-way entry state (never re-entered). `requesting` means the body and/or
|
|
406
|
+
* closure is still loading. `ready` means fully usable. `unavailable` means unreachable at the
|
|
407
|
+
* requested ceiling.
|
|
408
|
+
*/
|
|
409
|
+
readonly state: 'pending' | 'requesting' | 'ready' | 'unavailable';
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Fires (deferred to a microtask) whenever {@link state} changes.
|
|
413
|
+
*/
|
|
414
|
+
readonly stateChanged: Event<void>;
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Synchronous snapshot of the resolved entity; defined iff `state === 'ready'`.
|
|
418
|
+
*/
|
|
419
|
+
getResult(): AnyProperties | undefined;
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Settles when `state ∈ {ready, unavailable}`.
|
|
423
|
+
*/
|
|
424
|
+
wait(): Promise<AnyProperties | undefined>;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Decrements the refcount on the shared load op(s); cancels the underlying IO at zero.
|
|
428
|
+
*/
|
|
429
|
+
abort(): void;
|
|
430
|
+
}
|
|
431
|
+
|
|
329
432
|
export interface RefResolver {
|
|
433
|
+
/**
|
|
434
|
+
* Resolve a reference, returning a stateful handle. `source` is a required ceiling; cheaper
|
|
435
|
+
* tiers are always probed first.
|
|
436
|
+
*/
|
|
437
|
+
resolve(uri: URI.URI, options: { source: RefSource }): RefResolverRequest;
|
|
438
|
+
|
|
330
439
|
/**
|
|
331
440
|
* Resolve ref synchronously from the objects in the working set.
|
|
332
441
|
*
|
|
333
|
-
* @param
|
|
442
|
+
* @param uri
|
|
334
443
|
* @param load If true the resolver should attempt to load the object from disk.
|
|
335
444
|
* @param onLoad Callback to call when the object is loaded.
|
|
445
|
+
* @deprecated Use {@link resolve} with `{ source: 'working-set' }`. Removed in Task 11.
|
|
336
446
|
*/
|
|
337
|
-
resolveSync(
|
|
447
|
+
resolveSync(uri: URI.URI, load: boolean, onLoad?: () => void): AnyProperties | undefined;
|
|
338
448
|
|
|
339
449
|
/**
|
|
340
450
|
* Resolver ref asynchronously.
|
|
451
|
+
* @deprecated Use {@link resolve} with `{ source: 'network' }`. Removed in Task 11.
|
|
452
|
+
*/
|
|
453
|
+
resolveLegacy(uri: URI.URI): Promise<AnyProperties | undefined>;
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @deprecated Use {@link resolve} + `Type.getSchema`. Removed in Task 11.
|
|
341
457
|
*/
|
|
342
|
-
|
|
458
|
+
resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined>;
|
|
343
459
|
|
|
344
|
-
|
|
345
|
-
|
|
460
|
+
/**
|
|
461
|
+
* Resolve the source `Type.AnyEntity` entity for a type URI. Used by
|
|
462
|
+
* deserialization paths (`Obj.fromJSON`) to set the back-reference accessed
|
|
463
|
+
* via `Obj.getType` / `Entity.getType`. Optional — resolvers that only
|
|
464
|
+
* carry raw schemas may leave this unimplemented; the deserializer falls
|
|
465
|
+
* back to leaving the type entity unset.
|
|
466
|
+
* @deprecated Use {@link resolve}. Removed in Task 11.
|
|
467
|
+
*/
|
|
468
|
+
resolveType?(uri: URI.URI): Promise<unknown | undefined>;
|
|
346
469
|
}
|
|
347
470
|
|
|
471
|
+
/**
|
|
472
|
+
* A settled {@link RefResolverRequest} with a fixed `state` and `result`, used by resolvers
|
|
473
|
+
* whose backends are fully synchronous (e.g. {@link StaticRefResolver}).
|
|
474
|
+
*/
|
|
475
|
+
export const makeSettledRequest = (
|
|
476
|
+
state: RefResolverRequest['state'],
|
|
477
|
+
result: AnyProperties | undefined,
|
|
478
|
+
): RefResolverRequest => ({
|
|
479
|
+
state,
|
|
480
|
+
stateChanged: new Event<void>(),
|
|
481
|
+
getResult: () => (state === 'ready' ? result : undefined),
|
|
482
|
+
wait: async () => (state === 'ready' ? result : undefined),
|
|
483
|
+
abort: () => {},
|
|
484
|
+
});
|
|
485
|
+
|
|
348
486
|
export class RefImpl<T> implements Ref<T> {
|
|
349
|
-
#
|
|
487
|
+
#uri: URI.URI;
|
|
350
488
|
#resolver?: RefResolver = undefined;
|
|
351
489
|
#resolved = new Event<void>();
|
|
352
490
|
|
|
@@ -363,16 +501,16 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
363
501
|
this.#resolved.emit();
|
|
364
502
|
};
|
|
365
503
|
|
|
366
|
-
constructor(
|
|
367
|
-
this.#
|
|
504
|
+
constructor(uri: URI.URI, target?: T) {
|
|
505
|
+
this.#uri = uri;
|
|
368
506
|
this.#target = target;
|
|
369
507
|
}
|
|
370
508
|
|
|
371
509
|
/**
|
|
372
510
|
* @inheritdoc
|
|
373
511
|
*/
|
|
374
|
-
get
|
|
375
|
-
return this.#
|
|
512
|
+
get uri(): URI.URI {
|
|
513
|
+
return this.#uri;
|
|
376
514
|
}
|
|
377
515
|
|
|
378
516
|
/**
|
|
@@ -391,7 +529,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
391
529
|
}
|
|
392
530
|
|
|
393
531
|
invariant(this.#resolver, 'Resolver is not set');
|
|
394
|
-
return this.#resolver.resolveSync(this.#
|
|
532
|
+
return this.#resolver.resolveSync(this.#uri, true, this.#resolverCallback) as T | undefined;
|
|
395
533
|
}
|
|
396
534
|
|
|
397
535
|
/**
|
|
@@ -402,7 +540,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
402
540
|
return this.#target;
|
|
403
541
|
}
|
|
404
542
|
invariant(this.#resolver, 'Resolver is not set');
|
|
405
|
-
const obj = await this.#resolver.
|
|
543
|
+
const obj = await this.#resolver.resolveLegacy(this.#uri);
|
|
406
544
|
if (obj == null) {
|
|
407
545
|
throw new Error('Object not found');
|
|
408
546
|
}
|
|
@@ -417,7 +555,14 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
417
555
|
return this.#target;
|
|
418
556
|
}
|
|
419
557
|
invariant(this.#resolver, 'Resolver is not set');
|
|
420
|
-
return (await this.#resolver.
|
|
558
|
+
return (await this.#resolver.resolveLegacy(this.#uri)) as T | undefined;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @inheritdoc
|
|
563
|
+
*/
|
|
564
|
+
onResolved(callback: () => void): () => void {
|
|
565
|
+
return this.#resolved.on(callback);
|
|
421
566
|
}
|
|
422
567
|
|
|
423
568
|
/**
|
|
@@ -426,14 +571,14 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
426
571
|
* Clones the reference object.
|
|
427
572
|
*/
|
|
428
573
|
noInline(): RefImpl<T> {
|
|
429
|
-
const ref = new RefImpl<T>(this.#
|
|
574
|
+
const ref = new RefImpl<T>(this.#uri, undefined);
|
|
430
575
|
ref.#resolver = this.#resolver;
|
|
431
576
|
return ref;
|
|
432
577
|
}
|
|
433
578
|
|
|
434
579
|
encode(): EncodedReference {
|
|
435
580
|
return {
|
|
436
|
-
'/': this.#
|
|
581
|
+
'/': this.#uri,
|
|
437
582
|
...(this.#target ? { target: this.#target } : {}),
|
|
438
583
|
};
|
|
439
584
|
}
|
|
@@ -453,7 +598,7 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
453
598
|
return `Ref(${this.#target.toString()})`;
|
|
454
599
|
}
|
|
455
600
|
|
|
456
|
-
return `Ref(${this.#
|
|
601
|
+
return `Ref(${this.#uri.toString()})`;
|
|
457
602
|
}
|
|
458
603
|
|
|
459
604
|
[inspectCustom]: CustomInspectFunction = (depth, options, inspect) => {
|
|
@@ -469,12 +614,16 @@ export class RefImpl<T> implements Ref<T> {
|
|
|
469
614
|
* so without this, each access would create a separate cache entry.
|
|
470
615
|
*/
|
|
471
616
|
[Hash.symbol](): number {
|
|
472
|
-
return Hash.hash(this.#
|
|
617
|
+
return Hash.hash(this.#uri.toString());
|
|
473
618
|
}
|
|
474
619
|
|
|
475
620
|
/** Effect Equal trait. See {@link Hash.symbol} for rationale. */
|
|
476
621
|
[Equal.symbol](that: Equal.Equal): boolean {
|
|
477
|
-
return that instanceof RefImpl && this.#
|
|
622
|
+
return that instanceof RefImpl && this.#uri === that.uri;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
get atom(): Atom.Atom<T | undefined> {
|
|
626
|
+
return RefAtoms.refSimpleFamily(this);
|
|
478
627
|
}
|
|
479
628
|
|
|
480
629
|
/**
|
|
@@ -521,8 +670,8 @@ const refVariance: Ref<any>[typeof RefTypeId] = {
|
|
|
521
670
|
};
|
|
522
671
|
|
|
523
672
|
export const refFromEncodedReference = (encodedReference: EncodedReference, resolver?: RefResolver): Ref<any> => {
|
|
524
|
-
const
|
|
525
|
-
const ref = new RefImpl(
|
|
673
|
+
const uri = EncodedReference.toURI(encodedReference);
|
|
674
|
+
const ref = new RefImpl(uri);
|
|
526
675
|
|
|
527
676
|
// TODO(dmaretskyi): Handle inline target in the encoded reference.
|
|
528
677
|
|
|
@@ -533,40 +682,46 @@ export const refFromEncodedReference = (encodedReference: EncodedReference, reso
|
|
|
533
682
|
};
|
|
534
683
|
|
|
535
684
|
export class StaticRefResolver implements RefResolver {
|
|
536
|
-
public objects = new Map<
|
|
537
|
-
public schemas = new Map<
|
|
685
|
+
public objects = new Map<EntityId, AnyProperties>();
|
|
686
|
+
public schemas = new Map<URI.URI, Schema.Schema.AnyNoContext>();
|
|
538
687
|
|
|
539
688
|
addObject(obj: AnyProperties): this {
|
|
540
689
|
this.objects.set(obj.id, obj);
|
|
541
690
|
return this;
|
|
542
691
|
}
|
|
543
692
|
|
|
544
|
-
addSchema(
|
|
545
|
-
const
|
|
546
|
-
invariant(
|
|
547
|
-
|
|
693
|
+
addSchema(input: Type.AnyEntity): this {
|
|
694
|
+
const schema = getStaticTypeSchema(input);
|
|
695
|
+
invariant(schema, 'Type entity is missing its source schema');
|
|
696
|
+
const uri = getSchemaURI(schema);
|
|
697
|
+
invariant(uri, 'Schema has no URI');
|
|
698
|
+
this.schemas.set(uri, schema);
|
|
548
699
|
return this;
|
|
549
700
|
}
|
|
550
701
|
|
|
551
|
-
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
702
|
+
resolve(uri: URI.URI, _options: { source: RefSource }): RefResolverRequest {
|
|
703
|
+
const obj = this.#lookup(uri);
|
|
704
|
+
return makeSettledRequest(obj ? 'ready' : 'unavailable', obj);
|
|
705
|
+
}
|
|
556
706
|
|
|
557
|
-
|
|
707
|
+
resolveSync(uri: URI.URI, _load: boolean, _onLoad?: () => void): AnyProperties | undefined {
|
|
708
|
+
return this.#lookup(uri);
|
|
558
709
|
}
|
|
559
710
|
|
|
560
|
-
async
|
|
561
|
-
|
|
711
|
+
async resolveLegacy(uri: URI.URI): Promise<AnyProperties | undefined> {
|
|
712
|
+
return this.#lookup(uri);
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
async resolveSchema(uri: URI.URI): Promise<Schema.Schema.AnyNoContext | undefined> {
|
|
716
|
+
return this.schemas.get(uri);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
#lookup(uri: URI.URI): AnyProperties | undefined {
|
|
720
|
+
const echoUri = EID.tryParse(uri);
|
|
721
|
+
const id = echoUri ? EID.getEntityId(echoUri) : undefined;
|
|
562
722
|
if (id == null) {
|
|
563
723
|
return undefined;
|
|
564
724
|
}
|
|
565
|
-
|
|
566
725
|
return this.objects.get(id);
|
|
567
726
|
}
|
|
568
|
-
|
|
569
|
-
async resolveSchema(dxn: DXN): Promise<Schema.Schema.AnyNoContext | undefined> {
|
|
570
|
-
return this.schemas.get(dxn.toString());
|
|
571
|
-
}
|
|
572
727
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { EID, type SpaceId, type URI } from '@dxos/keys';
|
|
6
|
+
|
|
7
|
+
import { EntityKind } from '../common/types/entity';
|
|
8
|
+
import { RelationSourceDXNId, RelationTargetDXNId } from '../common/types/model-symbols';
|
|
9
|
+
import { ParentId, TypeId } from '../common/types/typename';
|
|
10
|
+
import { getObjectEchoUri } from '../Entity/util';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Normalized view of the references that make up an entity's strong-dependency set, store-agnostic
|
|
14
|
+
* so it can be filled from an {@link ObjectCore} (db) or a decoded entity (queue item / snapshot).
|
|
15
|
+
*/
|
|
16
|
+
export interface StrongDepRefs {
|
|
17
|
+
/** Entity kind — relations additionally depend on their source/target. */
|
|
18
|
+
kind: EntityKind;
|
|
19
|
+
/** Type reference URI (`echo:` for a persisted stored schema, `dxn:` for a static/registry type). */
|
|
20
|
+
type?: URI.URI;
|
|
21
|
+
/** Relation source reference URI. */
|
|
22
|
+
source?: URI.URI;
|
|
23
|
+
/** Relation target reference URI. */
|
|
24
|
+
target?: URI.URI;
|
|
25
|
+
/** Parent reference URI. */
|
|
26
|
+
parent?: URI.URI;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Direct strong-dependency URIs of an entity: the schema (only when stored as an object), the
|
|
31
|
+
* relation source/target, and the parent. Returns URIs (cross-space `echo:` EIDs and queue-item
|
|
32
|
+
* EIDs included); a persisted schema is an `echo:` URI, a static/registry type is a `dxn:` URI.
|
|
33
|
+
*
|
|
34
|
+
* A static/registry type (`dxn:`) is intentionally NOT a strong dep: it is always synchronously
|
|
35
|
+
* available through the registry, so gating on it would needlessly delay surfacing. Only a
|
|
36
|
+
* persisted (db-backed) schema, addressed by an `echo:` URI, must load before its instances.
|
|
37
|
+
*/
|
|
38
|
+
export const getStrongDependencyUris = (refs: StrongDepRefs, owningSpaceId?: SpaceId): URI.URI[] => {
|
|
39
|
+
const res: URI.URI[] = [];
|
|
40
|
+
|
|
41
|
+
if (refs.type != null && EID.tryParse(refs.type) != null) {
|
|
42
|
+
res.push(qualifyToSpace(refs.type, owningSpaceId));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (refs.kind === EntityKind.Relation) {
|
|
46
|
+
if (refs.source != null) {
|
|
47
|
+
res.push(qualifyToSpace(refs.source, owningSpaceId));
|
|
48
|
+
}
|
|
49
|
+
if (refs.target != null) {
|
|
50
|
+
res.push(qualifyToSpace(refs.target, owningSpaceId));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (refs.parent != null) {
|
|
55
|
+
res.push(qualifyToSpace(refs.parent, owningSpaceId));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return res;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Qualifies a space-less (relative) `echo:` dependency URI with the space of the entity that owns it.
|
|
63
|
+
* Same-space references are persisted relative; resolution needs them absolute to route to a single
|
|
64
|
+
* space. Already-qualified URIs (cross-space) and non-`echo:` URIs (registry `dxn:`) pass through.
|
|
65
|
+
*/
|
|
66
|
+
const qualifyToSpace = (uri: URI.URI, owningSpaceId: SpaceId | undefined): URI.URI => {
|
|
67
|
+
if (owningSpaceId == null) {
|
|
68
|
+
return uri;
|
|
69
|
+
}
|
|
70
|
+
const eid = EID.tryParse(uri);
|
|
71
|
+
if (eid == null || !EID.isLocal(eid)) {
|
|
72
|
+
return uri;
|
|
73
|
+
}
|
|
74
|
+
const entityId = EID.getEntityId(eid);
|
|
75
|
+
return entityId != null ? EID.make({ spaceId: owningSpaceId, entityId }) : uri;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Direct strong-dependency URIs of a live (decoded) entity — a queue item, cross-space proxy, or
|
|
80
|
+
* snapshot. Reads the reference URIs off the entity's hidden model symbols. ECHO db cores compute
|
|
81
|
+
* the same set from their raw encoded references via {@link getStrongDependencyUris}.
|
|
82
|
+
*/
|
|
83
|
+
export const getStrongDependencies = (entity: unknown): URI.URI[] => {
|
|
84
|
+
if (entity == null || typeof entity !== 'object') {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const props = entity as Record<symbol, unknown>;
|
|
88
|
+
const kind =
|
|
89
|
+
props[RelationSourceDXNId] != null || props[RelationTargetDXNId] != null ? EntityKind.Relation : EntityKind.Object;
|
|
90
|
+
const parent = props[ParentId];
|
|
91
|
+
|
|
92
|
+
// The entity's own space qualifies any relative dependency URIs it carries.
|
|
93
|
+
const selfUri = getObjectEchoUri(entity);
|
|
94
|
+
const owningSpaceId = selfUri != null ? EID.getSpaceId(selfUri) : undefined;
|
|
95
|
+
|
|
96
|
+
return getStrongDependencyUris(
|
|
97
|
+
{
|
|
98
|
+
kind,
|
|
99
|
+
type: typeof props[TypeId] === 'string' ? (props[TypeId] as URI.URI) : undefined,
|
|
100
|
+
source: props[RelationSourceDXNId] as URI.URI | undefined,
|
|
101
|
+
target: props[RelationTargetDXNId] as URI.URI | undefined,
|
|
102
|
+
// A parent is held as the resolved entity; derive its absolute URI for the dependency edge.
|
|
103
|
+
parent: parent != null ? getObjectEchoUri(parent) : undefined,
|
|
104
|
+
},
|
|
105
|
+
owningSpaceId,
|
|
106
|
+
);
|
|
107
|
+
};
|