@dxos/echo 0.8.4-main.84f28bd → 0.8.4-main.937b3ca
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/README.md +2 -3
- package/dist/lib/browser/Annotation.mjs +33 -0
- package/dist/lib/browser/Annotation.mjs.map +7 -0
- package/dist/lib/browser/Database.mjs +18 -0
- package/dist/lib/browser/Database.mjs.map +7 -0
- package/dist/lib/browser/Entity.mjs +52 -0
- package/dist/lib/browser/Entity.mjs.map +7 -0
- package/dist/lib/browser/Err.mjs +11 -0
- package/dist/lib/browser/Err.mjs.map +7 -0
- package/dist/lib/browser/Filter.mjs +62 -0
- package/dist/lib/browser/Filter.mjs.map +7 -0
- package/dist/lib/browser/Format.mjs +67 -0
- package/dist/lib/browser/Format.mjs.map +7 -0
- package/dist/lib/browser/JsonSchema.mjs +20 -0
- package/dist/lib/browser/JsonSchema.mjs.map +7 -0
- package/dist/lib/browser/Key.mjs +13 -0
- package/dist/lib/browser/Key.mjs.map +7 -0
- package/dist/lib/browser/Obj.mjs +91 -0
- package/dist/lib/browser/Obj.mjs.map +7 -0
- package/dist/lib/browser/Order.mjs +13 -0
- package/dist/lib/browser/Order.mjs.map +7 -0
- package/dist/lib/browser/Query.mjs +27 -0
- package/dist/lib/browser/Query.mjs.map +7 -0
- package/dist/lib/browser/QueryResult.mjs +3 -0
- package/dist/lib/browser/QueryResult.mjs.map +7 -0
- package/dist/lib/browser/Ref.mjs +23 -0
- package/dist/lib/browser/Ref.mjs.map +7 -0
- package/dist/lib/browser/Relation.mjs +85 -0
- package/dist/lib/browser/Relation.mjs.map +7 -0
- package/dist/lib/browser/SchemaRegistry.mjs +3 -0
- package/dist/lib/browser/SchemaRegistry.mjs.map +7 -0
- package/dist/lib/browser/Tag.mjs +26 -0
- package/dist/lib/browser/Tag.mjs.map +7 -0
- package/dist/lib/browser/Type.mjs +48 -0
- package/dist/lib/browser/Type.mjs.map +7 -0
- package/dist/lib/browser/chunk-22JMFST2.mjs +24 -0
- package/dist/lib/browser/chunk-22JMFST2.mjs.map +7 -0
- package/dist/lib/browser/chunk-2SBB7OWV.mjs +250 -0
- package/dist/lib/browser/chunk-2SBB7OWV.mjs.map +7 -0
- package/dist/lib/browser/chunk-6L5HHUVU.mjs +158 -0
- package/dist/lib/browser/chunk-6L5HHUVU.mjs.map +7 -0
- package/dist/lib/browser/chunk-7STIBCP7.mjs +133 -0
- package/dist/lib/browser/chunk-7STIBCP7.mjs.map +7 -0
- package/dist/lib/browser/chunk-BJPE6CIC.mjs +3847 -0
- package/dist/lib/browser/chunk-BJPE6CIC.mjs.map +7 -0
- package/dist/lib/browser/chunk-CGS2ULMK.mjs +11 -0
- package/dist/lib/browser/chunk-CGS2ULMK.mjs.map +7 -0
- package/dist/lib/browser/chunk-CJ5YELTO.mjs +39 -0
- package/dist/lib/browser/chunk-CJ5YELTO.mjs.map +7 -0
- package/dist/lib/browser/chunk-FPOISFQK.mjs +40 -0
- package/dist/lib/browser/chunk-FPOISFQK.mjs.map +7 -0
- package/dist/lib/browser/chunk-FRDT7RA4.mjs +403 -0
- package/dist/lib/browser/chunk-FRDT7RA4.mjs.map +7 -0
- package/dist/lib/browser/chunk-INHXFXY5.mjs +22 -0
- package/dist/lib/browser/chunk-INHXFXY5.mjs.map +7 -0
- package/dist/lib/browser/chunk-IXVWLTG7.mjs +9 -0
- package/dist/lib/browser/chunk-IXVWLTG7.mjs.map +7 -0
- package/dist/lib/browser/chunk-JMKVF2YQ.mjs +43 -0
- package/dist/lib/browser/chunk-JMKVF2YQ.mjs.map +7 -0
- package/dist/lib/browser/chunk-KQQGVHFN.mjs +143 -0
- package/dist/lib/browser/chunk-KQQGVHFN.mjs.map +7 -0
- package/dist/lib/browser/chunk-MYCCGG2T.mjs +15 -0
- package/dist/lib/browser/chunk-MYCCGG2T.mjs.map +7 -0
- package/dist/lib/browser/chunk-NOPVNWPT.mjs +204 -0
- package/dist/lib/browser/chunk-NOPVNWPT.mjs.map +7 -0
- package/dist/lib/browser/chunk-PQZW3S6L.mjs +74 -0
- package/dist/lib/browser/chunk-PQZW3S6L.mjs.map +7 -0
- package/dist/lib/browser/chunk-RK4Z4JUZ.mjs +283 -0
- package/dist/lib/browser/chunk-RK4Z4JUZ.mjs.map +7 -0
- package/dist/lib/browser/chunk-U2J7TA7K.mjs +57 -0
- package/dist/lib/browser/chunk-U2J7TA7K.mjs.map +7 -0
- package/dist/lib/browser/chunk-W5D2GWAW.mjs +98 -0
- package/dist/lib/browser/chunk-W5D2GWAW.mjs.map +7 -0
- package/dist/lib/browser/chunk-XDIUHAAX.mjs +41 -0
- package/dist/lib/browser/chunk-XDIUHAAX.mjs.map +7 -0
- package/dist/lib/browser/chunk-YKTSSMDS.mjs +69 -0
- package/dist/lib/browser/chunk-YKTSSMDS.mjs.map +7 -0
- package/dist/lib/browser/chunk-ZAGAOZVY.mjs +288 -0
- package/dist/lib/browser/chunk-ZAGAOZVY.mjs.map +7 -0
- package/dist/lib/browser/chunk-ZHXZGIXD.mjs +9 -0
- package/dist/lib/browser/chunk-ZHXZGIXD.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +72 -9
- package/dist/lib/browser/internal/index.mjs +457 -0
- package/dist/lib/browser/internal/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +332 -35
- package/dist/lib/browser/testing/index.mjs.map +4 -4
- package/dist/lib/node-esm/Annotation.mjs +33 -0
- package/dist/lib/node-esm/Annotation.mjs.map +7 -0
- package/dist/lib/node-esm/Database.mjs +18 -0
- package/dist/lib/node-esm/Database.mjs.map +7 -0
- package/dist/lib/node-esm/Entity.mjs +52 -0
- package/dist/lib/node-esm/Entity.mjs.map +7 -0
- package/dist/lib/node-esm/Err.mjs +11 -0
- package/dist/lib/node-esm/Err.mjs.map +7 -0
- package/dist/lib/node-esm/Filter.mjs +62 -0
- package/dist/lib/node-esm/Filter.mjs.map +7 -0
- package/dist/lib/node-esm/Format.mjs +67 -0
- package/dist/lib/node-esm/Format.mjs.map +7 -0
- package/dist/lib/node-esm/JsonSchema.mjs +20 -0
- package/dist/lib/node-esm/JsonSchema.mjs.map +7 -0
- package/dist/lib/node-esm/Key.mjs +13 -0
- package/dist/lib/node-esm/Key.mjs.map +7 -0
- package/dist/lib/node-esm/Obj.mjs +91 -0
- package/dist/lib/node-esm/Obj.mjs.map +7 -0
- package/dist/lib/node-esm/Order.mjs +13 -0
- package/dist/lib/node-esm/Order.mjs.map +7 -0
- package/dist/lib/node-esm/Query.mjs +27 -0
- package/dist/lib/node-esm/Query.mjs.map +7 -0
- package/dist/lib/node-esm/QueryResult.mjs +3 -0
- package/dist/lib/node-esm/QueryResult.mjs.map +7 -0
- package/dist/lib/node-esm/Ref.mjs +23 -0
- package/dist/lib/node-esm/Ref.mjs.map +7 -0
- package/dist/lib/node-esm/Relation.mjs +85 -0
- package/dist/lib/node-esm/Relation.mjs.map +7 -0
- package/dist/lib/node-esm/SchemaRegistry.mjs +3 -0
- package/dist/lib/node-esm/SchemaRegistry.mjs.map +7 -0
- package/dist/lib/node-esm/Tag.mjs +26 -0
- package/dist/lib/node-esm/Tag.mjs.map +7 -0
- package/dist/lib/node-esm/Type.mjs +48 -0
- package/dist/lib/node-esm/Type.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-4PNXQA64.mjs +250 -0
- package/dist/lib/node-esm/chunk-4PNXQA64.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-5OBN7GZW.mjs +158 -0
- package/dist/lib/node-esm/chunk-5OBN7GZW.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-AJEMYSIR.mjs +22 -0
- package/dist/lib/node-esm/chunk-AJEMYSIR.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ANLVLWME.mjs +98 -0
- package/dist/lib/node-esm/chunk-ANLVLWME.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-DMR7OAFK.mjs +57 -0
- package/dist/lib/node-esm/chunk-DMR7OAFK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-FWTSPIFF.mjs +133 -0
- package/dist/lib/node-esm/chunk-FWTSPIFF.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
- package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ILMLLM4R.mjs +204 -0
- package/dist/lib/node-esm/chunk-ILMLLM4R.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-K37NA7PO.mjs +43 -0
- package/dist/lib/node-esm/chunk-K37NA7PO.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-LT3H4JOX.mjs +3847 -0
- package/dist/lib/node-esm/chunk-LT3H4JOX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-MOLNWFNL.mjs +9 -0
- package/dist/lib/node-esm/chunk-MOLNWFNL.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-MOWUEW5P.mjs +15 -0
- package/dist/lib/node-esm/chunk-MOWUEW5P.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NBWL7UCZ.mjs +40 -0
- package/dist/lib/node-esm/chunk-NBWL7UCZ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-NRN3ZW2T.mjs +143 -0
- package/dist/lib/node-esm/chunk-NRN3ZW2T.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QLI2EIJ2.mjs +41 -0
- package/dist/lib/node-esm/chunk-QLI2EIJ2.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-QYR67VBV.mjs +288 -0
- package/dist/lib/node-esm/chunk-QYR67VBV.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-UKGVOINP.mjs +9 -0
- package/dist/lib/node-esm/chunk-UKGVOINP.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-W6QIEBTQ.mjs +403 -0
- package/dist/lib/node-esm/chunk-W6QIEBTQ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-XHJRMQZD.mjs +69 -0
- package/dist/lib/node-esm/chunk-XHJRMQZD.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-Y75VU7LB.mjs +74 -0
- package/dist/lib/node-esm/chunk-Y75VU7LB.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-YOLH5KS4.mjs +283 -0
- package/dist/lib/node-esm/chunk-YOLH5KS4.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-YQ2NWGL5.mjs +39 -0
- package/dist/lib/node-esm/chunk-YQ2NWGL5.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ZBB67AKD.mjs +24 -0
- package/dist/lib/node-esm/chunk-ZBB67AKD.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +72 -9
- package/dist/lib/node-esm/internal/index.mjs +457 -0
- package/dist/lib/node-esm/internal/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +332 -35
- package/dist/lib/node-esm/testing/index.mjs.map +4 -4
- package/dist/types/src/Annotation.d.ts +2 -0
- package/dist/types/src/Annotation.d.ts.map +1 -0
- package/dist/types/src/Database.d.ts +194 -0
- package/dist/types/src/Database.d.ts.map +1 -0
- package/dist/types/src/Entity.d.ts +142 -0
- package/dist/types/src/Entity.d.ts.map +1 -0
- package/dist/types/src/Entity.test.d.ts +2 -0
- package/dist/types/src/Entity.test.d.ts.map +1 -0
- package/dist/types/src/Err.d.ts +64 -0
- package/dist/types/src/Err.d.ts.map +1 -0
- package/dist/types/src/Filter.d.ts +120 -0
- package/dist/types/src/Filter.d.ts.map +1 -0
- package/dist/types/src/Format.d.ts +4 -0
- package/dist/types/src/Format.d.ts.map +1 -0
- package/dist/types/src/Hypergraph.d.ts +60 -0
- package/dist/types/src/Hypergraph.d.ts.map +1 -0
- package/dist/types/src/JsonSchema.d.ts +9 -0
- package/dist/types/src/JsonSchema.d.ts.map +1 -0
- package/dist/types/src/Key.d.ts +1 -0
- package/dist/types/src/Key.d.ts.map +1 -1
- package/dist/types/src/Obj.d.ts +344 -34
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Obj.test.d.ts +2 -0
- package/dist/types/src/Obj.test.d.ts.map +1 -0
- package/dist/types/src/Order.d.ts +16 -0
- package/dist/types/src/Order.d.ts.map +1 -0
- package/dist/types/src/Query.d.ts +115 -0
- package/dist/types/src/Query.d.ts.map +1 -0
- package/dist/types/src/Query.test.d.ts +2 -0
- package/dist/types/src/Query.test.d.ts.map +1 -0
- package/dist/types/src/QueryResult.d.ts +80 -0
- package/dist/types/src/QueryResult.d.ts.map +1 -0
- package/dist/types/src/Ref.d.ts +13 -11
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +242 -19
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Relation.test.d.ts +2 -0
- package/dist/types/src/Relation.test.d.ts.map +1 -0
- package/dist/types/src/SchemaRegistry.d.ts +84 -0
- package/dist/types/src/SchemaRegistry.d.ts.map +1 -0
- package/dist/types/src/Tag.d.ts +17 -0
- package/dist/types/src/Tag.d.ts.map +1 -0
- package/dist/types/src/Type.d.ts +225 -73
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/Type.test.d.ts +2 -0
- package/dist/types/src/Type.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +15 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/annotations/annotations.d.ts +170 -0
- package/dist/types/src/internal/annotations/annotations.d.ts.map +1 -0
- package/dist/types/src/internal/annotations/annotations.test.d.ts +2 -0
- package/dist/types/src/internal/annotations/annotations.test.d.ts.map +1 -0
- package/dist/types/src/internal/annotations/index.d.ts +3 -0
- package/dist/types/src/internal/annotations/index.d.ts.map +1 -0
- package/dist/types/src/internal/annotations/util.d.ts +27 -0
- package/dist/types/src/internal/annotations/util.d.ts.map +1 -0
- package/dist/types/src/internal/api/annotations.d.ts +23 -0
- package/dist/types/src/internal/api/annotations.d.ts.map +1 -0
- package/dist/types/src/internal/api/entity.d.ts +13 -0
- package/dist/types/src/internal/api/entity.d.ts.map +1 -0
- package/dist/types/src/internal/api/index.d.ts +15 -0
- package/dist/types/src/internal/api/index.d.ts.map +1 -0
- package/dist/types/src/internal/api/meta.d.ts +42 -0
- package/dist/types/src/internal/api/meta.d.ts.map +1 -0
- package/dist/types/src/internal/api/sorting.d.ts +24 -0
- package/dist/types/src/internal/api/sorting.d.ts.map +1 -0
- package/dist/types/src/internal/api/version.d.ts +42 -0
- package/dist/types/src/internal/api/version.d.ts.map +1 -0
- package/dist/types/src/internal/entities/entity.d.ts +20 -0
- package/dist/types/src/internal/entities/entity.d.ts.map +1 -0
- package/dist/types/src/internal/entities/index.d.ts +6 -0
- package/dist/types/src/internal/entities/index.d.ts.map +1 -0
- package/dist/types/src/internal/entities/model.d.ts +77 -0
- package/dist/types/src/internal/entities/model.d.ts.map +1 -0
- package/dist/types/src/internal/entities/object.d.ts +18 -0
- package/dist/types/src/internal/entities/object.d.ts.map +1 -0
- package/dist/types/src/internal/entities/relation.d.ts +62 -0
- package/dist/types/src/internal/entities/relation.d.ts.map +1 -0
- package/dist/types/src/internal/entities/util.d.ts +2 -0
- package/dist/types/src/internal/entities/util.d.ts.map +1 -0
- package/dist/types/src/internal/formats/date.d.ts +63 -0
- package/dist/types/src/internal/formats/date.d.ts.map +1 -0
- package/dist/types/src/internal/formats/date.test.d.ts +2 -0
- package/dist/types/src/internal/formats/date.test.d.ts.map +1 -0
- package/dist/types/src/internal/formats/format.d.ts +32 -0
- package/dist/types/src/internal/formats/format.d.ts.map +1 -0
- package/dist/types/src/internal/formats/format.test.d.ts +2 -0
- package/dist/types/src/internal/formats/format.test.d.ts.map +1 -0
- package/dist/types/src/internal/formats/index.d.ts +8 -0
- package/dist/types/src/internal/formats/index.d.ts.map +1 -0
- package/dist/types/src/internal/formats/number.d.ts +31 -0
- package/dist/types/src/internal/formats/number.d.ts.map +1 -0
- package/dist/types/src/internal/formats/object.d.ts +35 -0
- package/dist/types/src/internal/formats/object.d.ts.map +1 -0
- package/dist/types/src/internal/formats/select.d.ts +13 -0
- package/dist/types/src/internal/formats/select.d.ts.map +1 -0
- package/dist/types/src/internal/formats/string.d.ts +42 -0
- package/dist/types/src/internal/formats/string.d.ts.map +1 -0
- package/dist/types/src/internal/formats/types.d.ts +72 -0
- package/dist/types/src/internal/formats/types.d.ts.map +1 -0
- package/dist/types/src/internal/index.d.ts +12 -0
- package/dist/types/src/internal/index.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/annotations.d.ts +19 -0
- package/dist/types/src/internal/json-schema/annotations.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/effect-schema.test.d.ts +2 -0
- package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/index.d.ts +5 -0
- package/dist/types/src/internal/json-schema/index.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts +7 -0
- package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/json-schema-type.d.ts +250 -0
- package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/json-schema.d.ts +29 -0
- package/dist/types/src/internal/json-schema/json-schema.d.ts.map +1 -0
- package/dist/types/src/internal/json-schema/json-schema.test.d.ts +2 -0
- package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/object/clone.d.ts +8 -0
- package/dist/types/src/internal/object/clone.d.ts.map +1 -0
- package/dist/types/src/internal/object/common.d.ts +18 -0
- package/dist/types/src/internal/object/common.d.ts.map +1 -0
- package/dist/types/src/internal/object/create-object.d.ts +39 -0
- package/dist/types/src/internal/object/create-object.d.ts.map +1 -0
- package/dist/types/src/internal/object/create-object.test.d.ts +2 -0
- package/dist/types/src/internal/object/create-object.test.d.ts.map +1 -0
- package/dist/types/src/internal/object/deleted.d.ts +6 -0
- package/dist/types/src/internal/object/deleted.d.ts.map +1 -0
- package/dist/types/src/internal/object/ids.d.ts +6 -0
- package/dist/types/src/internal/object/ids.d.ts.map +1 -0
- package/dist/types/src/internal/object/index.d.ts +11 -0
- package/dist/types/src/internal/object/index.d.ts.map +1 -0
- package/dist/types/src/internal/object/inspect.d.ts +2 -0
- package/dist/types/src/internal/object/inspect.d.ts.map +1 -0
- package/dist/types/src/internal/object/json-serializer.d.ts +37 -0
- package/dist/types/src/internal/object/json-serializer.d.ts.map +1 -0
- package/dist/types/src/internal/object/json-serializer.test.d.ts +2 -0
- package/dist/types/src/internal/object/json-serializer.test.d.ts.map +1 -0
- package/dist/types/src/internal/object/schema-validator.d.ts +2 -0
- package/dist/types/src/internal/object/schema-validator.d.ts.map +1 -0
- package/dist/types/src/internal/object/schema-validator.test.d.ts +2 -0
- package/dist/types/src/internal/object/schema-validator.test.d.ts.map +1 -0
- package/dist/types/src/internal/object/set-value.d.ts +7 -0
- package/dist/types/src/internal/object/set-value.d.ts.map +1 -0
- package/dist/types/src/internal/object/set-value.test.d.ts +2 -0
- package/dist/types/src/internal/object/set-value.test.d.ts.map +1 -0
- package/dist/types/src/internal/object/snapshot.d.ts +6 -0
- package/dist/types/src/internal/object/snapshot.d.ts.map +1 -0
- package/dist/types/src/internal/object/typed-object.d.ts +25 -0
- package/dist/types/src/internal/object/typed-object.d.ts.map +1 -0
- package/dist/types/src/internal/object/typed-object.test.d.ts +2 -0
- package/dist/types/src/internal/object/typed-object.test.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/change-context.d.ts +55 -0
- package/dist/types/src/internal/proxy/change-context.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/change.test.d.ts +2 -0
- package/dist/types/src/internal/proxy/change.test.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/define-hidden-property.d.ts +5 -0
- package/dist/types/src/internal/proxy/define-hidden-property.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/errors.d.ts +19 -0
- package/dist/types/src/internal/proxy/errors.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/event-batch.d.ts +10 -0
- package/dist/types/src/internal/proxy/event-batch.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/handler.test.d.ts +2 -0
- package/dist/types/src/internal/proxy/handler.test.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/index.d.ts +14 -0
- package/dist/types/src/internal/proxy/index.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/json-serializer.d.ts +6 -0
- package/dist/types/src/internal/proxy/json-serializer.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/make-object.d.ts +14 -0
- package/dist/types/src/internal/proxy/make-object.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/ownership.d.ts +57 -0
- package/dist/types/src/internal/proxy/ownership.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/proxy-types.d.ts +18 -0
- package/dist/types/src/internal/proxy/proxy-types.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/proxy-utils.d.ts +47 -0
- package/dist/types/src/internal/proxy/proxy-utils.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/reactive-array.d.ts +8 -0
- package/dist/types/src/internal/proxy/reactive-array.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/reactive.d.ts +39 -0
- package/dist/types/src/internal/proxy/reactive.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/schema-validator.d.ts +15 -0
- package/dist/types/src/internal/proxy/schema-validator.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/schema.test.d.ts +2 -0
- package/dist/types/src/internal/proxy/schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/symbols.d.ts +3 -0
- package/dist/types/src/internal/proxy/symbols.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/typed-handler.d.ts +47 -0
- package/dist/types/src/internal/proxy/typed-handler.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/typed-handler.test.d.ts +2 -0
- package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +1 -0
- package/dist/types/src/internal/proxy/typed-object.test.d.ts +2 -0
- package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +1 -0
- package/dist/types/src/internal/ref/index.d.ts +3 -0
- package/dist/types/src/internal/ref/index.d.ts.map +1 -0
- package/dist/types/src/internal/ref/ref-array.d.ts +21 -0
- package/dist/types/src/internal/ref/ref-array.d.ts.map +1 -0
- package/dist/types/src/internal/ref/ref.d.ts +217 -0
- package/dist/types/src/internal/ref/ref.d.ts.map +1 -0
- package/dist/types/src/internal/ref/ref.test.d.ts +2 -0
- package/dist/types/src/internal/ref/ref.test.d.ts.map +1 -0
- package/dist/types/src/internal/schema/compose.d.ts +6 -0
- package/dist/types/src/internal/schema/compose.d.ts.map +1 -0
- package/dist/types/src/internal/schema/compose.test.d.ts +2 -0
- package/dist/types/src/internal/schema/compose.test.d.ts.map +1 -0
- package/dist/types/src/internal/schema/echo-schema.d.ts +180 -0
- package/dist/types/src/internal/schema/echo-schema.d.ts.map +1 -0
- package/dist/types/src/internal/schema/index.d.ts +4 -0
- package/dist/types/src/internal/schema/index.d.ts.map +1 -0
- package/dist/types/src/internal/schema/manipulation.d.ts +10 -0
- package/dist/types/src/internal/schema/manipulation.d.ts.map +1 -0
- package/dist/types/src/internal/schema/persistent-schema.d.ts +20 -0
- package/dist/types/src/internal/schema/persistent-schema.d.ts.map +1 -0
- package/dist/types/src/internal/types/base.d.ts +26 -0
- package/dist/types/src/internal/types/base.d.ts.map +1 -0
- package/dist/types/src/internal/types/entity.d.ts +37 -0
- package/dist/types/src/internal/types/entity.d.ts.map +1 -0
- package/dist/types/src/internal/types/index.d.ts +6 -0
- package/dist/types/src/internal/types/index.d.ts.map +1 -0
- package/dist/types/src/internal/types/meta.d.ts +32 -0
- package/dist/types/src/internal/types/meta.d.ts.map +1 -0
- package/dist/types/src/internal/types/typename.d.ts +13 -0
- package/dist/types/src/internal/types/typename.d.ts.map +1 -0
- package/dist/types/src/internal/types/version.d.ts +15 -0
- package/dist/types/src/internal/types/version.d.ts.map +1 -0
- package/dist/types/src/{test → testing}/api.test.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +3 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-data.d.ts +18 -0
- package/dist/types/src/testing/test-data.d.ts.map +1 -0
- package/dist/types/src/testing/test-schema.d.ts +303 -0
- package/dist/types/src/testing/test-schema.d.ts.map +1 -0
- package/dist/types/src/testing/util.d.ts +21 -0
- package/dist/types/src/testing/util.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +166 -33
- package/src/Annotation.ts +18 -0
- package/src/Database.ts +336 -0
- package/src/Entity.test.ts +22 -0
- package/src/Entity.ts +217 -0
- package/src/Err.ts +18 -0
- package/src/Filter.ts +376 -0
- package/src/Format.ts +9 -0
- package/src/Hypergraph.ts +74 -0
- package/src/JsonSchema.ts +16 -0
- package/src/Key.ts +3 -0
- package/src/Obj.test.ts +386 -0
- package/src/Obj.ts +509 -85
- package/src/Order.ts +44 -0
- package/src/Query.test.ts +465 -0
- package/src/Query.ts +296 -0
- package/src/QueryResult.ts +106 -0
- package/src/Ref.ts +25 -9
- package/src/Relation.test.ts +82 -0
- package/src/Relation.ts +414 -51
- package/src/SchemaRegistry.ts +105 -0
- package/src/Tag.ts +40 -0
- package/src/Type.test.ts +52 -0
- package/src/Type.ts +360 -112
- package/src/index.ts +17 -4
- package/src/internal/README.md +102 -0
- package/src/internal/annotations/annotations.test.ts +96 -0
- package/src/internal/annotations/annotations.ts +460 -0
- package/src/internal/annotations/index.ts +6 -0
- package/src/internal/annotations/util.ts +72 -0
- package/src/internal/api/annotations.ts +60 -0
- package/src/internal/api/entity.ts +29 -0
- package/src/internal/api/index.ts +19 -0
- package/src/internal/api/meta.ts +88 -0
- package/src/internal/api/sorting.ts +53 -0
- package/src/internal/api/version.ts +96 -0
- package/src/internal/entities/entity.ts +126 -0
- package/src/internal/entities/index.ts +9 -0
- package/src/internal/entities/model.ts +134 -0
- package/src/internal/entities/object.ts +60 -0
- package/src/internal/entities/relation.ts +173 -0
- package/src/internal/entities/util.ts +33 -0
- package/src/internal/formats/date.test.ts +56 -0
- package/src/internal/formats/date.ts +217 -0
- package/src/internal/formats/format.test.ts +77 -0
- package/src/internal/formats/format.ts +54 -0
- package/src/internal/formats/index.ts +12 -0
- package/src/internal/formats/number.ts +89 -0
- package/src/internal/formats/object.ts +80 -0
- package/src/internal/formats/select.ts +18 -0
- package/src/internal/formats/string.ts +81 -0
- package/src/internal/formats/types.ts +186 -0
- package/src/internal/index.ts +39 -0
- package/src/internal/json-schema/annotations.ts +50 -0
- package/src/internal/json-schema/effect-schema.test.ts +143 -0
- package/src/internal/json-schema/index.ts +8 -0
- package/src/internal/json-schema/json-schema-normalize.ts +109 -0
- package/src/internal/json-schema/json-schema-type.ts +404 -0
- package/src/internal/json-schema/json-schema.test.ts +861 -0
- package/src/internal/json-schema/json-schema.ts +528 -0
- package/src/internal/object/clone.ts +48 -0
- package/src/internal/object/common.ts +75 -0
- package/src/internal/object/create-object.test.ts +116 -0
- package/src/internal/object/create-object.ts +95 -0
- package/src/internal/object/deleted.ts +19 -0
- package/src/internal/object/ids.ts +12 -0
- package/src/internal/object/index.ts +14 -0
- package/src/internal/object/inspect.ts +46 -0
- package/src/internal/object/json-serializer.test.ts +97 -0
- package/src/internal/object/json-serializer.ts +188 -0
- package/src/internal/object/schema-validator.test.ts +186 -0
- package/src/internal/object/schema-validator.ts +6 -0
- package/src/internal/object/set-value.test.ts +281 -0
- package/src/internal/object/set-value.ts +165 -0
- package/src/internal/object/snapshot.ts +70 -0
- package/src/internal/object/typed-object.test.ts +34 -0
- package/src/internal/object/typed-object.ts +30 -0
- package/src/internal/proxy/change-context.ts +138 -0
- package/src/internal/proxy/change.test.ts +519 -0
- package/src/internal/proxy/define-hidden-property.ts +14 -0
- package/src/internal/proxy/errors.ts +42 -0
- package/src/internal/proxy/event-batch.ts +44 -0
- package/src/internal/proxy/handler.test.ts +123 -0
- package/src/internal/proxy/index.ts +17 -0
- package/src/internal/proxy/json-serializer.ts +87 -0
- package/src/internal/proxy/make-object.ts +96 -0
- package/src/internal/proxy/ownership.ts +253 -0
- package/src/internal/proxy/proxy-types.ts +23 -0
- package/src/internal/proxy/proxy-utils.ts +150 -0
- package/src/internal/proxy/reactive-array.ts +71 -0
- package/src/internal/proxy/reactive.ts +69 -0
- package/src/internal/proxy/schema-validator.ts +244 -0
- package/src/internal/proxy/schema.test.ts +145 -0
- package/src/internal/proxy/symbols.ts +7 -0
- package/src/internal/proxy/typed-handler.test.ts +318 -0
- package/src/internal/proxy/typed-handler.ts +442 -0
- package/src/internal/proxy/typed-object.test.ts +116 -0
- package/src/internal/ref/index.ts +6 -0
- package/src/internal/ref/ref-array.ts +39 -0
- package/src/internal/ref/ref.test.ts +101 -0
- package/src/internal/ref/ref.ts +548 -0
- package/src/internal/schema/compose.test.ts +42 -0
- package/src/internal/schema/compose.ts +36 -0
- package/src/internal/schema/echo-schema.ts +423 -0
- package/src/internal/schema/index.ts +7 -0
- package/src/internal/schema/manipulation.ts +92 -0
- package/src/internal/schema/persistent-schema.ts +27 -0
- package/src/internal/types/base.ts +43 -0
- package/src/internal/types/entity.ts +54 -0
- package/src/internal/types/index.ts +9 -0
- package/src/internal/types/meta.ts +66 -0
- package/src/internal/types/typename.ts +45 -0
- package/src/internal/types/version.ts +20 -0
- package/src/testing/api.test.ts +126 -0
- package/src/testing/index.ts +3 -1
- package/src/testing/test-data.ts +130 -0
- package/src/testing/test-schema.ts +238 -0
- package/src/testing/util.ts +85 -0
- package/dist/lib/browser/chunk-SVSJEELN.mjs +0 -619
- package/dist/lib/browser/chunk-SVSJEELN.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-53HXWYR6.mjs +0 -619
- package/dist/lib/node-esm/chunk-53HXWYR6.mjs.map +0 -7
- package/dist/types/src/experimental/database.d.ts +0 -8
- package/dist/types/src/experimental/database.d.ts.map +0 -1
- package/dist/types/src/experimental/index.d.ts +0 -1
- package/dist/types/src/experimental/index.d.ts.map +0 -1
- package/dist/types/src/experimental/queue.d.ts +0 -8
- package/dist/types/src/experimental/queue.d.ts.map +0 -1
- package/dist/types/src/experimental/space.d.ts +0 -8
- package/dist/types/src/experimental/space.d.ts.map +0 -1
- package/dist/types/src/query/dsl.d.ts +0 -218
- package/dist/types/src/query/dsl.d.ts.map +0 -1
- package/dist/types/src/query/dsl.test.d.ts +0 -2
- package/dist/types/src/query/dsl.test.d.ts.map +0 -1
- package/dist/types/src/query/index.d.ts +0 -2
- package/dist/types/src/query/index.d.ts.map +0 -1
- package/dist/types/src/testing/types.d.ts +0 -113
- package/dist/types/src/testing/types.d.ts.map +0 -1
- package/src/experimental/database.ts +0 -11
- package/src/experimental/index.ts +0 -7
- package/src/experimental/queue.ts +0 -11
- package/src/experimental/space.ts +0 -11
- package/src/query/dsl.test.ts +0 -323
- package/src/query/dsl.ts +0 -646
- package/src/query/index.ts +0 -5
- package/src/test/api.test.ts +0 -173
- package/src/testing/types.ts +0 -91
- /package/dist/types/src/{test → testing}/api.test.d.ts +0 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type InspectOptionsStylized } from 'node:util';
|
|
6
|
+
|
|
7
|
+
import * as Schema from 'effect/Schema';
|
|
8
|
+
import * as SchemaAST from 'effect/SchemaAST';
|
|
9
|
+
|
|
10
|
+
import { Event } from '@dxos/async';
|
|
11
|
+
import { inspectCustom } from '@dxos/debug';
|
|
12
|
+
import { invariant } from '@dxos/invariant';
|
|
13
|
+
|
|
14
|
+
import { getSchemaDXN } from '../annotations';
|
|
15
|
+
import { ObjectDeletedId } from '../entities';
|
|
16
|
+
import { SchemaId, TypeId } from '../types';
|
|
17
|
+
|
|
18
|
+
import { executeChange, isInChangeContext, queueNotification } from './change-context';
|
|
19
|
+
import { defineHiddenProperty } from './define-hidden-property';
|
|
20
|
+
import { createPropertyDeleteError } from './errors';
|
|
21
|
+
import { batchEvents } from './event-batch';
|
|
22
|
+
import {
|
|
23
|
+
getEchoRoot,
|
|
24
|
+
getOwner,
|
|
25
|
+
getRawTarget,
|
|
26
|
+
hasForeignOwner,
|
|
27
|
+
notifyOwnerChain,
|
|
28
|
+
setOwnerRecursive,
|
|
29
|
+
wouldCreateCycle,
|
|
30
|
+
} from './ownership';
|
|
31
|
+
import { type ReactiveHandler, objectData } from './proxy-types';
|
|
32
|
+
import { createProxy, isProxy, isValidProxyTarget, symbolIsProxy } from './proxy-utils';
|
|
33
|
+
import { ReactiveArray } from './reactive-array';
|
|
34
|
+
import { SchemaValidator } from './schema-validator';
|
|
35
|
+
import { ChangeId, EventId } from './symbols';
|
|
36
|
+
|
|
37
|
+
// Re-export for external consumers.
|
|
38
|
+
export { getEchoRoot, setMetaOwner } from './ownership';
|
|
39
|
+
|
|
40
|
+
type ProxyTarget = {
|
|
41
|
+
/**
|
|
42
|
+
* Typename or type DXN.
|
|
43
|
+
*/
|
|
44
|
+
[TypeId]: string;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Schema for the root.
|
|
48
|
+
*/
|
|
49
|
+
[SchemaId]: Schema.Schema.AnyNoContext;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* For modifications.
|
|
53
|
+
*/
|
|
54
|
+
[EventId]: Event<void>;
|
|
55
|
+
} & ({ [key: keyof any]: any } | any[]);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Deep copy a value, handling arrays and nested objects.
|
|
59
|
+
* Preserves ReactiveArray type and hidden properties (SchemaId, TypeId).
|
|
60
|
+
* Does not copy class instances or functions (except ReactiveArray).
|
|
61
|
+
*
|
|
62
|
+
* Note: Cannot use structuredClone because we need to:
|
|
63
|
+
* - Unwrap proxies
|
|
64
|
+
* - Preserve ReactiveArray instances
|
|
65
|
+
* - Copy Symbol-keyed hidden properties (SchemaId, TypeId)
|
|
66
|
+
* - Convert plain arrays to ReactiveArray
|
|
67
|
+
*
|
|
68
|
+
* Performance: O(n) where n is the total number of nested objects/arrays.
|
|
69
|
+
* For large structures, consider using Refs for frequently reassigned subtrees.
|
|
70
|
+
*/
|
|
71
|
+
const deepCopy = <T>(value: T, visited = new Map<object, object>()): T => {
|
|
72
|
+
if (value == null || typeof value !== 'object') {
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Handle proxies - get the underlying target.
|
|
77
|
+
const actualValue = getRawTarget(value);
|
|
78
|
+
|
|
79
|
+
// Check for circular references in the copy.
|
|
80
|
+
if (visited.has(actualValue)) {
|
|
81
|
+
return visited.get(actualValue) as T;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Handle ReactiveArray specially to preserve reactivity.
|
|
85
|
+
if (actualValue instanceof ReactiveArray) {
|
|
86
|
+
const copy = new ReactiveArray<any>();
|
|
87
|
+
visited.set(actualValue, copy);
|
|
88
|
+
for (const item of actualValue) {
|
|
89
|
+
copy.push(deepCopy(item, visited));
|
|
90
|
+
}
|
|
91
|
+
// Copy hidden properties.
|
|
92
|
+
copyHiddenProperties(actualValue, copy);
|
|
93
|
+
return copy as T;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Don't copy other class instances (objects with non-Object prototype).
|
|
97
|
+
const proto = Object.getPrototypeOf(actualValue);
|
|
98
|
+
if (proto !== Object.prototype && proto !== Array.prototype && proto !== null) {
|
|
99
|
+
return value; // Return as-is, don't copy class instances.
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (Array.isArray(actualValue)) {
|
|
103
|
+
// Plain arrays become ReactiveArrays.
|
|
104
|
+
const copy = new ReactiveArray<any>();
|
|
105
|
+
visited.set(actualValue, copy);
|
|
106
|
+
for (const item of actualValue) {
|
|
107
|
+
copy.push(deepCopy(item, visited));
|
|
108
|
+
}
|
|
109
|
+
return copy as T;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const copy: Record<string, any> = {};
|
|
113
|
+
visited.set(actualValue, copy);
|
|
114
|
+
for (const key of Object.keys(actualValue)) {
|
|
115
|
+
copy[key] = deepCopy((actualValue as any)[key], visited);
|
|
116
|
+
}
|
|
117
|
+
// Copy hidden properties (SchemaId, TypeId).
|
|
118
|
+
copyHiddenProperties(actualValue, copy);
|
|
119
|
+
return copy as T;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Copy hidden properties (SchemaId, TypeId) from source to target.
|
|
124
|
+
*/
|
|
125
|
+
const copyHiddenProperties = (source: any, target: any): void => {
|
|
126
|
+
if (SchemaId in source) {
|
|
127
|
+
defineHiddenProperty(target, SchemaId, source[SchemaId]);
|
|
128
|
+
}
|
|
129
|
+
if (TypeId in source) {
|
|
130
|
+
defineHiddenProperty(target, TypeId, source[TypeId]);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Typed in-memory reactive store (with Schema).
|
|
136
|
+
* Reactivity is based on Event subscriptions, not signals.
|
|
137
|
+
*/
|
|
138
|
+
export class TypedReactiveHandler implements ReactiveHandler<ProxyTarget> {
|
|
139
|
+
public static readonly instance: ReactiveHandler<any> = new TypedReactiveHandler();
|
|
140
|
+
|
|
141
|
+
readonly _proxyMap = new WeakMap<object, any>();
|
|
142
|
+
private _inSet = false;
|
|
143
|
+
|
|
144
|
+
private constructor() {}
|
|
145
|
+
|
|
146
|
+
init(target: ProxyTarget): void {
|
|
147
|
+
invariant(typeof target === 'object' && target !== null);
|
|
148
|
+
invariant(SchemaId in target, 'Schema is not defined for the target');
|
|
149
|
+
|
|
150
|
+
// Only set EventId on root objects (those without an owner).
|
|
151
|
+
// Nested objects share their root's EventId for centralized reactivity.
|
|
152
|
+
const hasOwner = !!getOwner(target);
|
|
153
|
+
if (!(EventId in target) && !hasOwner) {
|
|
154
|
+
defineHiddenProperty(target, EventId, new Event());
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
defineHiddenProperty(target, ObjectDeletedId, false);
|
|
158
|
+
|
|
159
|
+
// Mark root objects as having a change handler.
|
|
160
|
+
// The actual handler is returned dynamically in get() to have access to the proxy.
|
|
161
|
+
if (!hasOwner && !(ChangeId in target)) {
|
|
162
|
+
defineHiddenProperty(target, ChangeId, true);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Only set owners if this is a root object (no existing owner).
|
|
166
|
+
// Nested objects already have owners set by their root's initialization.
|
|
167
|
+
// If we re-set owners here for nested objects, we'd incorrectly point
|
|
168
|
+
// array elements to the array instead of the true root ECHO object.
|
|
169
|
+
if (!hasOwner) {
|
|
170
|
+
// Set owner on all nested objects to this root ECHO object.
|
|
171
|
+
// All nested records point directly to this root for centralized reactivity.
|
|
172
|
+
for (const key in target) {
|
|
173
|
+
if ((target as any)[symbolIsProxy]) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
let value = (target as any)[key];
|
|
177
|
+
if (isValidProxyTarget(value) || isProxy(value)) {
|
|
178
|
+
// Deep copy values that have foreign owners (owned by a different object,
|
|
179
|
+
// or are root ECHO objects whose nested structures would be owned by them).
|
|
180
|
+
// This recursively checks all nested objects.
|
|
181
|
+
if (hasForeignOwner(value, target)) {
|
|
182
|
+
value = deepCopy(value);
|
|
183
|
+
(target as any)[key] = value;
|
|
184
|
+
}
|
|
185
|
+
setOwnerRecursive(value, target);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Maybe have been set by `create`.
|
|
191
|
+
Object.defineProperty(target, inspectCustom, {
|
|
192
|
+
enumerable: false,
|
|
193
|
+
configurable: true,
|
|
194
|
+
value: this._inspect.bind(target),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
get(target: ProxyTarget, prop: string | symbol, receiver: any): any {
|
|
199
|
+
switch (prop) {
|
|
200
|
+
// TODO(burdon): Remove?
|
|
201
|
+
case objectData: {
|
|
202
|
+
return toJSON(target);
|
|
203
|
+
}
|
|
204
|
+
case ChangeId: {
|
|
205
|
+
// Return change handler only for root objects that have been marked with ChangeId.
|
|
206
|
+
if ((target as any)[ChangeId] !== true) {
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
// Return a function that allows mutations within a controlled context.
|
|
210
|
+
// Uses target as both the context key and event target for non-database objects.
|
|
211
|
+
return (callback: (obj: any) => void) => executeChange(target, target, receiver, callback);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Handle getter properties.
|
|
216
|
+
if (Object.getOwnPropertyDescriptor(target, prop)?.get) {
|
|
217
|
+
return Reflect.get(target, prop, receiver);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const value = Reflect.get(target, prop, receiver);
|
|
221
|
+
if (isValidProxyTarget(value)) {
|
|
222
|
+
return createProxy(value, this);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
set(target: ProxyTarget, prop: string | symbol, value: any, receiver: any): boolean {
|
|
229
|
+
const echoRoot = getEchoRoot(target);
|
|
230
|
+
|
|
231
|
+
// Check readonly enforcement - mutations only allowed within Obj.change().
|
|
232
|
+
// Skip check if the object is still being initialized (no ChangeId handler yet).
|
|
233
|
+
// Also skip for non-initialized root objects (those without EventId).
|
|
234
|
+
// Skip for symbol properties (internal infrastructure, not user data).
|
|
235
|
+
const isInitialized = ChangeId in echoRoot || EventId in echoRoot;
|
|
236
|
+
const isSymbolProp = typeof prop === 'symbol';
|
|
237
|
+
if (isInitialized && !isSymbolProp && !isInChangeContext(echoRoot)) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
`Cannot modify object property "${String(prop)}" outside of Obj.change(). ` +
|
|
240
|
+
'Use Obj.change(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
let result: boolean = false;
|
|
245
|
+
this._inSet = true;
|
|
246
|
+
try {
|
|
247
|
+
batchEvents(() => {
|
|
248
|
+
const { echoRoot: _, preparedValue } = this._prepareValueForAssignment(target, prop, value);
|
|
249
|
+
result = Reflect.set(target, prop, preparedValue, receiver);
|
|
250
|
+
// Queue notification instead of emitting immediately (batched).
|
|
251
|
+
if (isInitialized) {
|
|
252
|
+
queueNotification(echoRoot);
|
|
253
|
+
// Also notify the owner chain so parent objects are updated when nested objects change.
|
|
254
|
+
notifyOwnerChain(target);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
} finally {
|
|
258
|
+
this._inSet = false;
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
ownKeys(target: ProxyTarget): ArrayLike<string | symbol> {
|
|
264
|
+
return Reflect.ownKeys(target);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
deleteProperty(target: ProxyTarget, property: string | symbol): boolean {
|
|
268
|
+
const echoRoot = getEchoRoot(target);
|
|
269
|
+
|
|
270
|
+
// Check readonly enforcement - mutations only allowed within Obj.change().
|
|
271
|
+
// Skip for symbol properties (internal infrastructure, not user data).
|
|
272
|
+
const isInitialized = (echoRoot as any)[ChangeId] === true || EventId in echoRoot;
|
|
273
|
+
const isSymbolProp = typeof property === 'symbol';
|
|
274
|
+
if (isInitialized && !isSymbolProp && !isInChangeContext(echoRoot)) {
|
|
275
|
+
throw createPropertyDeleteError(property);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const result = Reflect.deleteProperty(target, property);
|
|
279
|
+
if (isInitialized) {
|
|
280
|
+
queueNotification(echoRoot);
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
defineProperty(target: ProxyTarget, property: string | symbol, attributes: PropertyDescriptor): boolean {
|
|
286
|
+
const echoRoot = getEchoRoot(target);
|
|
287
|
+
|
|
288
|
+
// Check readonly enforcement - mutations only allowed within Obj.change().
|
|
289
|
+
// Skip check if the object is still being initialized (no ChangeId handler yet).
|
|
290
|
+
// Skip for symbol properties (internal infrastructure, not user data).
|
|
291
|
+
const isInitialized = ChangeId in echoRoot || EventId in echoRoot;
|
|
292
|
+
const isSymbolProp = typeof property === 'symbol';
|
|
293
|
+
if (isInitialized && !isSymbolProp && !isInChangeContext(echoRoot)) {
|
|
294
|
+
throw new Error(
|
|
295
|
+
`Cannot modify object property "${String(property)}" outside of Obj.change(). ` +
|
|
296
|
+
'Use Obj.change(obj, (mutableObj) => { mutableObj.property = value; }) instead.',
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const { echoRoot: _, preparedValue } = this._prepareValueForAssignment(target, property, attributes.value);
|
|
301
|
+
const result = Reflect.defineProperty(target, property, {
|
|
302
|
+
...attributes,
|
|
303
|
+
value: preparedValue,
|
|
304
|
+
});
|
|
305
|
+
if (!this._inSet && isInitialized) {
|
|
306
|
+
// Queue notification instead of emitting immediately (batched).
|
|
307
|
+
queueNotification(echoRoot);
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Prepare a value for assignment to a typed object property.
|
|
314
|
+
* Handles cycle detection, copy-on-assign, array conversion, validation, and ownership.
|
|
315
|
+
*/
|
|
316
|
+
private _prepareValueForAssignment(
|
|
317
|
+
target: ProxyTarget,
|
|
318
|
+
prop: string | symbol,
|
|
319
|
+
value: any,
|
|
320
|
+
): { echoRoot: object; preparedValue: any } {
|
|
321
|
+
const echoRoot = getEchoRoot(target);
|
|
322
|
+
|
|
323
|
+
// Check for cycles before assignment.
|
|
324
|
+
if (isValidProxyTarget(value) || isProxy(value)) {
|
|
325
|
+
if (wouldCreateCycle(echoRoot, value)) {
|
|
326
|
+
throw new Error('Cannot create cycles in typed object graph. Consider using Ref for circular references.');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Prevent direct assignment of root ECHO objects (those created with Obj.make/Relation.make).
|
|
331
|
+
// These must be wrapped with Ref.make for proper reference handling.
|
|
332
|
+
// This matches database object behavior for consistency.
|
|
333
|
+
if (isValidProxyTarget(value) || isProxy(value)) {
|
|
334
|
+
const actualValue = getRawTarget(value);
|
|
335
|
+
const isRootEchoObject = EventId in actualValue;
|
|
336
|
+
if (isRootEchoObject) {
|
|
337
|
+
throw new Error('Object references must be wrapped with `Ref.make`');
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Copy-on-assign: If the value is a nested record owned by a different ECHO object, deep copy it.
|
|
342
|
+
if (isValidProxyTarget(value) || isProxy(value)) {
|
|
343
|
+
const actualValue = getRawTarget(value);
|
|
344
|
+
const existingOwner = getOwner(actualValue);
|
|
345
|
+
if (existingOwner != null && existingOwner !== echoRoot) {
|
|
346
|
+
value = deepCopy(value);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Convert arrays to reactive arrays.
|
|
351
|
+
if (Array.isArray(value) && !(value instanceof ReactiveArray)) {
|
|
352
|
+
value = ReactiveArray.from(value);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const validatedValue = this._validateValue(target, prop, value);
|
|
356
|
+
|
|
357
|
+
// Set owner on new value to the root ECHO object.
|
|
358
|
+
if (isValidProxyTarget(validatedValue) || isProxy(validatedValue)) {
|
|
359
|
+
setOwnerRecursive(validatedValue, echoRoot);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return { echoRoot, preparedValue: validatedValue };
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
private _validateValue(target: any, prop: string | symbol, value: any) {
|
|
366
|
+
const schema = SchemaValidator.getTargetPropertySchema(target, prop);
|
|
367
|
+
const _ = Schema.asserts(schema)(value);
|
|
368
|
+
if (isValidProxyTarget(value)) {
|
|
369
|
+
setSchemaProperties(value, schema);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return value;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private _inspect(
|
|
376
|
+
_: number,
|
|
377
|
+
options: InspectOptionsStylized,
|
|
378
|
+
inspectFn: (value: any, options?: InspectOptionsStylized) => string,
|
|
379
|
+
): string {
|
|
380
|
+
const inspected = inspectFn(this, {
|
|
381
|
+
...options,
|
|
382
|
+
showHidden: false,
|
|
383
|
+
customInspect: false,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
return `Typed ${inspected}`;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* @deprecated Use `Obj.toJSON` instead.
|
|
392
|
+
*/
|
|
393
|
+
// TODO(burdon): Remove?
|
|
394
|
+
const toJSON = (target: ProxyTarget): any => {
|
|
395
|
+
return { '@type': 'TypedReactiveObject', ...target };
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Recursively set AST on all potential proxy targets.
|
|
400
|
+
*/
|
|
401
|
+
const setSchemaProperties = (obj: any, schema: Schema.Schema.AnyNoContext) => {
|
|
402
|
+
const schemaType = getSchemaDXN(schema);
|
|
403
|
+
if (schemaType != null) {
|
|
404
|
+
defineHiddenProperty(obj, TypeId, schemaType);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
defineHiddenProperty(obj, SchemaId, schema);
|
|
408
|
+
for (const key in obj) {
|
|
409
|
+
if (isValidProxyTarget(obj[key])) {
|
|
410
|
+
const elementSchema = SchemaValidator.getTargetPropertySchema(obj, key);
|
|
411
|
+
if (elementSchema != null) {
|
|
412
|
+
setSchemaProperties(obj[key], elementSchema);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
export const prepareTypedTarget = <T>(target: T, schema: Schema.Schema<T>) => {
|
|
419
|
+
// log.info('prepareTypedTarget', { target, schema });
|
|
420
|
+
if (!SchemaAST.isTypeLiteral(schema.ast)) {
|
|
421
|
+
throw new Error('schema has to describe an object type');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
SchemaValidator.validateSchema(schema);
|
|
425
|
+
const _ = Schema.asserts(schema)(target);
|
|
426
|
+
makeArraysReactive(target);
|
|
427
|
+
setSchemaProperties(target, schema);
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
const makeArraysReactive = (target: any) => {
|
|
431
|
+
for (const key in target) {
|
|
432
|
+
if (target[symbolIsProxy]) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (Array.isArray(target[key])) {
|
|
436
|
+
target[key] = ReactiveArray.from(target[key]);
|
|
437
|
+
}
|
|
438
|
+
if (typeof target[key] === 'object') {
|
|
439
|
+
makeArraysReactive(target[key]);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { EchoObjectSchema } from '../entities';
|
|
9
|
+
import { getSchema } from '../types';
|
|
10
|
+
|
|
11
|
+
import { makeObject } from './make-object';
|
|
12
|
+
import { change } from './reactive';
|
|
13
|
+
|
|
14
|
+
const Organization = Schema.Struct({
|
|
15
|
+
name: Schema.String,
|
|
16
|
+
}).pipe(
|
|
17
|
+
EchoObjectSchema({
|
|
18
|
+
typename: 'example.com/type/Organization',
|
|
19
|
+
version: '0.1.0',
|
|
20
|
+
}),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
interface Organization extends Schema.Schema.Type<typeof Organization> {}
|
|
24
|
+
|
|
25
|
+
const Contact = Schema.Struct(
|
|
26
|
+
{
|
|
27
|
+
name: Schema.String,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: Schema.String,
|
|
31
|
+
value: Schema.Any,
|
|
32
|
+
},
|
|
33
|
+
).pipe(
|
|
34
|
+
Schema.partial,
|
|
35
|
+
EchoObjectSchema({
|
|
36
|
+
typename: 'example.com/type/Person',
|
|
37
|
+
version: '0.1.0',
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
interface Contact extends Schema.Schema.Type<typeof Contact> {}
|
|
42
|
+
|
|
43
|
+
const TEST_ORG: Omit<Organization, 'id'> = { name: 'Test' };
|
|
44
|
+
|
|
45
|
+
describe('EchoObjectSchema class DSL', () => {
|
|
46
|
+
test('can get object schema', async () => {
|
|
47
|
+
const obj = makeObject(Organization, TEST_ORG);
|
|
48
|
+
expect(getSchema(obj)).to.deep.eq(Organization);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('class options', () => {
|
|
52
|
+
test('can assign undefined to partial fields', async () => {
|
|
53
|
+
const person = makeObject(Contact, { name: 'John' });
|
|
54
|
+
change(person, (p) => {
|
|
55
|
+
p.name = undefined;
|
|
56
|
+
p.recordField = 'hello';
|
|
57
|
+
});
|
|
58
|
+
expect(person.name).to.be.undefined;
|
|
59
|
+
expect(person.recordField).to.eq('hello');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('record', () => {
|
|
64
|
+
const schema = Schema.mutable(
|
|
65
|
+
Schema.Struct({
|
|
66
|
+
meta: Schema.optional(Schema.mutable(Schema.Any)),
|
|
67
|
+
// NOTE: Schema.Record only supports shallow values.
|
|
68
|
+
// https://www.npmjs.com/package/@effect/schema#mutable-records
|
|
69
|
+
// meta: Schema.optional(Schema.mutable(Schema.Record({ key: Schema.String, value: Schema.Any }))),
|
|
70
|
+
// meta: Schema.optional(Schema.mutable(Schema.object)),
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
const object = makeObject(schema, {});
|
|
76
|
+
change(object, (o) => {
|
|
77
|
+
(o.meta ??= {}).test = 100;
|
|
78
|
+
});
|
|
79
|
+
expect(object.meta!.test).to.eq(100);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
const object = makeObject(schema, {});
|
|
84
|
+
change(object, (o) => {
|
|
85
|
+
o.meta = { test: { value: 300 } };
|
|
86
|
+
});
|
|
87
|
+
expect(object.meta!.test.value).to.eq(300);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
{
|
|
91
|
+
// Plain object (not a reactive proxy) - doesn't need Obj.change.
|
|
92
|
+
type Test1 = Schema.Schema.Type<typeof schema>;
|
|
93
|
+
|
|
94
|
+
const object: Test1 = {};
|
|
95
|
+
(object.meta ??= {}).test = 100;
|
|
96
|
+
expect(object.meta!.test).to.eq(100);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
const Test2 = Schema.Struct({
|
|
101
|
+
meta: Schema.optional(Schema.mutable(Schema.Record({ key: Schema.String, value: Schema.Any }))),
|
|
102
|
+
}).pipe(
|
|
103
|
+
EchoObjectSchema({
|
|
104
|
+
typename: 'dxos.org/type/FunctionTrigger',
|
|
105
|
+
version: '0.1.0',
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const object = makeObject(Test2, {});
|
|
110
|
+
change(object, (o) => {
|
|
111
|
+
(o.meta ??= {}).test = 100;
|
|
112
|
+
});
|
|
113
|
+
expect(object.meta!.test).to.eq(100);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ObjectId } from '@dxos/keys';
|
|
6
|
+
import { isNonNullable } from '@dxos/util';
|
|
7
|
+
|
|
8
|
+
import { type AnyEntity } from '../types';
|
|
9
|
+
|
|
10
|
+
import { Ref } from './ref';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Helper functions for working with arrays of refs.
|
|
14
|
+
*/
|
|
15
|
+
export const RefArray = Object.freeze({
|
|
16
|
+
/**
|
|
17
|
+
* @returns all resolved targets.
|
|
18
|
+
*/
|
|
19
|
+
targets: <T extends AnyEntity>(refs: readonly Ref<T>[]): T[] => {
|
|
20
|
+
return refs.map((ref) => ref.target).filter(isNonNullable);
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Load all referenced objects.
|
|
25
|
+
*/
|
|
26
|
+
loadAll: <T extends AnyEntity>(refs: readonly Ref<T>[]): Promise<T[]> => {
|
|
27
|
+
return Promise.all(refs.map((ref) => ref.load()));
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Removes the ref with the given id.
|
|
32
|
+
*/
|
|
33
|
+
removeById: (refs: Ref<AnyEntity>[], id: ObjectId) => {
|
|
34
|
+
const index = refs.findIndex(Ref.hasObjectId(id));
|
|
35
|
+
if (index >= 0) {
|
|
36
|
+
refs.splice(index, 1);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Schema from 'effect/Schema';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { DXN, ObjectId } from '@dxos/keys';
|
|
9
|
+
|
|
10
|
+
import { EchoObjectSchema, getObjectDXN } from '../entities';
|
|
11
|
+
import { createObject } from '../object';
|
|
12
|
+
|
|
13
|
+
import { Ref, getReferenceAst } from './ref';
|
|
14
|
+
|
|
15
|
+
const Task = Schema.Struct({
|
|
16
|
+
title: Schema.optional(Schema.String),
|
|
17
|
+
}).pipe(
|
|
18
|
+
EchoObjectSchema({
|
|
19
|
+
typename: 'example.com/type/Task',
|
|
20
|
+
version: '0.1.0',
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
type Task = Schema.Schema.Type<typeof Task>;
|
|
25
|
+
|
|
26
|
+
const Contact = Schema.Struct({
|
|
27
|
+
name: Schema.String,
|
|
28
|
+
email: Schema.optional(Schema.String),
|
|
29
|
+
tasks: Schema.mutable(Schema.Array(Ref(Task))),
|
|
30
|
+
}).pipe(
|
|
31
|
+
EchoObjectSchema({
|
|
32
|
+
typename: 'example.com/type/Person',
|
|
33
|
+
version: '0.1.0',
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
type Contact = Schema.Schema.Type<typeof Contact>;
|
|
38
|
+
|
|
39
|
+
describe('Ref', () => {
|
|
40
|
+
test('Schema is', () => {
|
|
41
|
+
Ref(Contact).pipe(Schema.is)(Ref.fromDXN(DXN.parse(`dxn:echo:@:${ObjectId.random()}`)));
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('ref ast', () => {
|
|
45
|
+
const ref = Ref(Task);
|
|
46
|
+
expect(ref.ast._tag).toEqual('Declaration');
|
|
47
|
+
const refAst = getReferenceAst(ref.ast);
|
|
48
|
+
expect(refAst).toEqual({ typename: Task.typename, version: Task.version });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// TODO(dmaretskyi): Figure out how to expose this in the API.
|
|
52
|
+
test.skip('encode with inlined target', () => {
|
|
53
|
+
const task = createObject(Task, { title: 'Fix bugs' });
|
|
54
|
+
const contact = createObject(Contact, { name: 'John Doe', tasks: [Ref.make(task)] });
|
|
55
|
+
|
|
56
|
+
const json = JSON.parse(JSON.stringify(contact));
|
|
57
|
+
expect(json).toEqual({
|
|
58
|
+
id: contact.id,
|
|
59
|
+
'@type': `dxn:type:${Contact.typename}:${Contact.version}`,
|
|
60
|
+
'@meta': {
|
|
61
|
+
keys: [],
|
|
62
|
+
},
|
|
63
|
+
name: 'John Doe',
|
|
64
|
+
tasks: [
|
|
65
|
+
{
|
|
66
|
+
'/': getObjectDXN(task as any)!.toString(),
|
|
67
|
+
target: JSON.parse(JSON.stringify(task)),
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('encode without inlining target', () => {
|
|
74
|
+
const task = createObject(Task, { title: 'Fix bugs' });
|
|
75
|
+
const contact = createObject(Contact, { name: 'John Doe', tasks: [Ref.make(task).noInline()] });
|
|
76
|
+
|
|
77
|
+
const json = JSON.parse(JSON.stringify(contact));
|
|
78
|
+
expect(json).toEqual({
|
|
79
|
+
id: contact.id,
|
|
80
|
+
'@type': `dxn:type:${Contact.typename}:${Contact.version}`,
|
|
81
|
+
'@meta': {
|
|
82
|
+
keys: [],
|
|
83
|
+
},
|
|
84
|
+
name: 'John Doe',
|
|
85
|
+
tasks: [{ '/': getObjectDXN(task)!.toString() }],
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('decode object', () => {
|
|
90
|
+
const id = ObjectId.random();
|
|
91
|
+
const contactData = {
|
|
92
|
+
id: ObjectId.random(),
|
|
93
|
+
name: 'John Doe',
|
|
94
|
+
tasks: [{ '/': `dxn:echo:@:${id}` }],
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const contact = Contact.pipe(Schema.decodeUnknownSync)(contactData);
|
|
98
|
+
expect(Ref.isRef(contact.tasks[0])).toEqual(true);
|
|
99
|
+
expect(contact.tasks[0].dxn.toString()).toEqual(`dxn:echo:@:${id}`);
|
|
100
|
+
});
|
|
101
|
+
});
|