@dxos/echo 0.8.4-main.40e3dcdf1b → 0.8.4-main.43cb759274
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 +29 -6
- package/dist/lib/neutral/Database.mjs +8 -9
- package/dist/lib/neutral/Entity.mjs +29 -18
- package/dist/lib/neutral/Err.mjs +3 -3
- package/dist/lib/neutral/Feed.mjs +27 -19
- package/dist/lib/neutral/Filter.mjs +25 -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 +18 -0
- package/dist/lib/neutral/Obj.mjs +25 -19
- package/dist/lib/neutral/Order.mjs +1 -1
- package/dist/lib/neutral/Query.mjs +19 -16
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +10 -9
- package/dist/lib/neutral/Registry.mjs +14 -0
- package/dist/lib/neutral/Registry.mjs.map +7 -0
- package/dist/lib/neutral/Relation.mjs +26 -24
- package/dist/lib/neutral/Scope.mjs +12 -0
- package/dist/lib/neutral/Scope.mjs.map +7 -0
- package/dist/lib/neutral/Tag.mjs +17 -13
- package/dist/lib/neutral/Type.mjs +52 -26
- package/dist/lib/neutral/chunk-3DKP2EIN.mjs +31 -0
- package/dist/lib/neutral/chunk-3DKP2EIN.mjs.map +7 -0
- package/dist/lib/neutral/chunk-4BB4MFCN.mjs +154 -0
- package/dist/lib/neutral/chunk-4BB4MFCN.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-CIRHIEMW.mjs → chunk-4SFPZJVA.mjs} +92 -112
- package/dist/lib/neutral/chunk-4SFPZJVA.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-YWXWXIE5.mjs → chunk-4Z6GET2X.mjs} +3 -3
- package/dist/lib/neutral/chunk-4Z6GET2X.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-43Y5DOS6.mjs → chunk-7OAFN3OX.mjs} +75 -112
- package/dist/lib/neutral/chunk-7OAFN3OX.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-BOZZPUXE.mjs → chunk-7PRCIDHH.mjs} +41 -81
- package/dist/lib/neutral/chunk-7PRCIDHH.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-BDQGMDIX.mjs +132 -0
- package/dist/lib/neutral/chunk-BDQGMDIX.mjs.map +7 -0
- package/dist/lib/neutral/chunk-CGTI5MXO.mjs +36 -0
- package/dist/lib/neutral/chunk-CGTI5MXO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-DKLUHO4T.mjs} +1 -1
- package/dist/lib/neutral/chunk-DKLUHO4T.mjs.map +7 -0
- package/dist/lib/neutral/chunk-DMN2CKPX.mjs +93 -0
- package/dist/lib/neutral/chunk-DMN2CKPX.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UTBRYVQC.mjs → chunk-G6CFWUYH.mjs} +2 -2
- package/dist/lib/neutral/chunk-H26LSXVJ.mjs +653 -0
- package/dist/lib/neutral/chunk-H26LSXVJ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-FXEG7EOK.mjs → chunk-J3MNM65T.mjs} +9 -6
- package/dist/lib/neutral/chunk-J3MNM65T.mjs.map +7 -0
- package/dist/lib/neutral/chunk-JE7AOSWF.mjs +247 -0
- package/dist/lib/neutral/chunk-JE7AOSWF.mjs.map +7 -0
- package/dist/lib/neutral/chunk-LAF3LSWI.mjs +379 -0
- package/dist/lib/neutral/chunk-LAF3LSWI.mjs.map +7 -0
- package/dist/lib/neutral/chunk-LMNRFOVB.mjs +108 -0
- package/dist/lib/neutral/chunk-LMNRFOVB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WYOKA6AE.mjs → chunk-O6BH7EPN.mjs} +31 -4
- package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-KTAWP7GI.mjs → chunk-OIYW7R2G.mjs} +99 -46
- package/dist/lib/neutral/chunk-OIYW7R2G.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TQQZLKB7.mjs → chunk-OYUG4FHF.mjs} +648 -1228
- package/dist/lib/neutral/chunk-OYUG4FHF.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-NQRLRYJM.mjs → chunk-Q5FKCVBC.mjs} +173 -60
- package/dist/lib/neutral/chunk-Q5FKCVBC.mjs.map +7 -0
- package/dist/lib/neutral/chunk-Q62IHV2N.mjs +41 -0
- package/dist/lib/neutral/chunk-Q62IHV2N.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UFDK26FO.mjs → chunk-QVJDDG44.mjs} +69 -34
- package/dist/lib/neutral/chunk-QVJDDG44.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-B5OXLWZL.mjs → chunk-TFEWTY5A.mjs} +155 -129
- package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-TTCSATUD.mjs} +1 -1
- package/dist/lib/neutral/{chunk-FZO7LQO7.mjs → chunk-VKWOFXT2.mjs} +22 -2
- package/dist/lib/neutral/{chunk-FZO7LQO7.mjs.map → chunk-VKWOFXT2.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-NXMFBIT5.mjs → chunk-ZACMEAYV.mjs} +89 -23
- package/dist/lib/neutral/chunk-ZACMEAYV.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +58 -38
- package/dist/lib/neutral/internal/index.mjs +131 -64
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +222 -177
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- 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 -24
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +17 -6
- package/dist/types/src/Dataset.d.ts.map +1 -1
- package/dist/types/src/Entity.d.ts +102 -26
- 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 +89 -25
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts +74 -11
- package/dist/types/src/Filter.d.ts.map +1 -1
- package/dist/types/src/Filter.test.d.ts +2 -0
- package/dist/types/src/Filter.test.d.ts.map +1 -0
- package/dist/types/src/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 +72 -0
- package/dist/types/src/Migration.d.ts.map +1 -0
- package/dist/types/src/Obj.d.ts +108 -65
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Order.d.ts.map +1 -1
- package/dist/types/src/Query.d.ts +35 -10
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/QueryResult.d.ts +9 -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 +72 -44
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Scope.d.ts +34 -0
- package/dist/types/src/Scope.d.ts.map +1 -0
- package/dist/types/src/StateMap.d.ts +32 -0
- package/dist/types/src/StateMap.d.ts.map +1 -0
- package/dist/types/src/StateMap.test.d.ts +2 -0
- package/dist/types/src/StateMap.test.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/TagIndex.d.ts +36 -0
- package/dist/types/src/TagIndex.d.ts.map +1 -0
- package/dist/types/src/TagIndex.test.d.ts +2 -0
- package/dist/types/src/TagIndex.test.d.ts.map +1 -0
- package/dist/types/src/Tagging.d.ts +31 -0
- package/dist/types/src/Tagging.d.ts.map +1 -0
- package/dist/types/src/Type.d.ts +357 -96
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +2 -5
- 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 +8 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/annotations.d.ts +79 -37
- 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 +3 -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 +20 -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 +25 -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 +28 -28
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts +3 -2
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/create-object.d.ts +11 -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 +0 -1
- package/dist/types/src/internal/Obj/index.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/json-serializer.d.ts +11 -10
- 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.d.ts +10 -0
- package/dist/types/src/internal/Query.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/ref-array.d.ts +2 -2
- package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref.d.ts +42 -19
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
- package/dist/types/src/internal/Type/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 +63 -6
- 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 +23 -7
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/model-symbols.d.ts +8 -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 -0
- package/dist/types/src/internal/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts +8 -8
- package/dist/types/src/testing/test-data.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +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 +27 -19
- package/src/Annotation.test.ts +439 -0
- package/src/Annotation.ts +152 -4
- package/src/Collection.ts +6 -5
- package/src/Database.ts +117 -57
- package/src/Dataset.ts +10 -2
- package/src/Entity.test.ts +116 -6
- package/src/Entity.ts +130 -31
- package/src/Err.ts +4 -4
- package/src/Feed.ts +138 -43
- package/src/Filter.test.ts +90 -0
- package/src/Filter.ts +143 -27
- 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 +114 -0
- package/src/Obj.test.ts +122 -19
- package/src/Obj.ts +279 -97
- package/src/Query.test.ts +317 -131
- package/src/Query.ts +181 -73
- package/src/QueryResult.ts +11 -0
- package/src/Ref.ts +22 -4
- package/src/Registry.ts +155 -0
- package/src/Relation.test.ts +10 -10
- package/src/Relation.ts +112 -71
- package/src/Scope.ts +50 -0
- package/src/StateMap.test.ts +56 -0
- package/src/StateMap.ts +99 -0
- package/src/Tag.md +88 -0
- package/src/Tag.ts +49 -6
- package/src/TagIndex.test.ts +57 -0
- package/src/TagIndex.ts +110 -0
- package/src/Tagging.ts +83 -0
- package/src/Type.test.ts +223 -18
- package/src/Type.ts +602 -132
- package/src/View.ts +11 -15
- package/src/exemplars.test.ts +21 -0
- package/src/index.ts +9 -3
- package/src/internal/Annotation/annotations.test.ts +82 -13
- package/src/internal/Annotation/annotations.ts +153 -115
- package/src/internal/Annotation/dictionary.ts +47 -0
- package/src/internal/Annotation/entity-dictionary.ts +40 -0
- package/src/internal/Annotation/index.ts +4 -2
- package/src/internal/Annotation/sorting.ts +0 -1
- package/src/internal/Annotation/util.ts +17 -8
- package/src/internal/Entity/api.ts +7 -8
- 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 +37 -28
- package/src/internal/Entity/object.ts +21 -6
- package/src/internal/Entity/relation.ts +68 -34
- package/src/internal/Entity/type-kind.ts +75 -0
- package/src/internal/Entity/type-uri.ts +87 -0
- package/src/internal/Entity/util.ts +10 -9
- package/src/internal/Entity/version.ts +0 -1
- package/src/internal/Format/date.test.ts +0 -1
- package/src/internal/Format/date.ts +0 -4
- package/src/internal/Format/format.test.ts +21 -1
- 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 +1 -1
- package/src/internal/JsonSchema/json-schema.test.ts +55 -142
- package/src/internal/JsonSchema/json-schema.ts +44 -31
- package/src/internal/Obj/clone.ts +9 -4
- package/src/internal/Obj/create-object.test.ts +13 -13
- package/src/internal/Obj/create-object.ts +68 -24
- package/src/internal/Obj/deleted.ts +1 -1
- package/src/internal/Obj/index.ts +0 -1
- package/src/internal/Obj/inspect.ts +4 -3
- package/src/internal/Obj/json-serializer.test.ts +102 -24
- package/src/internal/Obj/json-serializer.ts +105 -43
- package/src/internal/Obj/set-value.test.ts +31 -54
- package/src/internal/Obj/set-value.ts +1 -1
- package/src/internal/Obj/snapshot.ts +11 -4
- package/src/internal/Obj/typed-object.test.ts +9 -11
- package/src/internal/Obj/typed-object.ts +1 -1
- package/src/internal/Query.ts +159 -0
- package/src/internal/Ref/ref-array.ts +3 -4
- package/src/internal/Ref/ref.test.ts +17 -27
- package/src/internal/Ref/ref.ts +124 -59
- package/src/internal/Type/compose.test.ts +3 -2
- 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 +118 -110
- package/src/internal/common/proxy/errors.ts +2 -2
- package/src/internal/common/proxy/handler.test.ts +1 -3
- package/src/internal/common/proxy/json-serializer.ts +26 -16
- package/src/internal/common/proxy/make-object.ts +43 -21
- package/src/internal/common/proxy/ownership.ts +2 -3
- package/src/internal/common/proxy/reactive-array.ts +1 -1
- package/src/internal/common/proxy/reactive.test.ts +54 -0
- package/src/internal/common/proxy/reactive.ts +11 -3
- package/src/internal/common/proxy/schema.test.ts +48 -86
- package/src/internal/common/proxy/typed-handler.test.ts +12 -12
- package/src/internal/common/proxy/typed-handler.ts +79 -19
- package/src/internal/common/proxy/typed-object.test.ts +16 -29
- package/src/internal/common/types/base.ts +4 -4
- package/src/internal/common/types/entity.ts +81 -2
- package/src/internal/common/types/index.ts +6 -1
- package/src/internal/common/types/meta.ts +49 -15
- package/src/internal/common/types/model-symbols.ts +16 -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 -0
- package/src/testing/api.test.ts +15 -10
- package/src/testing/test-data.ts +159 -100
- package/src/testing/test-schema.ts +22 -58
- package/src/testing/util.ts +14 -11
- package/dist/lib/neutral/SchemaRegistry.mjs +0 -2
- package/dist/lib/neutral/chunk-43Y5DOS6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-724GQYEN.mjs +0 -56
- package/dist/lib/neutral/chunk-724GQYEN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ANHVGJI4.mjs.map +0 -7
- package/dist/lib/neutral/chunk-B5OXLWZL.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-BOZZPUXE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-CIRHIEMW.mjs.map +0 -7
- package/dist/lib/neutral/chunk-DYDJBZEG.mjs +0 -102
- package/dist/lib/neutral/chunk-DYDJBZEG.mjs.map +0 -7
- package/dist/lib/neutral/chunk-FXEG7EOK.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KTAWP7GI.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NEGC54NE.mjs +0 -130
- package/dist/lib/neutral/chunk-NEGC54NE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NQRLRYJM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NXMFBIT5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OENWMTE6.mjs +0 -45
- package/dist/lib/neutral/chunk-OENWMTE6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OMUPQMLR.mjs.map +0 -7
- package/dist/lib/neutral/chunk-RMLF7JOZ.mjs +0 -97
- package/dist/lib/neutral/chunk-RMLF7JOZ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-SEMVAGBM.mjs +0 -355
- package/dist/lib/neutral/chunk-SEMVAGBM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TQQZLKB7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UBEZSGXY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UFDK26FO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VA2F47ZC.mjs +0 -152
- package/dist/lib/neutral/chunk-VA2F47ZC.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WYOKA6AE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-YWXWXIE5.mjs.map +0 -7
- 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/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/SchemaRegistry.ts +0 -106
- package/src/internal/Obj/ids.ts +0 -12
- package/src/internal/Type/echo-schema.ts +0 -424
- package/src/internal/Type/persistent-schema.ts +0 -33
- /package/dist/lib/neutral/{SchemaRegistry.mjs.map → Migration.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UTBRYVQC.mjs.map → chunk-G6CFWUYH.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UI6MWK5W.mjs.map → chunk-TTCSATUD.mjs.map} +0 -0
package/src/Obj.ts
CHANGED
|
@@ -5,23 +5,27 @@
|
|
|
5
5
|
// @import-as-namespace
|
|
6
6
|
|
|
7
7
|
import * as Effect from 'effect/Effect';
|
|
8
|
+
import * as Equal from 'effect/Equal';
|
|
8
9
|
import * as Function from 'effect/Function';
|
|
9
10
|
import * as Option from 'effect/Option';
|
|
10
11
|
import * as Schema from 'effect/Schema';
|
|
12
|
+
import * as Utils from 'effect/Utils';
|
|
11
13
|
|
|
12
14
|
import type { ForeignKey } from '@dxos/echo-protocol';
|
|
13
15
|
import { createJsonPath } from '@dxos/effect';
|
|
14
|
-
import { assertArgument } from '@dxos/invariant';
|
|
15
|
-
import {
|
|
16
|
-
import { assumeType } from '@dxos/util';
|
|
16
|
+
import { assertArgument, invariant } from '@dxos/invariant';
|
|
17
|
+
import { DXN, EntityId, type URI } from '@dxos/keys';
|
|
18
|
+
import { assumeType, deepMapValues } from '@dxos/util';
|
|
17
19
|
|
|
18
20
|
import type * as Database from './Database';
|
|
19
21
|
import * as Entity from './Entity';
|
|
20
22
|
import * as Err from './Err';
|
|
21
|
-
import * as objInternal from './internal/Obj';
|
|
22
23
|
import * as internal from './internal';
|
|
23
|
-
import
|
|
24
|
-
import
|
|
24
|
+
import { getProxyTarget, isProxy } from './internal/common/proxy/proxy-utils';
|
|
25
|
+
import * as objInternal from './internal/Obj';
|
|
26
|
+
import * as Ref from './Ref';
|
|
27
|
+
import type * as Tag from './Tag';
|
|
28
|
+
import * as Type from './Type';
|
|
25
29
|
|
|
26
30
|
/**
|
|
27
31
|
* Base type for all ECHO objects.
|
|
@@ -61,27 +65,24 @@ export interface Unknown extends BaseObj {}
|
|
|
61
65
|
* // Reference to any object type
|
|
62
66
|
* const Collection = Schema.Struct({
|
|
63
67
|
* objects: Schema.Array(Ref.Ref(Obj.Unknown)),
|
|
64
|
-
* }).pipe(Type.
|
|
68
|
+
* }).pipe(Type.makeObject(DXN.make('com.example.type.collection', '0.1.0')));
|
|
65
69
|
* ```
|
|
66
70
|
*/
|
|
67
71
|
// TODO(wittjosiah): Investigate if Schema.filter can validate KindId on ECHO instances.
|
|
68
72
|
// Effect Schema normalizes proxy objects to plain objects before calling filter predicates.
|
|
69
73
|
// Possible approaches: custom Schema.declare, AST manipulation, or upstream contribution.
|
|
70
|
-
export const Unknown:
|
|
74
|
+
export const Unknown: internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object> = Schema.Struct({
|
|
71
75
|
id: Schema.String,
|
|
72
76
|
}).pipe(
|
|
73
77
|
Schema.extend(Schema.Record({ key: Schema.String, value: Schema.Unknown })),
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
/**
|
|
78
|
+
Schema.annotations({
|
|
79
|
+
[internal.TypeAnnotationId]: {
|
|
80
|
+
kind: Entity.Kind.Object,
|
|
81
|
+
typename: internal.ANY_OBJECT_TYPENAME,
|
|
82
|
+
version: internal.ANY_OBJECT_VERSION,
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
) as unknown as internal.UnknownTypeSchema<Unknown, typeof Entity.Kind.Object>;
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* Object with arbitrary properties.
|
|
@@ -98,7 +99,7 @@ export interface Any extends BaseObj, internal.AnyProperties {}
|
|
|
98
99
|
*/
|
|
99
100
|
interface BaseSnapshot extends internal.AnyEntity {
|
|
100
101
|
readonly [Entity.SnapshotKindId]: typeof Entity.Kind.Object;
|
|
101
|
-
readonly id:
|
|
102
|
+
readonly id: EntityId;
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
/**
|
|
@@ -119,30 +120,44 @@ export interface BaseObjJson {
|
|
|
119
120
|
id: string;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
const
|
|
123
|
+
// Factory (not a shared const): each object must get its own `keys`/`tags`/`annotations` containers,
|
|
124
|
+
// otherwise mutating one object's meta would leak into every other object via the shared references.
|
|
125
|
+
const defaultMeta = (): internal.EntityMeta => ({
|
|
123
126
|
keys: [],
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
id?: ObjectId;
|
|
128
|
-
[Meta]?: Partial<internal.ObjectMeta>;
|
|
129
|
-
} & Entity.Properties<T>;
|
|
127
|
+
tags: [],
|
|
128
|
+
annotations: {},
|
|
129
|
+
});
|
|
130
130
|
|
|
131
131
|
// TODO(burdon): Should we allow the caller to set the id?
|
|
132
132
|
/**
|
|
133
|
-
* Props type for object creation with a given
|
|
133
|
+
* Props type for object creation with a given type. Accepts a `Type.AnyObj`
|
|
134
|
+
* entity and derives the instance shape via `Type.InstanceType`. Relation-kind
|
|
135
|
+
* entities are rejected at the type level — use `Relation.MakeProps` for those.
|
|
136
|
+
*
|
|
137
|
+
* When the schema is the unconstrained `Type.AnyObj` (`Obj<unknown>` — e.g. a
|
|
138
|
+
* dynamic type from `schemaRegistry.register`), the instance shape is not
|
|
139
|
+
* statically known, so data props widen to `Record<string, unknown>` and the
|
|
140
|
+
* caller can pass arbitrary fields without a cast.
|
|
134
141
|
*/
|
|
135
|
-
export type MakeProps<S extends
|
|
136
|
-
id?:
|
|
137
|
-
[Meta]?: Partial<internal.
|
|
142
|
+
export type MakeProps<S extends Type.AnyObj> = {
|
|
143
|
+
id?: EntityId;
|
|
144
|
+
[Meta]?: Partial<internal.EntityMeta>;
|
|
138
145
|
[Parent]?: Unknown;
|
|
139
|
-
|
|
146
|
+
// When the resolved instance has no known data keys, widen to a permissive
|
|
147
|
+
// record (the `Obj<unknown>` case); otherwise use the precise property shape.
|
|
148
|
+
// `[keyof …] extends [never]` is wrapped in tuples so the check is
|
|
149
|
+
// non-distributive — a `never` instance type (e.g. when narrowing collapses
|
|
150
|
+
// the schema) stays a single branch instead of distributing to `never`.
|
|
151
|
+
} & ([keyof Entity.Properties<Type.InstanceType<S>>] extends [never]
|
|
152
|
+
? Record<string, unknown>
|
|
153
|
+
: Entity.Properties<Type.InstanceType<S>>);
|
|
140
154
|
|
|
141
155
|
/**
|
|
142
|
-
* Creates a new echo object of the given schema.
|
|
143
|
-
*
|
|
156
|
+
* Creates a new echo object of the given schema or `Type.Type`.
|
|
157
|
+
*
|
|
158
|
+
* @param typeOrSchema - A static object schema (`Type.makeObject(...)`) or a
|
|
159
|
+
* `Type.Type` entity (e.g. one returned by `db.addType(schemaEntity)`).
|
|
144
160
|
* @param props - Object properties.
|
|
145
|
-
* @param meta - Object metadata (deprecated) -- pass with Obj.Meta.
|
|
146
161
|
*
|
|
147
162
|
* Meta can be passed as a symbol in `props`.
|
|
148
163
|
*
|
|
@@ -151,23 +166,26 @@ export type MakeProps<S extends Schema.Schema.AnyNoContext> = {
|
|
|
151
166
|
* const obj = Obj.make(Person, { [Obj.Meta]: { keys: [...] }, name: 'John' });
|
|
152
167
|
* ```
|
|
153
168
|
*
|
|
154
|
-
* Note: Only accepts object schemas, not relation schemas.
|
|
169
|
+
* Note: Only accepts object schemas / object-kind types, not relation schemas.
|
|
170
|
+
* Use `Relation.make` for relations.
|
|
155
171
|
*/
|
|
156
|
-
export
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
export function make<T extends Type.AnyObj>(type: T, props: NoInfer<MakeProps<T>>): OfShape<Type.InstanceType<T>>;
|
|
173
|
+
export function make(input: Type.AnyObj, props: any): OfShape<any> {
|
|
174
|
+
// `Type.Type` entities aren't `Schema.Schema` themselves; derive the Effect
|
|
175
|
+
// Schema via `Type.getSchema(...)`. Pass the entity through to `makeObject`
|
|
176
|
+
// so subsequent schema mutations (`Type.addFields`, etc.) propagate.
|
|
177
|
+
const schema = Type.getSchema(input);
|
|
160
178
|
assertArgument(
|
|
161
179
|
internal.getTypeAnnotation(schema)?.kind === Entity.Kind.Object,
|
|
162
180
|
'schema',
|
|
163
181
|
'Expected an object schema',
|
|
164
182
|
);
|
|
165
183
|
|
|
166
|
-
let meta: internal.
|
|
184
|
+
let meta: internal.EntityMeta | undefined = undefined;
|
|
167
185
|
|
|
168
186
|
// Set default fields on meta on creation.
|
|
169
187
|
if (props[internal.MetaId] != null) {
|
|
170
|
-
meta = { ...
|
|
188
|
+
meta = { ...defaultMeta(), ...props[internal.MetaId] };
|
|
171
189
|
delete props[internal.MetaId];
|
|
172
190
|
}
|
|
173
191
|
|
|
@@ -182,11 +200,16 @@ export const make = <S extends Type.AnyObj>(
|
|
|
182
200
|
}
|
|
183
201
|
}
|
|
184
202
|
|
|
185
|
-
return internal.makeObject
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
203
|
+
return internal.makeObject(
|
|
204
|
+
schema,
|
|
205
|
+
filterUndefined,
|
|
206
|
+
{
|
|
207
|
+
...defaultMeta(),
|
|
208
|
+
...meta,
|
|
209
|
+
},
|
|
210
|
+
input,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
190
213
|
|
|
191
214
|
/**
|
|
192
215
|
* Determine if object is an ECHO object.
|
|
@@ -303,7 +326,7 @@ export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = objI
|
|
|
303
326
|
|
|
304
327
|
/**
|
|
305
328
|
* Makes all properties mutable recursively.
|
|
306
|
-
* Used to provide a mutable view of an object within `Obj.
|
|
329
|
+
* Used to provide a mutable view of an object within `Obj.update`.
|
|
307
330
|
*/
|
|
308
331
|
export type Mutable<T> = internal.Mutable<T>;
|
|
309
332
|
|
|
@@ -311,33 +334,33 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
311
334
|
* Perform mutations on an echo object within a controlled context.
|
|
312
335
|
*
|
|
313
336
|
* All mutations within the callback are batched and trigger a single notification
|
|
314
|
-
* when the callback completes. Direct mutations outside of `Obj.
|
|
337
|
+
* when the callback completes. Direct mutations outside of `Obj.update` will throw
|
|
315
338
|
* an error for echo objects.
|
|
316
339
|
*
|
|
317
340
|
* This function also works with nested objects within echo objects (e.g., Template structs)
|
|
318
341
|
* that are reactive at runtime.
|
|
319
342
|
*
|
|
320
|
-
* @param obj - The echo object to mutate. Use `Relation.
|
|
343
|
+
* @param obj - The echo object to mutate. Use `Relation.update` for relations.
|
|
321
344
|
* @param callback - The callback that performs mutations on the object.
|
|
322
345
|
*
|
|
323
346
|
* @example
|
|
324
347
|
* ```ts
|
|
325
348
|
* const person = Obj.make(Person, { name: 'John', age: 25 });
|
|
326
349
|
*
|
|
327
|
-
* // Mutate within Obj.
|
|
328
|
-
* Obj.
|
|
329
|
-
*
|
|
330
|
-
*
|
|
350
|
+
* // Mutate within Obj.update
|
|
351
|
+
* Obj.update(person, (obj) => {
|
|
352
|
+
* obj.name = 'Jane';
|
|
353
|
+
* obj.age = 30;
|
|
331
354
|
* });
|
|
332
355
|
* // ONE notification fires here
|
|
333
356
|
*
|
|
334
357
|
* // Direct mutation throws
|
|
335
|
-
* person.name = 'Bob'; // Error: Cannot modify outside Obj.
|
|
358
|
+
* person.name = 'Bob'; // Error: Cannot modify outside Obj.update()
|
|
336
359
|
* ```
|
|
337
360
|
*
|
|
338
|
-
* Note: Only accepts objects. Use `Relation.
|
|
361
|
+
* Note: Only accepts objects. Use `Relation.update` for relations.
|
|
339
362
|
*/
|
|
340
|
-
export const
|
|
363
|
+
export const update = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {
|
|
341
364
|
internal.change(obj, callback);
|
|
342
365
|
};
|
|
343
366
|
|
|
@@ -372,7 +395,7 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
372
395
|
* whether to initialize nested data as an empty object or array.
|
|
373
396
|
*
|
|
374
397
|
* Similar to lodash.set and setDeep from @dxos/util, but schema-aware.
|
|
375
|
-
* Must be called within an `Obj.
|
|
398
|
+
* Must be called within an `Obj.update` callback.
|
|
376
399
|
*
|
|
377
400
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
378
401
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -386,8 +409,8 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
386
409
|
* ```ts
|
|
387
410
|
* const person = Obj.make(Person, { name: 'John' });
|
|
388
411
|
* // Person schema has: addresses: Schema.Array(Address)
|
|
389
|
-
* Obj.
|
|
390
|
-
* Obj.setValue(
|
|
412
|
+
* Obj.update(person, (obj) => {
|
|
413
|
+
* Obj.setValue(obj, ['addresses', 0, 'street'], '123 Main St');
|
|
391
414
|
* });
|
|
392
415
|
* // Creates: person.addresses = [{ street: '123 Main St' }]
|
|
393
416
|
* ```
|
|
@@ -400,12 +423,12 @@ export const setValue: (obj: Mutable<Unknown>, path: readonly (string | number)[
|
|
|
400
423
|
// Type
|
|
401
424
|
//
|
|
402
425
|
|
|
403
|
-
|
|
404
|
-
export
|
|
405
|
-
export type ID = ObjectId;
|
|
426
|
+
export const ID = EntityId;
|
|
427
|
+
export type ID = EntityId;
|
|
406
428
|
|
|
407
429
|
/**
|
|
408
|
-
* Test if object
|
|
430
|
+
* Test if an object is an instance of a given object type.
|
|
431
|
+
*
|
|
409
432
|
* @example
|
|
410
433
|
* ```ts
|
|
411
434
|
* const john = Obj.make(Person, { name: 'John' });
|
|
@@ -414,11 +437,29 @@ export type ID = ObjectId;
|
|
|
414
437
|
* // john is Person
|
|
415
438
|
* }
|
|
416
439
|
* ```
|
|
440
|
+
*
|
|
441
|
+
* Only accepts `Type.AnyObj` — use `Relation.instanceOf` for relations and
|
|
442
|
+
* `Type.isType(value)` to test for `Type.Type` meta-schema entities.
|
|
417
443
|
*/
|
|
418
444
|
export const instanceOf: {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
445
|
+
// Reject `Type.Type` at the type level — those are meta-schema entities, not
|
|
446
|
+
// object instances. Use `Type.isType(value)` instead.
|
|
447
|
+
<T extends Type.Type>(
|
|
448
|
+
type: T,
|
|
449
|
+
_hint?: never,
|
|
450
|
+
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
|
451
|
+
..._error: ['ERROR: Obj.instanceOf does not accept Type.Type; use Type.isType(value) instead']
|
|
452
|
+
): never;
|
|
453
|
+
// Reject relation types — use `Relation.instanceOf` instead.
|
|
454
|
+
<R extends Type.AnyRelation>(
|
|
455
|
+
type: R,
|
|
456
|
+
_hint?: never,
|
|
457
|
+
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
|
458
|
+
..._error: ['ERROR: Obj.instanceOf does not accept relation types; use Relation.instanceOf instead']
|
|
459
|
+
): never;
|
|
460
|
+
<S extends Type.AnyObj>(schema: S): (value: unknown) => value is Type.InstanceType<S>;
|
|
461
|
+
<S extends Type.AnyObj>(schema: S, value: unknown): value is Type.InstanceType<S>;
|
|
462
|
+
} = ((...args: [schema: Type.AnyEntity, value?: unknown]) => {
|
|
422
463
|
if (args.length === 1) {
|
|
423
464
|
return (entity: unknown) => internal.isInstanceOf(args[0], entity);
|
|
424
465
|
}
|
|
@@ -440,9 +481,9 @@ export const instanceOf: {
|
|
|
440
481
|
* ```
|
|
441
482
|
*/
|
|
442
483
|
export const snapshotOf: {
|
|
443
|
-
<S extends Type.
|
|
444
|
-
<S extends Type.
|
|
445
|
-
} = ((...args: [schema: Type.
|
|
484
|
+
<S extends Type.AnyObj>(schema: S): (value: unknown) => value is Snapshot<Type.InstanceType<S>>;
|
|
485
|
+
<S extends Type.AnyObj>(schema: S, value: unknown): value is Snapshot<Type.InstanceType<S>>;
|
|
486
|
+
} = ((...args: [schema: Type.AnyObj, value: unknown] | [schema: Type.AnyObj]) => {
|
|
446
487
|
const check = (entity: unknown) =>
|
|
447
488
|
entity != null &&
|
|
448
489
|
typeof entity === 'object' &&
|
|
@@ -458,27 +499,37 @@ export const snapshotOf: {
|
|
|
458
499
|
|
|
459
500
|
// TODO(dmaretskyi): Allow returning undefined.
|
|
460
501
|
/**
|
|
461
|
-
* Get the
|
|
502
|
+
* Get the canonical URI of the object. Returns `URI.URI` (today always an EID,
|
|
503
|
+
* but future entity kinds may surface other URI schemes — narrow with
|
|
504
|
+
* `EID.parse(uri)` or `DXN.tryMake(uri)` at the point of use).
|
|
462
505
|
* Accepts both reactive objects and snapshots.
|
|
463
506
|
*/
|
|
464
|
-
export const
|
|
507
|
+
export const getURI = (entity: Unknown | Snapshot): URI.URI => {
|
|
465
508
|
assertArgument(!Schema.isSchema(entity), 'obj', 'Object should not be a schema.');
|
|
466
|
-
return internal.
|
|
509
|
+
return internal.getUri(entity);
|
|
467
510
|
};
|
|
468
511
|
|
|
469
512
|
/**
|
|
470
513
|
* @returns The DXN of the object's type.
|
|
471
514
|
* @example dxn:com.example.type.person:1.0.0
|
|
515
|
+
* @throws If the object is missing its type (corrupted object).
|
|
472
516
|
*/
|
|
473
|
-
|
|
474
|
-
|
|
517
|
+
export const getTypeURI = (obj: Unknown | Snapshot): URI.URI => {
|
|
518
|
+
const type = internal.getTypeURI(obj);
|
|
519
|
+
invariant(type != null, 'Corrupted object: missing type.');
|
|
520
|
+
return type;
|
|
521
|
+
};
|
|
475
522
|
|
|
476
523
|
/**
|
|
477
|
-
* Get the
|
|
478
|
-
*
|
|
524
|
+
* Get the type entity (`Type.AnyObj`) the object was created from.
|
|
525
|
+
*
|
|
526
|
+
* Returns `undefined` when the object's type isn't registered in this runtime
|
|
527
|
+
* (e.g. a freshly deserialized snapshot whose type entity hasn't been wired
|
|
528
|
+
* up yet, or an object loaded from storage before its schema is known). To
|
|
529
|
+
* get the Effect Schema from the returned entity, use `Type.getSchema(...)`.
|
|
479
530
|
*/
|
|
480
|
-
|
|
481
|
-
|
|
531
|
+
export const getType = (obj: Unknown | Snapshot): Type.AnyObj | undefined =>
|
|
532
|
+
internal.getType(obj) as Type.AnyObj | undefined;
|
|
482
533
|
|
|
483
534
|
/**
|
|
484
535
|
* @returns The typename of the object's type.
|
|
@@ -510,13 +561,13 @@ export const getDatabase = (entity: Entity.Unknown | Entity.Snapshot): Database.
|
|
|
510
561
|
export const Meta = internal.MetaId;
|
|
511
562
|
|
|
512
563
|
/**
|
|
513
|
-
* Deeply read-only version of
|
|
564
|
+
* Deeply read-only version of EntityMeta.
|
|
514
565
|
* Prevents mutation at all nesting levels (e.g., `meta.keys.push()` is a TypeScript error).
|
|
515
566
|
*/
|
|
516
567
|
export type ReadonlyMeta = internal.ReadonlyMeta;
|
|
517
568
|
|
|
518
569
|
/**
|
|
519
|
-
* Mutable meta type returned by `Obj.getMeta` inside an `Obj.
|
|
570
|
+
* Mutable meta type returned by `Obj.getMeta` inside an `Obj.update` callback.
|
|
520
571
|
*/
|
|
521
572
|
export type Meta = internal.Meta;
|
|
522
573
|
|
|
@@ -524,7 +575,7 @@ export type Meta = internal.Meta;
|
|
|
524
575
|
// TODO(dmaretskyi): Allow returning undefined.
|
|
525
576
|
/**
|
|
526
577
|
* Get the metadata for an object.
|
|
527
|
-
* Returns mutable meta when passed a mutable object (inside `Obj.
|
|
578
|
+
* Returns mutable meta when passed a mutable object (inside `Obj.update` callback).
|
|
528
579
|
* Returns read-only meta when passed a regular object or snapshot.
|
|
529
580
|
*
|
|
530
581
|
* @example
|
|
@@ -533,10 +584,9 @@ export type Meta = internal.Meta;
|
|
|
533
584
|
* const meta = Obj.getMeta(person); // ReadonlyMeta
|
|
534
585
|
*
|
|
535
586
|
* // Mutable access inside change callback
|
|
536
|
-
* Obj.
|
|
537
|
-
* const meta = Obj.getMeta(
|
|
538
|
-
* meta.tags
|
|
539
|
-
* meta.tags.push('important');
|
|
587
|
+
* Obj.update(person, (obj) => {
|
|
588
|
+
* const meta = Obj.getMeta(obj); // EntityMeta (mutable)
|
|
589
|
+
* meta.tags.push(Ref.make(tag)); // tags are refs to Tag objects
|
|
540
590
|
* });
|
|
541
591
|
* ```
|
|
542
592
|
*/
|
|
@@ -558,7 +608,7 @@ export const getKeys: {
|
|
|
558
608
|
|
|
559
609
|
/**
|
|
560
610
|
* Delete all keys from the object for the specified source.
|
|
561
|
-
* Must be called within an `Obj.
|
|
611
|
+
* Must be called within an `Obj.update` callback.
|
|
562
612
|
*
|
|
563
613
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
564
614
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -567,21 +617,21 @@ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => in
|
|
|
567
617
|
|
|
568
618
|
/**
|
|
569
619
|
* Add a tag to the object.
|
|
570
|
-
* Must be called within an `Obj.
|
|
620
|
+
* Must be called within an `Obj.update` callback.
|
|
571
621
|
*
|
|
572
622
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
573
623
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
574
624
|
*/
|
|
575
|
-
export const addTag = (entity: Mutable<Unknown>, tag:
|
|
625
|
+
export const addTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.addTag(entity, tag);
|
|
576
626
|
|
|
577
627
|
/**
|
|
578
628
|
* Remove a tag from the object.
|
|
579
|
-
* Must be called within an `Obj.
|
|
629
|
+
* Must be called within an `Obj.update` callback.
|
|
580
630
|
*
|
|
581
631
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
582
632
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
583
633
|
*/
|
|
584
|
-
export const removeTag = (entity: Mutable<Unknown>, tag:
|
|
634
|
+
export const removeTag = (entity: Mutable<Unknown>, tag: Ref.Ref<Tag.Tag>): void => internal.removeTag(entity, tag);
|
|
585
635
|
|
|
586
636
|
/**
|
|
587
637
|
* Check if the object is deleted.
|
|
@@ -597,12 +647,16 @@ export const isDeleted = (entity: Unknown | Snapshot): boolean => objInternal.is
|
|
|
597
647
|
/**
|
|
598
648
|
* Get the label of the object.
|
|
599
649
|
* Accepts both reactive objects and snapshots.
|
|
650
|
+
*
|
|
651
|
+
* @param options.fallback `'typename'` returns the object's typename when no
|
|
652
|
+
* label is set (e.g. `org.dxos.type.table`).
|
|
600
653
|
*/
|
|
601
|
-
export const getLabel = (entity: Unknown | Snapshot): string | undefined =>
|
|
654
|
+
export const getLabel = (entity: Unknown | Snapshot, options?: internal.GetLabelOptions): string | undefined =>
|
|
655
|
+
internal.getLabel(entity, options);
|
|
602
656
|
|
|
603
657
|
/**
|
|
604
658
|
* Set the label of the object.
|
|
605
|
-
* Must be called within an `Obj.
|
|
659
|
+
* Must be called within an `Obj.update` callback.
|
|
606
660
|
*
|
|
607
661
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
608
662
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -615,9 +669,20 @@ export const setLabel = (entity: Mutable<Unknown>, label: string): void => inter
|
|
|
615
669
|
*/
|
|
616
670
|
export const getDescription = (entity: Unknown | Snapshot): string | undefined => internal.getDescription(entity);
|
|
617
671
|
|
|
672
|
+
/**
|
|
673
|
+
* Get the icon annotation for the object (or any entity), resolved via its type-level
|
|
674
|
+
* `IconAnnotation`. Accepts both reactive entities and snapshots, and either Objects or
|
|
675
|
+
* Relations — the underlying schema-based lookup works for both.
|
|
676
|
+
*
|
|
677
|
+
* Returns the full `{ icon, hue }` annotation; callers wanting just the icon name typically
|
|
678
|
+
* write `Obj.getIcon(obj)?.icon ?? 'ph--cube--regular'`.
|
|
679
|
+
*/
|
|
680
|
+
export const getIcon = (entity: Entity.Unknown | Entity.Snapshot): internal.IconAnnotation | undefined =>
|
|
681
|
+
internal.getIcon(entity);
|
|
682
|
+
|
|
618
683
|
/**
|
|
619
684
|
* Set the description of the object.
|
|
620
|
-
* Must be called within an `Obj.
|
|
685
|
+
* Must be called within an `Obj.update` callback.
|
|
621
686
|
*
|
|
622
687
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
623
688
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -644,7 +709,7 @@ export const Parent: unique symbol = internal.ParentId as any;
|
|
|
644
709
|
* @returns The parent object, or undefined if the object has no parent.
|
|
645
710
|
*/
|
|
646
711
|
export const getParent = (entity: Unknown | Snapshot): Unknown | undefined => {
|
|
647
|
-
assertArgument(isObject(entity), 'Expected an object');
|
|
712
|
+
assertArgument(isObject(entity) || isSnapshot(entity), 'Expected an object');
|
|
648
713
|
assumeType<internal.InternalObjectProps>(entity);
|
|
649
714
|
return entity[internal.ParentId] as Unknown | undefined;
|
|
650
715
|
};
|
|
@@ -660,6 +725,123 @@ export const setParent = (entity: Unknown, parent: Any | undefined) => {
|
|
|
660
725
|
assumeType<internal.InternalObjectProps>(entity);
|
|
661
726
|
assumeType<internal.InternalObjectProps | undefined>(parent);
|
|
662
727
|
entity[internal.ParentId] = parent;
|
|
728
|
+
return entity;
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
interface UpdateFromOptions<T> {
|
|
732
|
+
exclude?: (keyof T)[];
|
|
733
|
+
include?: (keyof T)[];
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const valuesEqual = (left: unknown, right: unknown): boolean => {
|
|
737
|
+
if (left === right) {
|
|
738
|
+
return true;
|
|
739
|
+
}
|
|
740
|
+
if (left === null || right === null) {
|
|
741
|
+
return left === right;
|
|
742
|
+
}
|
|
743
|
+
if (typeof left !== 'object' || typeof right !== 'object') {
|
|
744
|
+
return Utils.structuralRegion(() => Equal.equals(left, right));
|
|
745
|
+
}
|
|
746
|
+
if (Ref.isRef(left) && Ref.isRef(right)) {
|
|
747
|
+
return left.uri === right.uri;
|
|
748
|
+
}
|
|
749
|
+
if (Ref.isRef(left) || Ref.isRef(right)) {
|
|
750
|
+
return false;
|
|
751
|
+
}
|
|
752
|
+
if (Array.isArray(left) && Array.isArray(right)) {
|
|
753
|
+
if (left.length !== right.length) {
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
for (let index = 0; index < left.length; index++) {
|
|
757
|
+
if (!valuesEqual(left[index], right[index])) {
|
|
758
|
+
return false;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return true;
|
|
762
|
+
}
|
|
763
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
764
|
+
return false;
|
|
765
|
+
}
|
|
766
|
+
const leftRecord = left as Record<string, unknown>;
|
|
767
|
+
const rightRecord = right as Record<string, unknown>;
|
|
768
|
+
const keys = new Set([
|
|
769
|
+
...Object.keys(leftRecord).filter((key) => key !== 'id'),
|
|
770
|
+
...Object.keys(rightRecord).filter((key) => key !== 'id'),
|
|
771
|
+
]);
|
|
772
|
+
for (const key of keys) {
|
|
773
|
+
const leftHas = Object.hasOwn(leftRecord, key);
|
|
774
|
+
const rightHas = Object.hasOwn(rightRecord, key);
|
|
775
|
+
const leftValue = leftHas ? leftRecord[key] : undefined;
|
|
776
|
+
const rightValue = rightHas ? rightRecord[key] : undefined;
|
|
777
|
+
if (!valuesEqual(leftValue, rightValue)) {
|
|
778
|
+
return false;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
return true;
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
/**
|
|
785
|
+
* Breaks reactive proxies on assigned values so echo-db assignment accepts nested structs (same idea as link assignment).
|
|
786
|
+
*/
|
|
787
|
+
const prepareAssignValue = (value: unknown): unknown =>
|
|
788
|
+
deepMapValues(value, (nested, recurse) => {
|
|
789
|
+
if (nested === null || typeof nested !== 'object') {
|
|
790
|
+
return nested;
|
|
791
|
+
}
|
|
792
|
+
if (Ref.isRef(nested)) {
|
|
793
|
+
return nested;
|
|
794
|
+
}
|
|
795
|
+
if (Array.isArray(nested)) {
|
|
796
|
+
return recurse(nested);
|
|
797
|
+
}
|
|
798
|
+
if (isProxy(nested)) {
|
|
799
|
+
return recurse({ ...getProxyTarget(nested) });
|
|
800
|
+
}
|
|
801
|
+
return recurse(nested);
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* For each key present on `source` (except `id`), assigns `target[key]` when the current value differs.
|
|
806
|
+
* References are compared by target DXN; other values use Effect `Equal.equals` inside a structural region,
|
|
807
|
+
* with recursive comparison for arrays and plain object-shaped property bags (excluding `id`).
|
|
808
|
+
*
|
|
809
|
+
* Must be called within an `Obj.update` callback.
|
|
810
|
+
*
|
|
811
|
+
* @returns Whether any property was updated.
|
|
812
|
+
*/
|
|
813
|
+
export const updateFrom = <T extends Unknown>(
|
|
814
|
+
target: Mutable<T>,
|
|
815
|
+
source: T,
|
|
816
|
+
options?: UpdateFromOptions<T>,
|
|
817
|
+
): boolean => {
|
|
818
|
+
assertArgument(isObject(target), 'Expected an echo object target.');
|
|
819
|
+
assertArgument(isObject(source), 'Expected an echo object source.');
|
|
820
|
+
let keys = Object.keys(source as Record<string, unknown>).filter((key) => key !== 'id');
|
|
821
|
+
if (options?.include !== undefined) {
|
|
822
|
+
const include = new Set(options.include.map((key) => String(key)));
|
|
823
|
+
keys = keys.filter((key) => include.has(key));
|
|
824
|
+
}
|
|
825
|
+
if (options?.exclude !== undefined) {
|
|
826
|
+
const exclude = new Set(options.exclude.map((key) => String(key)));
|
|
827
|
+
keys = keys.filter((key) => !exclude.has(key));
|
|
828
|
+
}
|
|
829
|
+
let updated = false;
|
|
830
|
+
const sourceRecord = source as Record<string, unknown>;
|
|
831
|
+
const targetRecord = target as Record<string, unknown>;
|
|
832
|
+
for (const key of keys) {
|
|
833
|
+
if (!Object.hasOwn(sourceRecord, key)) {
|
|
834
|
+
continue;
|
|
835
|
+
}
|
|
836
|
+
const nextValue = sourceRecord[key];
|
|
837
|
+
const prevValue = Object.hasOwn(targetRecord, key) ? targetRecord[key] : undefined;
|
|
838
|
+
if (valuesEqual(prevValue, nextValue)) {
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
targetRecord[key] = prepareAssignValue(nextValue) as never;
|
|
842
|
+
updated = true;
|
|
843
|
+
}
|
|
844
|
+
return updated;
|
|
663
845
|
};
|
|
664
846
|
|
|
665
847
|
//
|
|
@@ -686,12 +868,12 @@ export const toJSON = (entity: Unknown | Snapshot): JSON => objInternal.objectTo
|
|
|
686
868
|
* The function must be async to support resolving the schema as well as the relation endpoints.
|
|
687
869
|
*
|
|
688
870
|
* @param options.refResolver - Resolver for references. Produces hydrated references that can be resolved.
|
|
689
|
-
* @param options.
|
|
871
|
+
* @param options.uri - Override object URI. Changes the result of `Obj.getURI`.
|
|
690
872
|
* @param options.database - Database to associate with the object.
|
|
691
873
|
*/
|
|
692
874
|
export const fromJSON: (
|
|
693
875
|
json: unknown,
|
|
694
|
-
options?: { refResolver?: Ref.Resolver;
|
|
876
|
+
options?: { refResolver?: Ref.Resolver; uri?: URI.URI; database?: Database.Database; parent?: Unknown },
|
|
695
877
|
) => Promise<Unknown> = objInternal.objectFromJSON as any;
|
|
696
878
|
|
|
697
879
|
/**
|