@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
|
@@ -6,18 +6,21 @@ import type { ForeignKey } from '@dxos/echo-protocol';
|
|
|
6
6
|
import { assertArgument, invariant } from '@dxos/invariant';
|
|
7
7
|
import type { DeepReadonly } from '@dxos/util';
|
|
8
8
|
|
|
9
|
+
import type * as Tag from '../../../Tag';
|
|
10
|
+
import type { Ref } from '../../Ref/ref';
|
|
9
11
|
import { type Mutable } from '../proxy';
|
|
10
|
-
import { type AnyProperties
|
|
12
|
+
import { type AnyProperties } from '../types';
|
|
13
|
+
import { type EntityMeta, getMeta as getMeta$ } from '../types/meta';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
|
-
* Deeply read-only version of
|
|
16
|
+
* Deeply read-only version of EntityMeta.
|
|
14
17
|
*/
|
|
15
|
-
export type ReadonlyMeta = DeepReadonly<
|
|
18
|
+
export type ReadonlyMeta = DeepReadonly<EntityMeta>;
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* Mutable meta type received in meta mutation callbacks.
|
|
19
22
|
*/
|
|
20
|
-
export type Meta = Mutable<
|
|
23
|
+
export type Meta = Mutable<EntityMeta>;
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* Get the metadata for an entity with validation.
|
|
@@ -48,7 +51,7 @@ export const getKeys = (entity: AnyProperties, source: string): ForeignKey[] =>
|
|
|
48
51
|
|
|
49
52
|
/**
|
|
50
53
|
* Delete all keys from the entity for the specified source.
|
|
51
|
-
* Must be called within an Obj.
|
|
54
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
52
55
|
*/
|
|
53
56
|
export const deleteKeys = (entity: Mutable<AnyProperties>, source: string) => {
|
|
54
57
|
const meta = getMetaChecked(entity);
|
|
@@ -61,26 +64,25 @@ export const deleteKeys = (entity: Mutable<AnyProperties>, source: string) => {
|
|
|
61
64
|
};
|
|
62
65
|
|
|
63
66
|
/**
|
|
64
|
-
* Add a tag to the entity.
|
|
65
|
-
* Must be called within an Obj.
|
|
67
|
+
* Add a tag (a reference to a {@link Tag} object) to the entity. Idempotent.
|
|
68
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
66
69
|
*/
|
|
67
|
-
export const addTag = (entity: Mutable<AnyProperties>, tag:
|
|
70
|
+
export const addTag = (entity: Mutable<AnyProperties>, tag: Ref<Tag.Tag>) => {
|
|
68
71
|
const meta = getMetaChecked(entity);
|
|
69
|
-
|
|
70
|
-
meta.tags.
|
|
72
|
+
// Two refs to the same target are not `===`; dedupe by URI.
|
|
73
|
+
if (!meta.tags.some((existing) => existing.uri === tag.uri)) {
|
|
74
|
+
meta.tags.push(tag);
|
|
75
|
+
}
|
|
71
76
|
};
|
|
72
77
|
|
|
73
78
|
/**
|
|
74
|
-
* Remove a tag from the entity.
|
|
75
|
-
* Must be called within an Obj.
|
|
79
|
+
* Remove a tag (a reference to a {@link Tag} object) from the entity. No-op when not present.
|
|
80
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
76
81
|
*/
|
|
77
|
-
export const removeTag = (entity: Mutable<AnyProperties>, tag:
|
|
82
|
+
export const removeTag = (entity: Mutable<AnyProperties>, tag: Ref<Tag.Tag>) => {
|
|
78
83
|
const meta = getMetaChecked(entity);
|
|
79
|
-
if (!meta.tags) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
84
|
for (let i = 0; i < meta.tags.length; i++) {
|
|
83
|
-
if (meta.tags[i] === tag) {
|
|
85
|
+
if (meta.tags[i].uri === tag.uri) {
|
|
84
86
|
meta.tags.splice(i, 1);
|
|
85
87
|
i--;
|
|
86
88
|
}
|
|
@@ -35,7 +35,7 @@ const pendingOwnerNotifications = new Set<object>();
|
|
|
35
35
|
/**
|
|
36
36
|
* Enter a change context for the given key.
|
|
37
37
|
* While in a change context, mutations are allowed on the associated object.
|
|
38
|
-
* Nested Obj.
|
|
38
|
+
* Nested Obj.update calls are not supported.
|
|
39
39
|
*
|
|
40
40
|
* @param key - The key to enter the change context for (target object or ObjectCore).
|
|
41
41
|
* @returns A cleanup function that exits the change context.
|
|
@@ -4,22 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, test } from 'vitest';
|
|
6
6
|
|
|
7
|
+
import { URI } from '@dxos/keys';
|
|
8
|
+
|
|
7
9
|
import * as Obj from '../../../Obj';
|
|
10
|
+
import * as Ref from '../../../Ref';
|
|
8
11
|
import * as Relation from '../../../Relation';
|
|
9
12
|
import { TestSchema } from '../../../testing';
|
|
10
13
|
|
|
14
|
+
// Tags are stored as `Ref<Tag>`; build refs from synthetic URIs and compare by `.uri`.
|
|
15
|
+
const tagRef = (id: string): Ref.Ref<any> => Ref.fromURI(URI.make(`echo://BBBBBBBBBBBBBBBBBBBBBBBBBB/${id}`));
|
|
16
|
+
const tagUris = (entity: Obj.Unknown | Relation.Unknown): string[] =>
|
|
17
|
+
Obj.getMeta(entity as Obj.Unknown).tags.map((tag) => tag.uri);
|
|
18
|
+
|
|
11
19
|
/**
|
|
12
|
-
* Tests for Obj.
|
|
20
|
+
* Tests for Obj.update context enforcement and mutator type safety.
|
|
13
21
|
*
|
|
14
22
|
* These tests verify:
|
|
15
23
|
* 1. Mutator functions require Mutable<T> at compile-time.
|
|
16
|
-
* 2. getMeta returns ReadonlyMeta outside change callbacks and
|
|
17
|
-
* 3. Mutations outside Obj.
|
|
24
|
+
* 2. getMeta returns ReadonlyMeta outside change callbacks and EntityMeta inside.
|
|
25
|
+
* 3. Mutations outside Obj.update throw at runtime.
|
|
18
26
|
* 4. Nested object/property mutations work correctly.
|
|
19
27
|
* 5. Array mutations (push, pop, splice) require change context.
|
|
20
28
|
* 6. Property delete requires change context.
|
|
21
29
|
*/
|
|
22
|
-
describe('Obj.
|
|
30
|
+
describe('Obj.update enforcement', () => {
|
|
23
31
|
describe('compile-time and runtime safety', () => {
|
|
24
32
|
test('direct property mutation outside change throws', ({ expect }) => {
|
|
25
33
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
@@ -28,7 +36,7 @@ describe('Obj.change enforcement', () => {
|
|
|
28
36
|
expect(() => {
|
|
29
37
|
// @ts-expect-error Testing runtime error for readonly property mutation.
|
|
30
38
|
obj.name = 'New Name';
|
|
31
|
-
}).toThrow(/outside of Obj.
|
|
39
|
+
}).toThrow(/outside of Obj.update/);
|
|
32
40
|
});
|
|
33
41
|
|
|
34
42
|
test('Obj.setValue outside change throws', ({ expect }) => {
|
|
@@ -36,7 +44,7 @@ describe('Obj.change enforcement', () => {
|
|
|
36
44
|
|
|
37
45
|
// No compile-time error: TypeScript's structural typing allows readonly objects
|
|
38
46
|
// to be passed to Mutable<T> parameters. Enforcement is runtime-only.
|
|
39
|
-
expect(() => Obj.setValue(obj, ['name'], 'value')).toThrow(/outside of Obj.
|
|
47
|
+
expect(() => Obj.setValue(obj, ['name'], 'value')).toThrow(/outside of Obj.update/);
|
|
40
48
|
});
|
|
41
49
|
|
|
42
50
|
test('Obj.addTag outside change throws', ({ expect }) => {
|
|
@@ -44,7 +52,7 @@ describe('Obj.change enforcement', () => {
|
|
|
44
52
|
|
|
45
53
|
// No compile-time error: TypeScript's structural typing allows readonly objects
|
|
46
54
|
// to be passed to Mutable<T> parameters. Enforcement is runtime-only.
|
|
47
|
-
expect(() => Obj.addTag(obj, 'tag')).toThrow(/outside of Obj.
|
|
55
|
+
expect(() => Obj.addTag(obj, tagRef('tag'))).toThrow(/outside of Obj.update/);
|
|
48
56
|
});
|
|
49
57
|
|
|
50
58
|
test('getMeta mutation outside change throws', ({ expect }) => {
|
|
@@ -52,23 +60,23 @@ describe('Obj.change enforcement', () => {
|
|
|
52
60
|
const meta = Obj.getMeta(obj);
|
|
53
61
|
|
|
54
62
|
// Runtime errors for direct meta mutations.
|
|
55
|
-
expect(() => ((meta as any).keys = [])).toThrow(/outside of Obj.
|
|
56
|
-
expect(() => ((meta as any).tags = ['tag'])).toThrow(/outside of Obj.
|
|
63
|
+
expect(() => ((meta as any).keys = [])).toThrow(/outside of Obj.update/);
|
|
64
|
+
expect(() => ((meta as any).tags = [tagRef('tag')])).toThrow(/outside of Obj.update/);
|
|
57
65
|
});
|
|
58
66
|
|
|
59
|
-
test('getMeta returns mutable
|
|
67
|
+
test('getMeta returns mutable EntityMeta inside change callback', ({ expect }) => {
|
|
60
68
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
61
69
|
|
|
62
|
-
Obj.
|
|
70
|
+
Obj.update(obj, (obj) => {
|
|
63
71
|
const meta = Obj.getMeta(obj);
|
|
64
72
|
|
|
65
|
-
// These should compile without errors because meta is
|
|
73
|
+
// These should compile without errors because meta is EntityMeta (mutable).
|
|
66
74
|
meta.keys = [];
|
|
67
|
-
meta.tags = ['tag'];
|
|
75
|
+
meta.tags = [tagRef('tag')];
|
|
68
76
|
meta.keys.push({ source: 'test', id: '123' });
|
|
69
77
|
});
|
|
70
78
|
|
|
71
|
-
expect(
|
|
79
|
+
expect(tagUris(obj)).toEqual([tagRef('tag').uri]);
|
|
72
80
|
expect(Obj.getMeta(obj).keys).toHaveLength(1);
|
|
73
81
|
});
|
|
74
82
|
|
|
@@ -76,13 +84,13 @@ describe('Obj.change enforcement', () => {
|
|
|
76
84
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
77
85
|
|
|
78
86
|
// These should compile without errors inside change callback.
|
|
79
|
-
Obj.
|
|
80
|
-
Obj.addTag(obj, 'my-tag');
|
|
87
|
+
Obj.update(obj, (obj) => {
|
|
88
|
+
Obj.addTag(obj, tagRef('my-tag'));
|
|
81
89
|
Obj.setValue(obj, ['name'], 'Updated');
|
|
82
90
|
});
|
|
83
91
|
|
|
84
92
|
expect(obj.name).toBe('Updated');
|
|
85
|
-
expect(
|
|
93
|
+
expect(tagUris(obj)).toContain(tagRef('my-tag').uri);
|
|
86
94
|
});
|
|
87
95
|
|
|
88
96
|
test('Relation property mutation outside change throws', ({ expect }) => {
|
|
@@ -97,7 +105,7 @@ describe('Obj.change enforcement', () => {
|
|
|
97
105
|
expect(() => {
|
|
98
106
|
// @ts-expect-error Testing runtime error for readonly property mutation.
|
|
99
107
|
rel.title = 'Manager';
|
|
100
|
-
}).toThrow(/outside of Obj.
|
|
108
|
+
}).toThrow(/outside of Obj.update/);
|
|
101
109
|
});
|
|
102
110
|
|
|
103
111
|
test('Relation.addTag outside change throws', ({ expect }) => {
|
|
@@ -110,7 +118,7 @@ describe('Obj.change enforcement', () => {
|
|
|
110
118
|
|
|
111
119
|
// No compile-time error: TypeScript's structural typing allows readonly objects
|
|
112
120
|
// to be passed to Mutable<T> parameters. Enforcement is runtime-only.
|
|
113
|
-
expect(() => Relation.addTag(rel, 'tag')).toThrow(/outside of Obj.
|
|
121
|
+
expect(() => Relation.addTag(rel, tagRef('tag'))).toThrow(/outside of Obj.update/);
|
|
114
122
|
});
|
|
115
123
|
});
|
|
116
124
|
|
|
@@ -122,7 +130,7 @@ describe('Obj.change enforcement', () => {
|
|
|
122
130
|
// Person schema uses 'name' as label field.
|
|
123
131
|
expect(Obj.getLabel(obj)).toBe('John');
|
|
124
132
|
|
|
125
|
-
Obj.
|
|
133
|
+
Obj.update(obj, (obj) => {
|
|
126
134
|
Obj.setLabel(obj, 'Jane');
|
|
127
135
|
});
|
|
128
136
|
|
|
@@ -140,7 +148,7 @@ describe('Obj.change enforcement', () => {
|
|
|
140
148
|
|
|
141
149
|
// setDescription only works if schema has description annotation.
|
|
142
150
|
// For schemas without it, this is a no-op.
|
|
143
|
-
Obj.
|
|
151
|
+
Obj.update(obj, (obj) => {
|
|
144
152
|
Obj.setDescription(obj, 'My Description');
|
|
145
153
|
});
|
|
146
154
|
|
|
@@ -151,26 +159,26 @@ describe('Obj.change enforcement', () => {
|
|
|
151
159
|
test('addTag and removeTag work correctly', ({ expect }) => {
|
|
152
160
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
153
161
|
|
|
154
|
-
expect(Obj.getMeta(obj).tags).
|
|
162
|
+
expect(Obj.getMeta(obj).tags).toEqual([]);
|
|
155
163
|
|
|
156
|
-
Obj.
|
|
157
|
-
Obj.addTag(obj, 'tag-1');
|
|
158
|
-
Obj.addTag(obj, 'tag-2');
|
|
164
|
+
Obj.update(obj, (obj) => {
|
|
165
|
+
Obj.addTag(obj, tagRef('tag-1'));
|
|
166
|
+
Obj.addTag(obj, tagRef('tag-2'));
|
|
159
167
|
});
|
|
160
168
|
|
|
161
|
-
expect(
|
|
169
|
+
expect(tagUris(obj)).toEqual([tagRef('tag-1').uri, tagRef('tag-2').uri]);
|
|
162
170
|
|
|
163
|
-
Obj.
|
|
164
|
-
Obj.removeTag(obj, 'tag-1');
|
|
171
|
+
Obj.update(obj, (obj) => {
|
|
172
|
+
Obj.removeTag(obj, tagRef('tag-1'));
|
|
165
173
|
});
|
|
166
174
|
|
|
167
|
-
expect(
|
|
175
|
+
expect(tagUris(obj)).toEqual([tagRef('tag-2').uri]);
|
|
168
176
|
});
|
|
169
177
|
|
|
170
178
|
test('deleteKeys removes foreign keys by source', ({ expect }) => {
|
|
171
179
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
172
180
|
|
|
173
|
-
Obj.
|
|
181
|
+
Obj.update(obj, (obj) => {
|
|
174
182
|
const meta = Obj.getMeta(obj);
|
|
175
183
|
meta.keys.push({ source: 'source-a', id: '1' });
|
|
176
184
|
meta.keys.push({ source: 'source-a', id: '2' });
|
|
@@ -179,7 +187,7 @@ describe('Obj.change enforcement', () => {
|
|
|
179
187
|
|
|
180
188
|
expect(Obj.getMeta(obj).keys).toHaveLength(3);
|
|
181
189
|
|
|
182
|
-
Obj.
|
|
190
|
+
Obj.update(obj, (obj) => {
|
|
183
191
|
Obj.deleteKeys(obj, 'source-a');
|
|
184
192
|
});
|
|
185
193
|
|
|
@@ -190,7 +198,7 @@ describe('Obj.change enforcement', () => {
|
|
|
190
198
|
test('setValue sets nested properties', ({ expect }) => {
|
|
191
199
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
192
200
|
|
|
193
|
-
Obj.
|
|
201
|
+
Obj.update(obj, (obj) => {
|
|
194
202
|
Obj.setValue(obj, ['name'], 'Updated Name');
|
|
195
203
|
});
|
|
196
204
|
|
|
@@ -200,36 +208,36 @@ describe('Obj.change enforcement', () => {
|
|
|
200
208
|
test('getMeta is mutable inside change and changes persist', ({ expect }) => {
|
|
201
209
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
202
210
|
|
|
203
|
-
Obj.
|
|
211
|
+
Obj.update(obj, (obj) => {
|
|
204
212
|
const meta = Obj.getMeta(obj);
|
|
205
|
-
meta.tags = ['tag-1', 'tag-2'];
|
|
213
|
+
meta.tags = [tagRef('tag-1'), tagRef('tag-2')];
|
|
206
214
|
meta.keys.push({ source: 'external', id: '123' });
|
|
207
215
|
});
|
|
208
216
|
|
|
209
217
|
// Changes should persist after the change callback.
|
|
210
|
-
expect(
|
|
218
|
+
expect(tagUris(obj)).toEqual([tagRef('tag-1').uri, tagRef('tag-2').uri]);
|
|
211
219
|
expect(Obj.getMeta(obj).keys).toEqual([{ source: 'external', id: '123' }]);
|
|
212
220
|
});
|
|
213
221
|
|
|
214
222
|
test('multiple mutations in single change all persist', ({ expect }) => {
|
|
215
223
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
216
224
|
|
|
217
|
-
Obj.
|
|
225
|
+
Obj.update(obj, (obj) => {
|
|
218
226
|
obj.name = 'Name 1';
|
|
219
227
|
obj.name = 'Name 2';
|
|
220
228
|
obj.name = 'Name 3';
|
|
221
|
-
Obj.addTag(obj, 'tag-1');
|
|
222
|
-
Obj.addTag(obj, 'tag-2');
|
|
229
|
+
Obj.addTag(obj, tagRef('tag-1'));
|
|
230
|
+
Obj.addTag(obj, tagRef('tag-2'));
|
|
223
231
|
});
|
|
224
232
|
|
|
225
233
|
// All mutations should persist.
|
|
226
234
|
expect(obj.name).toBe('Name 3');
|
|
227
|
-
expect(
|
|
235
|
+
expect(tagUris(obj)).toEqual([tagRef('tag-1').uri, tagRef('tag-2').uri]);
|
|
228
236
|
});
|
|
229
237
|
});
|
|
230
238
|
|
|
231
239
|
describe('notifications', () => {
|
|
232
|
-
test('batched notifications - only one per Obj.
|
|
240
|
+
test('batched notifications - only one per Obj.update', ({ expect }) => {
|
|
233
241
|
const obj = Obj.make(TestSchema.Person, { name: 'John' });
|
|
234
242
|
|
|
235
243
|
let notificationCount = 0;
|
|
@@ -237,7 +245,7 @@ describe('Obj.change enforcement', () => {
|
|
|
237
245
|
notificationCount++;
|
|
238
246
|
});
|
|
239
247
|
|
|
240
|
-
Obj.
|
|
248
|
+
Obj.update(obj, (obj) => {
|
|
241
249
|
obj.name = 'Jane';
|
|
242
250
|
obj.age = 30;
|
|
243
251
|
});
|
|
@@ -250,13 +258,13 @@ describe('Obj.change enforcement', () => {
|
|
|
250
258
|
});
|
|
251
259
|
|
|
252
260
|
describe('nested mutations', () => {
|
|
253
|
-
test('nested object property mutation within Obj.
|
|
261
|
+
test('nested object property mutation within Obj.update', ({ expect }) => {
|
|
254
262
|
const obj = Obj.make(TestSchema.Person, {
|
|
255
263
|
name: 'John',
|
|
256
264
|
address: { city: 'NYC', coordinates: {} },
|
|
257
265
|
});
|
|
258
266
|
|
|
259
|
-
Obj.
|
|
267
|
+
Obj.update(obj, (obj) => {
|
|
260
268
|
obj.address!.state = 'NY';
|
|
261
269
|
});
|
|
262
270
|
|
|
@@ -264,13 +272,13 @@ describe('Obj.change enforcement', () => {
|
|
|
264
272
|
expect(obj.address?.city).toBe('NYC');
|
|
265
273
|
});
|
|
266
274
|
|
|
267
|
-
test('deeply nested property mutation within Obj.
|
|
275
|
+
test('deeply nested property mutation within Obj.update (2 levels)', ({ expect }) => {
|
|
268
276
|
const obj = Obj.make(TestSchema.Person, {
|
|
269
277
|
name: 'John',
|
|
270
278
|
address: { city: 'NYC', coordinates: { lat: 40.7128, lng: -74.006 } },
|
|
271
279
|
});
|
|
272
280
|
|
|
273
|
-
Obj.
|
|
281
|
+
Obj.update(obj, (obj) => {
|
|
274
282
|
obj.address!.coordinates!.lat = 51.5074;
|
|
275
283
|
obj.address!.coordinates!.lng = -0.1278;
|
|
276
284
|
});
|
|
@@ -279,7 +287,7 @@ describe('Obj.change enforcement', () => {
|
|
|
279
287
|
expect(obj.address?.coordinates?.lng).toBe(-0.1278);
|
|
280
288
|
});
|
|
281
289
|
|
|
282
|
-
test('nested object mutation outside Obj.
|
|
290
|
+
test('nested object mutation outside Obj.update throws (1 level deep)', ({ expect }) => {
|
|
283
291
|
const obj = Obj.make(TestSchema.Person, {
|
|
284
292
|
name: 'John',
|
|
285
293
|
address: { city: 'NYC', coordinates: {} },
|
|
@@ -288,10 +296,10 @@ describe('Obj.change enforcement', () => {
|
|
|
288
296
|
expect(() => {
|
|
289
297
|
// @ts-expect-error - nested property assignment is readonly.
|
|
290
298
|
obj.address!.city = 'LA';
|
|
291
|
-
}).toThrow(/outside of Obj.
|
|
299
|
+
}).toThrow(/outside of Obj.update/);
|
|
292
300
|
});
|
|
293
301
|
|
|
294
|
-
test('deeply nested mutation outside Obj.
|
|
302
|
+
test('deeply nested mutation outside Obj.update throws (2 levels deep)', ({ expect }) => {
|
|
295
303
|
const obj = Obj.make(TestSchema.Person, {
|
|
296
304
|
name: 'John',
|
|
297
305
|
address: { city: 'NYC', coordinates: { lat: 40.7128, lng: -74.006 } },
|
|
@@ -300,17 +308,17 @@ describe('Obj.change enforcement', () => {
|
|
|
300
308
|
expect(() => {
|
|
301
309
|
// @ts-expect-error - deeply nested property assignment should be caught.
|
|
302
310
|
obj.address!.coordinates!.lat = 0;
|
|
303
|
-
}).toThrow(/outside of Obj.
|
|
311
|
+
}).toThrow(/outside of Obj.update/);
|
|
304
312
|
});
|
|
305
313
|
|
|
306
|
-
test('nested Obj.
|
|
314
|
+
test('nested Obj.update calls work correctly', ({ expect }) => {
|
|
307
315
|
const obj = Obj.make(TestSchema.Person, { name: 'John' });
|
|
308
316
|
|
|
309
|
-
Obj.
|
|
317
|
+
Obj.update(obj, (obj) => {
|
|
310
318
|
obj.name = 'Jane';
|
|
311
319
|
|
|
312
320
|
// Nested change should work (already in change context).
|
|
313
|
-
Obj.
|
|
321
|
+
Obj.update(obj, (obj) => {
|
|
314
322
|
obj.age = 30;
|
|
315
323
|
});
|
|
316
324
|
});
|
|
@@ -323,7 +331,7 @@ describe('Obj.change enforcement', () => {
|
|
|
323
331
|
const obj = Obj.make(TestSchema.Person, { name: 'John' });
|
|
324
332
|
|
|
325
333
|
expect(() => {
|
|
326
|
-
Obj.
|
|
334
|
+
Obj.update(obj, (obj) => {
|
|
327
335
|
obj.name = 'Jane';
|
|
328
336
|
throw new Error('Test error');
|
|
329
337
|
});
|
|
@@ -333,18 +341,18 @@ describe('Obj.change enforcement', () => {
|
|
|
333
341
|
expect(() => {
|
|
334
342
|
// @ts-expect-error Testing runtime error for readonly property mutation.
|
|
335
343
|
obj.name = 'Bob';
|
|
336
|
-
}).toThrow(/outside of Obj.
|
|
344
|
+
}).toThrow(/outside of Obj.update/);
|
|
337
345
|
});
|
|
338
346
|
});
|
|
339
347
|
|
|
340
348
|
describe('array mutations', () => {
|
|
341
|
-
test('array push within Obj.
|
|
349
|
+
test('array push within Obj.update', ({ expect }) => {
|
|
342
350
|
const obj = Obj.make(TestSchema.Person, {
|
|
343
351
|
name: 'John',
|
|
344
352
|
fields: [{ label: 'tag1', value: 'val1' }],
|
|
345
353
|
});
|
|
346
354
|
|
|
347
|
-
Obj.
|
|
355
|
+
Obj.update(obj, (obj) => {
|
|
348
356
|
obj.fields!.push({ label: 'tag2', value: 'val2' });
|
|
349
357
|
});
|
|
350
358
|
|
|
@@ -352,7 +360,7 @@ describe('Obj.change enforcement', () => {
|
|
|
352
360
|
expect(obj.fields![1].label).toBe('tag2');
|
|
353
361
|
});
|
|
354
362
|
|
|
355
|
-
test('array pop within Obj.
|
|
363
|
+
test('array pop within Obj.update', ({ expect }) => {
|
|
356
364
|
const obj = Obj.make(TestSchema.Person, {
|
|
357
365
|
name: 'John',
|
|
358
366
|
fields: [
|
|
@@ -362,7 +370,7 @@ describe('Obj.change enforcement', () => {
|
|
|
362
370
|
});
|
|
363
371
|
|
|
364
372
|
let popped: any;
|
|
365
|
-
Obj.
|
|
373
|
+
Obj.update(obj, (obj) => {
|
|
366
374
|
popped = obj.fields!.pop();
|
|
367
375
|
});
|
|
368
376
|
|
|
@@ -370,7 +378,7 @@ describe('Obj.change enforcement', () => {
|
|
|
370
378
|
expect(obj.fields).toHaveLength(1);
|
|
371
379
|
});
|
|
372
380
|
|
|
373
|
-
test('array splice within Obj.
|
|
381
|
+
test('array splice within Obj.update', ({ expect }) => {
|
|
374
382
|
const obj = Obj.make(TestSchema.Person, {
|
|
375
383
|
name: 'John',
|
|
376
384
|
fields: [
|
|
@@ -380,7 +388,7 @@ describe('Obj.change enforcement', () => {
|
|
|
380
388
|
],
|
|
381
389
|
});
|
|
382
390
|
|
|
383
|
-
Obj.
|
|
391
|
+
Obj.update(obj, (obj) => {
|
|
384
392
|
obj.fields!.splice(1, 1, { label: 'x', value: 'x' });
|
|
385
393
|
});
|
|
386
394
|
|
|
@@ -388,7 +396,7 @@ describe('Obj.change enforcement', () => {
|
|
|
388
396
|
expect(obj.fields![1].label).toBe('x');
|
|
389
397
|
});
|
|
390
398
|
|
|
391
|
-
test('array push outside Obj.
|
|
399
|
+
test('array push outside Obj.update throws', ({ expect }) => {
|
|
392
400
|
const obj = Obj.make(TestSchema.Person, {
|
|
393
401
|
name: 'John',
|
|
394
402
|
fields: [{ label: 'tag1', value: 'val1' }],
|
|
@@ -397,10 +405,10 @@ describe('Obj.change enforcement', () => {
|
|
|
397
405
|
expect(() => {
|
|
398
406
|
// @ts-expect-error Testing runtime error for readonly array mutation.
|
|
399
407
|
obj.fields!.push({ label: 'tag2', value: 'val2' });
|
|
400
|
-
}).toThrow(/array\.push\(\).*outside of Obj\.
|
|
408
|
+
}).toThrow(/array\.push\(\).*outside of Obj\.update/);
|
|
401
409
|
});
|
|
402
410
|
|
|
403
|
-
test('array pop outside Obj.
|
|
411
|
+
test('array pop outside Obj.update throws', ({ expect }) => {
|
|
404
412
|
const obj = Obj.make(TestSchema.Person, {
|
|
405
413
|
name: 'John',
|
|
406
414
|
fields: [{ label: 'tag1', value: 'val1' }],
|
|
@@ -409,10 +417,10 @@ describe('Obj.change enforcement', () => {
|
|
|
409
417
|
expect(() => {
|
|
410
418
|
// @ts-expect-error Testing runtime error for readonly array mutation.
|
|
411
419
|
obj.fields!.pop();
|
|
412
|
-
}).toThrow(/array\.pop\(\).*outside of Obj\.
|
|
420
|
+
}).toThrow(/array\.pop\(\).*outside of Obj\.update/);
|
|
413
421
|
});
|
|
414
422
|
|
|
415
|
-
test('array splice outside Obj.
|
|
423
|
+
test('array splice outside Obj.update throws', ({ expect }) => {
|
|
416
424
|
const obj = Obj.make(TestSchema.Person, {
|
|
417
425
|
name: 'John',
|
|
418
426
|
fields: [{ label: 'tag1', value: 'val1' }],
|
|
@@ -421,33 +429,33 @@ describe('Obj.change enforcement', () => {
|
|
|
421
429
|
expect(() => {
|
|
422
430
|
// @ts-expect-error Testing runtime error for readonly array mutation.
|
|
423
431
|
obj.fields!.splice(0, 1);
|
|
424
|
-
}).toThrow(/array\.splice\(\).*outside of Obj\.
|
|
432
|
+
}).toThrow(/array\.splice\(\).*outside of Obj\.update/);
|
|
425
433
|
});
|
|
426
434
|
});
|
|
427
435
|
|
|
428
436
|
describe('property delete', () => {
|
|
429
|
-
test('delete property within Obj.
|
|
437
|
+
test('delete property within Obj.update', ({ expect }) => {
|
|
430
438
|
const obj = Obj.make(TestSchema.Person, { name: 'John', age: 25 });
|
|
431
439
|
|
|
432
|
-
Obj.
|
|
440
|
+
Obj.update(obj, (obj) => {
|
|
433
441
|
delete obj.age;
|
|
434
442
|
});
|
|
435
443
|
|
|
436
444
|
expect(obj.age).toBeUndefined();
|
|
437
445
|
});
|
|
438
446
|
|
|
439
|
-
test('delete property outside Obj.
|
|
447
|
+
test('delete property outside Obj.update throws', ({ expect }) => {
|
|
440
448
|
const obj = Obj.make(TestSchema.Person, { name: 'John', age: 25 });
|
|
441
449
|
|
|
442
450
|
expect(() => {
|
|
443
451
|
// @ts-expect-error Testing runtime error for readonly property delete.
|
|
444
452
|
delete obj.age;
|
|
445
|
-
}).toThrow(/delete object property.*outside of Obj\.
|
|
453
|
+
}).toThrow(/delete object property.*outside of Obj\.update/);
|
|
446
454
|
});
|
|
447
455
|
});
|
|
448
456
|
|
|
449
457
|
describe('Relation mutators', () => {
|
|
450
|
-
test('Relation.getMeta is mutable inside Relation.
|
|
458
|
+
test('Relation.getMeta is mutable inside Relation.update', ({ expect }) => {
|
|
451
459
|
const source = Obj.make(TestSchema.Person, { name: 'Alice' });
|
|
452
460
|
const target = Obj.make(TestSchema.Person, { name: 'Bob' });
|
|
453
461
|
const rel = Relation.make(TestSchema.HasManager, {
|
|
@@ -455,13 +463,13 @@ describe('Obj.change enforcement', () => {
|
|
|
455
463
|
[Relation.Target]: target,
|
|
456
464
|
});
|
|
457
465
|
|
|
458
|
-
Relation.
|
|
466
|
+
Relation.update(rel, (rel) => {
|
|
459
467
|
const meta = Relation.getMeta(rel);
|
|
460
|
-
meta.tags = ['rel-tag'];
|
|
468
|
+
meta.tags = [tagRef('rel-tag')];
|
|
461
469
|
meta.keys.push({ source: 'rel-source', id: 'rel-key' });
|
|
462
470
|
});
|
|
463
471
|
|
|
464
|
-
expect(
|
|
472
|
+
expect(tagUris(rel)).toEqual([tagRef('rel-tag').uri]);
|
|
465
473
|
expect(Relation.getMeta(rel).keys).toHaveLength(1);
|
|
466
474
|
});
|
|
467
475
|
|
|
@@ -473,17 +481,17 @@ describe('Obj.change enforcement', () => {
|
|
|
473
481
|
[Relation.Target]: target,
|
|
474
482
|
});
|
|
475
483
|
|
|
476
|
-
Relation.
|
|
477
|
-
Relation.addTag(rel, 'important');
|
|
484
|
+
Relation.update(rel, (rel) => {
|
|
485
|
+
Relation.addTag(rel, tagRef('important'));
|
|
478
486
|
});
|
|
479
487
|
|
|
480
|
-
expect(
|
|
488
|
+
expect(tagUris(rel)).toContain(tagRef('important').uri);
|
|
481
489
|
|
|
482
|
-
Relation.
|
|
483
|
-
Relation.removeTag(rel, 'important');
|
|
490
|
+
Relation.update(rel, (rel) => {
|
|
491
|
+
Relation.removeTag(rel, tagRef('important'));
|
|
484
492
|
});
|
|
485
493
|
|
|
486
|
-
expect(
|
|
494
|
+
expect(tagUris(rel)).not.toContain(tagRef('important').uri);
|
|
487
495
|
});
|
|
488
496
|
});
|
|
489
497
|
|
|
@@ -494,7 +502,7 @@ describe('Obj.change enforcement', () => {
|
|
|
494
502
|
|
|
495
503
|
// Direct assignment of root ECHO objects (created with Obj.make) is not allowed.
|
|
496
504
|
expect(() => {
|
|
497
|
-
Obj.
|
|
505
|
+
Obj.update(obj, (obj) => {
|
|
498
506
|
obj.other = other;
|
|
499
507
|
});
|
|
500
508
|
}).toThrow(/Object references must be wrapped with `Ref\.make`/);
|
|
@@ -504,13 +512,13 @@ describe('Obj.change enforcement', () => {
|
|
|
504
512
|
const obj = Obj.make(TestSchema.Expando, {});
|
|
505
513
|
|
|
506
514
|
// Assign a plain object (not created with Obj.make).
|
|
507
|
-
Obj.
|
|
515
|
+
Obj.update(obj, (obj) => {
|
|
508
516
|
obj.nested = { value: 'initial' };
|
|
509
517
|
});
|
|
510
518
|
expect(obj.nested.value).toBe('initial');
|
|
511
519
|
|
|
512
520
|
// Modify plain nested object through parent's change context.
|
|
513
|
-
Obj.
|
|
521
|
+
Obj.update(obj, (obj) => {
|
|
514
522
|
obj.nested.value = 'modified';
|
|
515
523
|
});
|
|
516
524
|
expect(obj.nested.value).toBe('modified');
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Error thrown when attempting to mutate an object outside of an Obj.
|
|
6
|
+
* Error thrown when attempting to mutate an object outside of an Obj.update() context.
|
|
7
7
|
*/
|
|
8
8
|
export class MutationOutsideChangeContextError extends Error {
|
|
9
9
|
constructor(operation: string, suggestion: string) {
|
|
10
10
|
super(
|
|
11
|
-
`Cannot ${operation} outside of Obj.
|
|
11
|
+
`Cannot ${operation} outside of Obj.update(). Use Obj.update(obj, (mutableObj) => { ${suggestion} }) instead.`,
|
|
12
12
|
);
|
|
13
13
|
this.name = 'MutationOutsideChangeContextError';
|
|
14
14
|
}
|
|
@@ -9,7 +9,7 @@ import { isNode } from '@dxos/util';
|
|
|
9
9
|
|
|
10
10
|
import { TestSchema, updateCounter } from '../../../testing';
|
|
11
11
|
import { createObject } from '../../Obj';
|
|
12
|
-
import { ATTR_META } from '../types';
|
|
12
|
+
import { ATTR_META } from '../types/meta';
|
|
13
13
|
import { makeObject } from './make-object';
|
|
14
14
|
import { objectData } from './proxy-types';
|
|
15
15
|
import { change } from './reactive';
|