@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/Entity.test.ts
CHANGED
|
@@ -4,19 +4,129 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import * as Entity from './Entity';
|
|
8
8
|
import * as Obj from './Obj';
|
|
9
9
|
import * as Relation from './Relation';
|
|
10
10
|
import { TestSchema } from './testing';
|
|
11
|
+
import * as Type from './Type';
|
|
12
|
+
|
|
13
|
+
const makeObject = () =>
|
|
14
|
+
Obj.make(TestSchema.Person, {
|
|
15
|
+
name: 'Test',
|
|
16
|
+
username: 'test',
|
|
17
|
+
email: 'test@example.com',
|
|
18
|
+
tasks: [],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const makeRelation = (obj: TestSchema.Person) =>
|
|
22
|
+
Relation.make(TestSchema.HasManager, { [Relation.Source]: obj, [Relation.Target]: obj });
|
|
11
23
|
|
|
12
24
|
describe('Entity', () => {
|
|
13
25
|
test('Entity.Unknown accepts any object or relation', () => {
|
|
14
|
-
const obj =
|
|
15
|
-
const rel =
|
|
16
|
-
const doSomething = (entity: Entity.Unknown) =>
|
|
17
|
-
return entity;
|
|
18
|
-
};
|
|
26
|
+
const obj = makeObject();
|
|
27
|
+
const rel = makeRelation(obj);
|
|
28
|
+
const doSomething = (entity: Entity.Unknown) => entity;
|
|
19
29
|
expect(doSomething(obj)).toBe(obj);
|
|
20
30
|
expect(doSomething(rel)).toBe(rel);
|
|
21
31
|
});
|
|
32
|
+
|
|
33
|
+
// `isEntity` is a bare brand check (`[KindId] !== undefined`). All three entity
|
|
34
|
+
// kinds — objects, relations, and type entities — carry the brand, so all three
|
|
35
|
+
// are recognised as entities. (Type entities brand with `EntityKind.Type`.)
|
|
36
|
+
describe('isEntity / isSnapshot', () => {
|
|
37
|
+
test('object instance is an entity', () => {
|
|
38
|
+
const obj = makeObject();
|
|
39
|
+
expect(Entity.isEntity(obj)).toBe(true);
|
|
40
|
+
expect(Entity.isSnapshot(obj)).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('relation instance is an entity', () => {
|
|
44
|
+
const rel = makeRelation(makeObject());
|
|
45
|
+
expect(Entity.isEntity(rel)).toBe(true);
|
|
46
|
+
expect(Entity.isSnapshot(rel)).toBe(false);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('type entity is an entity', () => {
|
|
50
|
+
expect(Entity.isEntity(TestSchema.Person)).toBe(true);
|
|
51
|
+
expect(Entity.isSnapshot(TestSchema.Person)).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('non-entities are rejected', () => {
|
|
55
|
+
expect(Entity.isEntity(null)).toBe(false);
|
|
56
|
+
expect(Entity.isEntity({})).toBe(false);
|
|
57
|
+
expect(Entity.isEntity({ id: 'x' })).toBe(false);
|
|
58
|
+
expect(Entity.isEntity('string')).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Object and relation instances behave identically across the Entity.* accessor
|
|
63
|
+
// surface: these accessors are written for runtime instances and read the
|
|
64
|
+
// instance's identity, type pointer and metadata.
|
|
65
|
+
describe.each([
|
|
66
|
+
['object', () => makeObject(), 'com.example.type.person'],
|
|
67
|
+
['relation', () => makeRelation(makeObject()), 'com.example.type.hasManager'],
|
|
68
|
+
] as const)('instance accessors (%s)', (_label, make, typename) => {
|
|
69
|
+
test('getURI returns an echo URI', () => {
|
|
70
|
+
const entity = make();
|
|
71
|
+
expect(Entity.getURI(entity)).toMatch(/^echo:/);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('getTypename returns the typename', () => {
|
|
75
|
+
expect(Entity.getTypename(make())).toBe(typename);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('getTypeURI returns the type DXN', () => {
|
|
79
|
+
expect(Entity.getTypeURI(make())).toBe(`dxn:${typename}:0.1.0`);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('getType resolves back to the type entity', () => {
|
|
83
|
+
const type = Entity.getType(make());
|
|
84
|
+
expect(type).toBeDefined();
|
|
85
|
+
expect(Type.getTypename(type!)).toBe(typename);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('getMeta returns metadata', () => {
|
|
89
|
+
expect(Entity.getMeta(make())).toBeDefined();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('isDeleted is false for a live entity', () => {
|
|
93
|
+
expect(Entity.isDeleted(make())).toBe(false);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('toJSON serializes the entity', () => {
|
|
97
|
+
const json = Entity.toJSON(make());
|
|
98
|
+
expect(json).toMatchObject({ '@type': expect.stringContaining(typename) });
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Type entities are first-class entities: the Entity.* accessors work on them too.
|
|
103
|
+
// `getURI`/`getTypename` return the type's OWN identity, while `getType`/`getTypeURI`
|
|
104
|
+
// (which mean "the type this entity is an instance of") resolve to the meta-type
|
|
105
|
+
// `Type.Type`.
|
|
106
|
+
describe('type entity', () => {
|
|
107
|
+
test('isEntity / getMeta / isDeleted', () => {
|
|
108
|
+
expect(Entity.isEntity(TestSchema.Person)).toBe(true);
|
|
109
|
+
expect(Entity.getMeta(TestSchema.Person)).toBeDefined();
|
|
110
|
+
expect(Entity.isDeleted(TestSchema.Person)).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('getURI / getTypename return the type entity’s own identity', () => {
|
|
114
|
+
expect(Entity.getURI(TestSchema.Person)).toBe('dxn:com.example.type.person:0.1.0');
|
|
115
|
+
expect(Entity.getTypename(TestSchema.Person)).toBe('com.example.type.person');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('getType / getTypeURI resolve to the meta-type (Type.Type)', () => {
|
|
119
|
+
expect(Entity.getType(TestSchema.Person)).toBe(Type.Type);
|
|
120
|
+
expect(Entity.getTypeURI(TestSchema.Person)).toBe('dxn:org.dxos.type.schema:0.1.0');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('Entity.* and Type.* agree on type identity', () => {
|
|
124
|
+
expect(Entity.getURI(TestSchema.Person)).toBe(Type.getURI(TestSchema.Person));
|
|
125
|
+
expect(Entity.getTypename(TestSchema.Person)).toBe(Type.getTypename(TestSchema.Person));
|
|
126
|
+
expect(Type.isType(TestSchema.Person)).toBe(true);
|
|
127
|
+
expect(Type.isObject(TestSchema.Person)).toBe(true);
|
|
128
|
+
expect(Type.isRelation(TestSchema.HasManager)).toBe(true);
|
|
129
|
+
expect(Type.getVersion(TestSchema.Person)).toBe('0.1.0');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
22
132
|
});
|
package/src/Entity.ts
CHANGED
|
@@ -4,12 +4,17 @@
|
|
|
4
4
|
|
|
5
5
|
// @import-as-namespace
|
|
6
6
|
|
|
7
|
+
import * as Schema from 'effect/Schema';
|
|
8
|
+
|
|
7
9
|
import type { ForeignKey } from '@dxos/echo-protocol';
|
|
8
|
-
import type {
|
|
10
|
+
import type { EntityId, URI } from '@dxos/keys';
|
|
9
11
|
|
|
10
12
|
import * as internal from './internal';
|
|
13
|
+
import * as objInternal from './internal/Obj';
|
|
14
|
+
import type * as Ref from './Ref';
|
|
11
15
|
import type * as Relation from './Relation';
|
|
12
|
-
import type * as
|
|
16
|
+
import type * as Tag from './Tag';
|
|
17
|
+
import * as Type from './Type';
|
|
13
18
|
|
|
14
19
|
// Re-export KindId and SnapshotKindId from internal.
|
|
15
20
|
export const KindId = internal.KindId;
|
|
@@ -31,7 +36,7 @@ export const KindSchema = internal.EntityKindSchema;
|
|
|
31
36
|
*/
|
|
32
37
|
export interface OfKind<K extends Kind> {
|
|
33
38
|
readonly [KindId]: K;
|
|
34
|
-
readonly id:
|
|
39
|
+
readonly id: EntityId;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -39,7 +44,7 @@ export interface OfKind<K extends Kind> {
|
|
|
39
44
|
*/
|
|
40
45
|
export interface SnapshotOfKind<K extends Kind> {
|
|
41
46
|
readonly [SnapshotKindId]: K;
|
|
42
|
-
readonly id:
|
|
47
|
+
readonly id: EntityId;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
/**
|
|
@@ -52,6 +57,27 @@ export type Entity<Props> = OfKind<Kind> & Props;
|
|
|
52
57
|
*/
|
|
53
58
|
export interface Unknown extends OfKind<Kind> {}
|
|
54
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Effect Schema for any ECHO entity (object or relation).
|
|
62
|
+
*
|
|
63
|
+
* Kind-agnostic counterpart to `Obj.Unknown` / `Relation.Unknown` — validates
|
|
64
|
+
* the structural shape (id + properties) without constraining `[KindId]`. Used
|
|
65
|
+
* in operation input schemas that accept any entity flavour (e.g.
|
|
66
|
+
* `Schema.Array(Entity.Unknown)`).
|
|
67
|
+
*
|
|
68
|
+
* The cast bridges the runtime structural schema to the branded `Unknown` type:
|
|
69
|
+
* `[KindId]` is a symbol brand that can't be expressed in a runtime `Struct`,
|
|
70
|
+
* so the entity guarantee is carried at the type level only (same approach as
|
|
71
|
+
* `Obj.Unknown` / `Relation.Unknown`). Unlike those, this is kind-agnostic so it
|
|
72
|
+
* isn't an `UnknownTypeSchema<_, K>` (there's no single `K`) and carries no
|
|
73
|
+
* `TypeAnnotation`.
|
|
74
|
+
*/
|
|
75
|
+
export const Unknown: Schema.Schema<Unknown> = Schema.Struct({
|
|
76
|
+
id: Schema.String,
|
|
77
|
+
}).pipe(
|
|
78
|
+
Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),
|
|
79
|
+
) as unknown as Schema.Schema<Unknown>;
|
|
80
|
+
|
|
55
81
|
/**
|
|
56
82
|
* Snapshot of an Obj or Relation.
|
|
57
83
|
* Branded with SnapshotKindId instead of KindId.
|
|
@@ -80,12 +106,30 @@ export type Properties<T> = Omit<T, 'id' | KindId | Relation.Source | Relation.T
|
|
|
80
106
|
* Check if a value is an ECHO entity (object or relation).
|
|
81
107
|
* Returns `false` for snapshots.
|
|
82
108
|
*/
|
|
83
|
-
export const isEntity
|
|
84
|
-
|
|
85
|
-
|
|
109
|
+
export const isEntity: (value: unknown) => value is Unknown = internal.isEntity;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Test if a value is an instance of a given object or relation type.
|
|
113
|
+
*
|
|
114
|
+
* Kind-agnostic counterpart to `Obj.instanceOf` / `Relation.instanceOf` —
|
|
115
|
+
* use this when the caller's input type is `Type.AnyObj | Type.AnyRelation`.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* // Caller doesn't know whether `type` is object- or relation-kind.
|
|
120
|
+
* const matches = <T extends Type.AnyObj | Type.AnyRelation>(type: T, value: unknown) =>
|
|
121
|
+
* Entity.instanceOf(type, value);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export const instanceOf: {
|
|
125
|
+
<S extends Type.AnyEntity>(schema: S): (value: unknown) => value is Type.InstanceType<S>;
|
|
126
|
+
<S extends Type.AnyEntity>(schema: S, value: unknown): value is Type.InstanceType<S>;
|
|
127
|
+
} = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {
|
|
128
|
+
if (args.length === 1) {
|
|
129
|
+
return (entity: unknown) => internal.isInstanceOf(args[0], entity);
|
|
86
130
|
}
|
|
87
|
-
return (
|
|
88
|
-
};
|
|
131
|
+
return internal.isInstanceOf(args[0], args[1]);
|
|
132
|
+
}) as any;
|
|
89
133
|
|
|
90
134
|
/**
|
|
91
135
|
* Check if a value is an ECHO entity snapshot.
|
|
@@ -123,25 +167,60 @@ export type Meta = typeof Meta;
|
|
|
123
167
|
export type JSON = internal.ObjectJSON;
|
|
124
168
|
|
|
125
169
|
/**
|
|
126
|
-
*
|
|
170
|
+
* Whether the entity is a type-kind entity (a `Type.Type` produced by
|
|
171
|
+
* `Type.makeObject` / `Type.makeRelation`, or a persisted schema). Type entities
|
|
172
|
+
* carry their identity (typename/version) on themselves rather than referencing a
|
|
173
|
+
* separate type, so the accessors below route them through the `Type.*` module.
|
|
174
|
+
*/
|
|
175
|
+
const isTypeEntity = (entity: unknown): boolean => internal.getEntityKindBrand(entity) === internal.EntityKind.Type;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Any value the read accessors operate on: a reactive entity or a snapshot.
|
|
179
|
+
* Type entities (`Type.AnyEntity`) are also accepted — they're first-class
|
|
180
|
+
* entities, and `Unknown`'s kind-agnostic brand already subsumes them.
|
|
127
181
|
*/
|
|
128
|
-
export
|
|
182
|
+
export type AnyInput = Unknown | Snapshot;
|
|
129
183
|
|
|
130
184
|
/**
|
|
131
|
-
* Get the
|
|
185
|
+
* Get the canonical URI of an entity (object, relation, or type). Returns `URI.URI` —
|
|
186
|
+
* an `EID` for object/relation instances and persisted types, or a typename
|
|
187
|
+
* `DXN` for static type entities; narrow with `EID.parse(uri)` or
|
|
188
|
+
* `DXN.tryMake(uri)` at the point of use.
|
|
189
|
+
*
|
|
190
|
+
* @param options.prefer - Controls the URI form (see {@link internal.GetURIOptions}).
|
|
132
191
|
*/
|
|
133
|
-
export const
|
|
192
|
+
export const getURI = (entity: AnyInput, options?: internal.GetURIOptions): URI.URI =>
|
|
193
|
+
isTypeEntity(entity) ? Type.getURI(entity as Type.AnyEntity) : internal.getUri(entity as Unknown, options);
|
|
134
194
|
|
|
135
195
|
/**
|
|
136
|
-
* Get the
|
|
137
|
-
*
|
|
196
|
+
* Get the DXN of an entity's type. For object/relation instances this is the URI
|
|
197
|
+
* of the type they were created from; for a type entity it is the URI of the
|
|
198
|
+
* meta-type ({@link Type.Type}, `dxn:org.dxos.type.schema:0.1.0`).
|
|
138
199
|
*/
|
|
139
|
-
export const
|
|
200
|
+
export const getTypeURI = (entity: AnyInput): URI.URI | undefined =>
|
|
201
|
+
isTypeEntity(entity) ? Type.getURI(Type.Type) : internal.getTypeURI(entity as Unknown);
|
|
140
202
|
|
|
141
203
|
/**
|
|
142
|
-
* Get the
|
|
204
|
+
* Get the type entity (`Type.AnyEntity`) the instance was created from.
|
|
205
|
+
*
|
|
206
|
+
* Returns `undefined` when the entity's type isn't registered in this runtime
|
|
207
|
+
* (e.g. a freshly deserialized snapshot whose type entity hasn't been wired
|
|
208
|
+
* up yet, or an entity loaded from storage before its schema is known). To
|
|
209
|
+
* get the Effect Schema from the returned entity, use `Type.getSchema(...)`.
|
|
210
|
+
*
|
|
211
|
+
* For a type entity, returns the meta-type {@link Type.Type} (a type entity's
|
|
212
|
+
* type is "Type").
|
|
143
213
|
*/
|
|
144
|
-
export const
|
|
214
|
+
export const getType = (entity: AnyInput): Type.AnyEntity | undefined =>
|
|
215
|
+
isTypeEntity(entity) ? Type.Type : (internal.getType(entity) as Type.AnyEntity | undefined);
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Get the typename of an entity's type. For object/relation instances this is the
|
|
219
|
+
* typename of the type they were created from; for a type entity it is the type's
|
|
220
|
+
* own typename (e.g. `com.example.type.person`).
|
|
221
|
+
*/
|
|
222
|
+
export const getTypename = (entity: AnyInput): string | undefined =>
|
|
223
|
+
isTypeEntity(entity) ? Type.getTypename(entity as Type.AnyEntity) : internal.getTypename(entity as Unknown);
|
|
145
224
|
|
|
146
225
|
/**
|
|
147
226
|
* Get the database an entity belongs to.
|
|
@@ -154,9 +233,9 @@ export const getDatabase = (entity: Unknown | Snapshot): any | undefined => inte
|
|
|
154
233
|
* Returns read-only meta when passed a regular entity or snapshot.
|
|
155
234
|
*/
|
|
156
235
|
// TODO(wittjosiah): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.
|
|
157
|
-
export function getMeta(entity: Mutable<Unknown>): internal.
|
|
236
|
+
export function getMeta(entity: Mutable<Unknown>): internal.EntityMeta;
|
|
158
237
|
export function getMeta(entity: Unknown | Snapshot): internal.ReadonlyMeta;
|
|
159
|
-
export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): internal.
|
|
238
|
+
export function getMeta(entity: Unknown | Snapshot | Mutable<Unknown>): internal.EntityMeta | internal.ReadonlyMeta {
|
|
160
239
|
return internal.getMetaChecked(entity);
|
|
161
240
|
}
|
|
162
241
|
|
|
@@ -172,14 +251,31 @@ export const isDeleted = (entity: Unknown | Snapshot): boolean => internal.isDel
|
|
|
172
251
|
|
|
173
252
|
/**
|
|
174
253
|
* Get the label of an entity.
|
|
254
|
+
*
|
|
255
|
+
* @param options.fallback `'typename'` returns the entity's typename when no
|
|
256
|
+
* label is set (e.g. `org.dxos.type.table`).
|
|
257
|
+
*/
|
|
258
|
+
export const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>
|
|
259
|
+
internal.getLabel(entity, options);
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Set the label of an entity.
|
|
263
|
+
* Must be called within an `Entity.update` / `Obj.update` / `Relation.update` callback.
|
|
175
264
|
*/
|
|
176
|
-
export const
|
|
265
|
+
export const setLabel = (entity: Mutable<Unknown>, label: string): void => internal.setLabel(entity, label);
|
|
177
266
|
|
|
178
267
|
/**
|
|
179
268
|
* Get the description of an entity.
|
|
180
269
|
*/
|
|
181
270
|
export const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);
|
|
182
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Get the icon annotation for an entity (object or relation), resolved via its type-level
|
|
274
|
+
* `IconAnnotation`. Returns the full `{ icon, hue }` annotation so callers can use both
|
|
275
|
+
* the phosphor icon name and the suggested colour.
|
|
276
|
+
*/
|
|
277
|
+
export const getIcon = (entity: Unknown | Snapshot): internal.IconAnnotation | undefined => internal.getIcon(entity);
|
|
278
|
+
|
|
183
279
|
/**
|
|
184
280
|
* Convert an entity to its JSON representation.
|
|
185
281
|
*/
|
|
@@ -198,7 +294,7 @@ export const subscribe = (entity: Unknown, callback: () => void): (() => void) =
|
|
|
198
294
|
//
|
|
199
295
|
|
|
200
296
|
/**
|
|
201
|
-
* Used to provide a mutable view of an entity within `Entity.
|
|
297
|
+
* Used to provide a mutable view of an entity within `Entity.update`.
|
|
202
298
|
*/
|
|
203
299
|
export type Mutable<T> = internal.Mutable<T>;
|
|
204
300
|
|
|
@@ -206,7 +302,7 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
206
302
|
* Perform mutations on an entity (object or relation) within a change context.
|
|
207
303
|
*
|
|
208
304
|
* Entities are read-only by default. Mutations are batched and notifications fire
|
|
209
|
-
* when the callback completes. Direct mutations outside of `Entity.
|
|
305
|
+
* when the callback completes. Direct mutations outside of `Entity.update` will throw
|
|
210
306
|
* at runtime.
|
|
211
307
|
*
|
|
212
308
|
* @param entity - The echo entity (object or relation) to mutate.
|
|
@@ -214,30 +310,36 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
214
310
|
*
|
|
215
311
|
* @example
|
|
216
312
|
* ```typescript
|
|
217
|
-
* // Mutate within Entity.
|
|
218
|
-
* Entity.
|
|
313
|
+
* // Mutate within Entity.update
|
|
314
|
+
* Entity.update(entity, (obj) => {
|
|
219
315
|
* obj.name = 'Updated';
|
|
220
316
|
* obj.count = 42;
|
|
221
317
|
* });
|
|
222
318
|
*
|
|
223
319
|
* // Direct mutation throws
|
|
224
|
-
* entity.name = 'Bob'; // Error: Cannot modify outside Entity.
|
|
320
|
+
* entity.name = 'Bob'; // Error: Cannot modify outside Entity.update()
|
|
225
321
|
* ```
|
|
226
322
|
*
|
|
227
|
-
* Note: For type-specific operations, prefer `Obj.
|
|
323
|
+
* Note: For type-specific operations, prefer `Obj.update` or `Relation.update`.
|
|
228
324
|
*/
|
|
229
|
-
export const
|
|
325
|
+
export const update = <T extends Unknown>(entity: T, callback: internal.ChangeCallback<T>): void => {
|
|
230
326
|
internal.change(entity, callback);
|
|
231
327
|
};
|
|
232
328
|
|
|
233
329
|
/**
|
|
234
330
|
* Add a tag to an entity.
|
|
235
|
-
* Must be called within an `Entity.
|
|
331
|
+
* Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
|
|
236
332
|
*/
|
|
237
|
-
export const addTag = (entity: Mutable<Unknown>, tag:
|
|
333
|
+
export const addTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.addTag(entity, tag);
|
|
238
334
|
|
|
239
335
|
/**
|
|
240
336
|
* Remove a tag from an entity.
|
|
241
|
-
* Must be called within an `Entity.
|
|
337
|
+
* Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
|
|
242
338
|
*/
|
|
243
|
-
export const removeTag = (entity: Mutable<Unknown>, tag:
|
|
339
|
+
export const removeTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.removeTag(entity, tag);
|
|
340
|
+
|
|
341
|
+
//
|
|
342
|
+
// Atoms
|
|
343
|
+
//
|
|
344
|
+
|
|
345
|
+
export const atom = objInternal.makeEntity;
|
package/src/Err.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// @import-as-namespace
|
|
6
6
|
|
|
7
7
|
import { BaseError, type BaseErrorOptions } from '@dxos/errors';
|
|
8
|
-
import { type
|
|
8
|
+
import { type URI } from '@dxos/keys';
|
|
9
9
|
|
|
10
10
|
export class SchemaNotFoundError extends BaseError.extend('SchemaNotFoundError', 'Schema not found') {
|
|
11
11
|
constructor(schema: string, options?: BaseErrorOptions) {
|
|
@@ -13,9 +13,9 @@ export class SchemaNotFoundError extends BaseError.extend('SchemaNotFoundError',
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export class
|
|
17
|
-
constructor(
|
|
18
|
-
super({ context: {
|
|
16
|
+
export class EntityNotFoundError extends BaseError.extend('EntityNotFoundError', 'Entity not found') {
|
|
17
|
+
constructor(uri: URI.URI, options?: BaseErrorOptions) {
|
|
18
|
+
super({ context: { uri }, ...options });
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
package/src/Feed.ts
CHANGED
|
@@ -10,7 +10,7 @@ import * as Layer from 'effect/Layer';
|
|
|
10
10
|
import type * as Option from 'effect/Option';
|
|
11
11
|
import * as Schema from 'effect/Schema';
|
|
12
12
|
|
|
13
|
-
import { DXN,
|
|
13
|
+
import { DXN, EID } from '@dxos/keys';
|
|
14
14
|
|
|
15
15
|
import * as Annotation from './Annotation';
|
|
16
16
|
import type * as Entity from './Entity';
|
|
@@ -43,21 +43,15 @@ export const Feed = Schema.Struct({
|
|
|
43
43
|
*/
|
|
44
44
|
namespace: Schema.optional(Schema.Literal('data', 'trace')),
|
|
45
45
|
}).pipe(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}),
|
|
50
|
-
internal.SystemTypeAnnotation.set(true),
|
|
51
|
-
Annotation.IconAnnotation.set({
|
|
52
|
-
icon: 'ph--rows--regular',
|
|
53
|
-
hue: 'yellow',
|
|
54
|
-
}),
|
|
46
|
+
internal.HiddenAnnotation.set(true),
|
|
47
|
+
Annotation.IconAnnotation.set({ icon: 'ph--rows--regular', hue: 'yellow' }),
|
|
48
|
+
Type.makeObject(DXN.make('org.dxos.type.feed', '0.1.0')),
|
|
55
49
|
);
|
|
56
50
|
|
|
57
51
|
/**
|
|
58
52
|
* TypeScript instance type for a Feed object.
|
|
59
53
|
*/
|
|
60
|
-
export
|
|
54
|
+
export type Feed = Type.InstanceType<typeof Feed>;
|
|
61
55
|
|
|
62
56
|
//
|
|
63
57
|
// Types
|
|
@@ -80,6 +74,29 @@ export interface RetentionOptions {
|
|
|
80
74
|
cursor?: string;
|
|
81
75
|
}
|
|
82
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Sync options for a feed.
|
|
79
|
+
*/
|
|
80
|
+
export interface SyncOptions {
|
|
81
|
+
/** Push local changes to the server. Defaults to true. */
|
|
82
|
+
shouldPush?: boolean;
|
|
83
|
+
/** Pull remote changes from the server. Defaults to true. */
|
|
84
|
+
shouldPull?: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Queue replication backlog for a feed namespace.
|
|
89
|
+
* `0` / `0` means caught up on pull and push.
|
|
90
|
+
*/
|
|
91
|
+
export interface SyncState {
|
|
92
|
+
/** Blocks still to pull from remote. */
|
|
93
|
+
blocksToPull: number;
|
|
94
|
+
/** Unpositioned blocks still to push to remote. */
|
|
95
|
+
blocksToPush: number;
|
|
96
|
+
/** Total blocks stored locally for the feed namespace. */
|
|
97
|
+
totalBlocks: number;
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
//
|
|
84
101
|
// Factory
|
|
85
102
|
//
|
|
@@ -96,39 +113,11 @@ export interface RetentionOptions {
|
|
|
96
113
|
export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
|
|
97
114
|
|
|
98
115
|
/**
|
|
99
|
-
*
|
|
100
|
-
* Returns `undefined` when the feed is not stored in a space yet.
|
|
116
|
+
* Returns the feed object's EID when the feed is stored in a space.
|
|
101
117
|
*
|
|
102
118
|
* Used internally by the feed service layer.
|
|
103
119
|
*/
|
|
104
|
-
export const
|
|
105
|
-
const self = Obj.getDXN(feed).asEchoDXN();
|
|
106
|
-
if (!self || !self.spaceId) {
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
return new DXN(DXN.kind.QUEUE, [feed.namespace ?? 'data', self.spaceId, self.echoId]);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Creates a Feed object from a queue DXN, inferring the feed's id and namespace from the DXN parts.
|
|
114
|
-
*
|
|
115
|
-
* The resulting Feed, when added to the same space as the queue, will have a queue DXN
|
|
116
|
-
* equal to the input (see `Feed.getQueueDxn`). Useful when migrating `Ref(Queue)` fields to
|
|
117
|
-
* `Ref(Feed.Feed)`.
|
|
118
|
-
*
|
|
119
|
-
* @remarks Unsafe because the caller must ensure the queue DXN's space matches the database
|
|
120
|
-
* the feed is added to; the feed id is set from the queue id, bypassing id generation.
|
|
121
|
-
*/
|
|
122
|
-
export const unsafeFromQueueDXN = (queueDxn: DXN): Feed => {
|
|
123
|
-
const parts = queueDxn.asQueueDXN();
|
|
124
|
-
if (!parts) {
|
|
125
|
-
throw new Error(`Expected a queue DXN, got: ${queueDxn.toString()}`);
|
|
126
|
-
}
|
|
127
|
-
return Obj.make(Feed, {
|
|
128
|
-
id: parts.queueId as ObjectId,
|
|
129
|
-
namespace: parts.subspaceTag === 'trace' ? 'trace' : undefined,
|
|
130
|
-
});
|
|
131
|
-
};
|
|
120
|
+
export const getQueueUri = (feed: Feed): EID.EID | undefined => EID.tryParse(Obj.getURI(feed));
|
|
132
121
|
|
|
133
122
|
//
|
|
134
123
|
// Service
|
|
@@ -150,7 +139,6 @@ export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
|
|
|
150
139
|
/**
|
|
151
140
|
* Removes items from a feed by ID.
|
|
152
141
|
*/
|
|
153
|
-
// TODO(dmaretskyi): Change type to ObjectId.
|
|
154
142
|
remove(feed: Feed, ids: string[]): Promise<void>;
|
|
155
143
|
|
|
156
144
|
/**
|
|
@@ -160,6 +148,16 @@ export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
|
|
|
160
148
|
<Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;
|
|
161
149
|
<F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;
|
|
162
150
|
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Syncs the feed with the server.
|
|
154
|
+
*/
|
|
155
|
+
sync(feed: Feed, options?: SyncOptions): Promise<void>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Returns queue replication backlog for the feed's namespace.
|
|
159
|
+
*/
|
|
160
|
+
getSyncState(feed: Feed): Promise<SyncState>;
|
|
163
161
|
}
|
|
164
162
|
>() {}
|
|
165
163
|
|
|
@@ -173,6 +171,21 @@ export type Service = FeedService;
|
|
|
173
171
|
*/
|
|
174
172
|
export const Service = FeedService;
|
|
175
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Effect context service that holds the current feed for a scoped operation.
|
|
176
|
+
*
|
|
177
|
+
* @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures
|
|
178
|
+
* over hiding it behind a context service.
|
|
179
|
+
*/
|
|
180
|
+
export class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<
|
|
181
|
+
ContextFeedService,
|
|
182
|
+
{
|
|
183
|
+
readonly feed: Feed;
|
|
184
|
+
}
|
|
185
|
+
>() {
|
|
186
|
+
static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });
|
|
187
|
+
}
|
|
188
|
+
|
|
176
189
|
/**
|
|
177
190
|
* Layer that provides a Feed service that throws when accessed.
|
|
178
191
|
* Useful as a default layer when no feed service is available.
|
|
@@ -187,6 +200,12 @@ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService,
|
|
|
187
200
|
query: () => {
|
|
188
201
|
throw new Error('Feed.FeedService not available');
|
|
189
202
|
},
|
|
203
|
+
sync: () => {
|
|
204
|
+
throw new Error('Feed.FeedService not available');
|
|
205
|
+
},
|
|
206
|
+
getSyncState: () => {
|
|
207
|
+
throw new Error('Feed.FeedService not available');
|
|
208
|
+
},
|
|
190
209
|
} as Context.Tag.Service<FeedService>);
|
|
191
210
|
|
|
192
211
|
//
|
|
@@ -262,6 +281,35 @@ export const runQuery: {
|
|
|
262
281
|
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
263
282
|
query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
|
|
264
283
|
|
|
284
|
+
/**
|
|
285
|
+
* Syncs the feed with the server.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* yield* Feed.sync(feed);
|
|
290
|
+
* yield* Feed.sync(feed, { shouldPush: false });
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>
|
|
294
|
+
Effect.gen(function* () {
|
|
295
|
+
const service = yield* FeedService;
|
|
296
|
+
yield* Effect.promise(() => service.sync(feed, options));
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Returns queue replication backlog for the feed's namespace.
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```ts
|
|
304
|
+
* const { blocksToPull, blocksToPush } = yield* Feed.getSyncState(feed);
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
export const getSyncState = (feed: Feed): Effect.Effect<SyncState, never, FeedService> =>
|
|
308
|
+
Effect.gen(function* () {
|
|
309
|
+
const service = yield* FeedService;
|
|
310
|
+
return yield* Effect.promise(() => service.getSyncState(feed));
|
|
311
|
+
});
|
|
312
|
+
|
|
265
313
|
/**
|
|
266
314
|
* Creates a cursor for iterating over feed items.
|
|
267
315
|
* Currently stubbed — cursor operations are not yet implemented.
|
|
@@ -292,13 +340,13 @@ export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<
|
|
|
292
340
|
|
|
293
341
|
/**
|
|
294
342
|
* Sets the local retention policy for a feed.
|
|
295
|
-
* Currently stubbed —
|
|
343
|
+
* Currently stubbed — feeds do not yet support retention.
|
|
296
344
|
*
|
|
297
345
|
* @example
|
|
298
346
|
* ```ts
|
|
299
347
|
* yield* Feed.setRetention(feed, { count: 1000 });
|
|
300
348
|
* ```
|
|
301
349
|
*/
|
|
302
|
-
// TODO(
|
|
350
|
+
// TODO(dmaretskyi): Implement when feed retention is supported.
|
|
303
351
|
export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
|
|
304
352
|
Effect.void;
|