@dxos/echo 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b
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 +4 -4
- package/dist/lib/neutral/Annotation.mjs +7 -3
- package/dist/lib/neutral/Database.mjs +8 -4
- package/dist/lib/neutral/Entity.mjs +24 -14
- package/dist/lib/neutral/Err.mjs +1 -1
- package/dist/lib/neutral/Extension.mjs +18 -0
- package/dist/lib/neutral/Extension.mjs.map +7 -0
- package/dist/lib/neutral/Feed.mjs +50 -0
- package/dist/lib/neutral/Feed.mjs.map +7 -0
- package/dist/lib/neutral/Filter.mjs +21 -10
- package/dist/lib/neutral/Format.mjs +3 -3
- package/dist/lib/neutral/JsonSchema.mjs +9 -9
- package/dist/lib/neutral/Key.mjs +1 -1
- package/dist/lib/neutral/Migration.mjs +17 -0
- package/dist/lib/neutral/Migration.mjs.map +7 -0
- package/dist/lib/neutral/Obj.mjs +26 -17
- package/dist/lib/neutral/Order.mjs +1 -1
- package/dist/lib/neutral/Query.mjs +21 -9
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +9 -7
- package/dist/lib/neutral/Relation.mjs +23 -13
- package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
- package/dist/lib/neutral/Tag.mjs +14 -10
- package/dist/lib/neutral/Type.mjs +13 -23
- package/dist/lib/neutral/{chunk-N2QNHMT5.mjs → chunk-44HT3MEC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-N2QNHMT5.mjs.map → chunk-44HT3MEC.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-XAJMXQ4H.mjs → chunk-5SL5LDLD.mjs} +6 -2
- package/dist/lib/neutral/chunk-5SL5LDLD.mjs.map +7 -0
- package/dist/lib/neutral/chunk-6VIJV543.mjs +34 -0
- package/dist/lib/neutral/chunk-6VIJV543.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7RVZT53K.mjs} +1 -1
- package/dist/lib/neutral/{chunk-4L6DOFXP.mjs → chunk-BICZKPQG.mjs} +1 -1
- package/dist/lib/neutral/{chunk-4L6DOFXP.mjs.map → chunk-BICZKPQG.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-B4FLOYG7.mjs → chunk-FHYIM4RD.mjs} +18 -20
- package/dist/lib/neutral/chunk-FHYIM4RD.mjs.map +7 -0
- package/dist/lib/neutral/chunk-FZHVQEHN.mjs +81 -0
- package/dist/lib/neutral/chunk-FZHVQEHN.mjs.map +7 -0
- package/dist/lib/neutral/chunk-GWFFC34K.mjs +50 -0
- package/dist/lib/neutral/chunk-GWFFC34K.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-EXAYCLIM.mjs → chunk-HPNQTEEQ.mjs} +5 -5
- package/dist/lib/neutral/chunk-HPNQTEEQ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-YPIP3WGI.mjs → chunk-LVGOVFDV.mjs} +40 -12
- package/dist/lib/neutral/chunk-LVGOVFDV.mjs.map +7 -0
- package/dist/lib/neutral/chunk-MPAI2MHO.mjs +346 -0
- package/dist/lib/neutral/chunk-MPAI2MHO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-KB7RIVLK.mjs → chunk-N4B7FHQT.mjs} +4 -4
- package/dist/lib/neutral/{chunk-KB7RIVLK.mjs.map → chunk-N4B7FHQT.mjs.map} +2 -2
- package/dist/lib/neutral/chunk-O5LRY6CO.mjs +734 -0
- package/dist/lib/neutral/chunk-O5LRY6CO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-VYEWMV5U.mjs → chunk-QGMIH2SN.mjs} +8 -4
- package/dist/lib/neutral/chunk-QGMIH2SN.mjs.map +7 -0
- package/dist/lib/neutral/chunk-QXIANHKU.mjs +206 -0
- package/dist/lib/neutral/chunk-QXIANHKU.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-UMECVTXM.mjs → chunk-RF7ZBZ4A.mjs} +72 -5
- package/dist/lib/neutral/chunk-RF7ZBZ4A.mjs.map +7 -0
- package/dist/lib/neutral/chunk-S7IMFVTB.mjs +132 -0
- package/dist/lib/neutral/chunk-S7IMFVTB.mjs.map +7 -0
- package/dist/lib/neutral/chunk-SJKBWMJY.mjs +2436 -0
- package/dist/lib/neutral/chunk-SJKBWMJY.mjs.map +7 -0
- package/dist/lib/neutral/chunk-SUZMWP3Y.mjs +36 -0
- package/dist/lib/neutral/chunk-SUZMWP3Y.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-HQXQWXLH.mjs → chunk-SW5CUSBY.mjs} +183 -32
- package/dist/lib/neutral/chunk-SW5CUSBY.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-RIMHNJ3E.mjs → chunk-TNBK56IN.mjs} +98 -44
- package/dist/lib/neutral/chunk-TNBK56IN.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-7WE7SBA2.mjs → chunk-TRPZU2HV.mjs} +13 -13
- package/dist/lib/neutral/chunk-TRPZU2HV.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ROKO4RKJ.mjs → chunk-TTCSATUD.mjs} +2 -2
- package/dist/lib/neutral/chunk-TTCSATUD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
- package/dist/lib/neutral/chunk-VGKLHHRT.mjs +318 -0
- package/dist/lib/neutral/chunk-VGKLHHRT.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TMLVKIMX.mjs → chunk-VYAGNFSJ.mjs} +8 -3
- package/dist/lib/neutral/chunk-VYAGNFSJ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-7YWDDFPH.mjs → chunk-WRVRDZDA.mjs} +77 -58
- package/dist/lib/neutral/chunk-WRVRDZDA.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-MXQJZCPY.mjs → chunk-ZISMEVKD.mjs} +1 -1
- package/dist/lib/neutral/chunk-ZISMEVKD.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +51 -28
- package/dist/lib/neutral/internal/index.mjs +52 -38
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +199 -136
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/types/src/Annotation.d.ts +3 -3
- package/dist/types/src/Annotation.d.ts.map +1 -1
- package/dist/types/src/Collection.d.ts +16 -0
- package/dist/types/src/Collection.d.ts.map +1 -0
- package/dist/types/src/Database.d.ts +20 -35
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +19 -0
- package/dist/types/src/Dataset.d.ts.map +1 -0
- package/dist/types/src/Entity.d.ts +54 -22
- package/dist/types/src/Entity.d.ts.map +1 -1
- package/dist/types/src/Err.d.ts +18 -18
- package/dist/types/src/Err.d.ts.map +1 -1
- package/dist/types/src/Extension.d.ts +80 -0
- package/dist/types/src/Extension.d.ts.map +1 -0
- package/dist/types/src/Extension.test.d.ts +2 -0
- package/dist/types/src/Extension.test.d.ts.map +1 -0
- package/dist/types/src/Feed.d.ts +182 -0
- package/dist/types/src/Feed.d.ts.map +1 -0
- package/dist/types/src/Filter.d.ts +34 -5
- 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/Format.d.ts +3 -3
- package/dist/types/src/Format.d.ts.map +1 -1
- package/dist/types/src/Hypergraph.d.ts +8 -3
- 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 +11 -4
- package/dist/types/src/JsonSchema.d.ts.map +1 -1
- package/dist/types/src/Migration.d.ts +57 -0
- package/dist/types/src/Migration.d.ts.map +1 -0
- package/dist/types/src/Obj.d.ts +109 -60
- 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 +105 -17
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +58 -10
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +86 -40
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/SchemaRegistry.d.ts +4 -4
- package/dist/types/src/SchemaRegistry.d.ts.map +1 -1
- package/dist/types/src/Tag.d.ts +2 -1
- package/dist/types/src/Tag.d.ts.map +1 -1
- package/dist/types/src/Type.d.ts +51 -180
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +68 -0
- package/dist/types/src/View.d.ts.map +1 -0
- 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 +7 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/{annotations → Annotation}/annotations.d.ts +65 -2
- package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -0
- package/dist/types/src/internal/Annotation/annotations.test.d.ts.map +1 -0
- package/dist/types/src/internal/Annotation/index.d.ts +4 -0
- package/dist/types/src/internal/Annotation/index.d.ts.map +1 -0
- package/dist/types/src/internal/{api → Annotation}/sorting.d.ts +1 -1
- package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -0
- package/dist/types/src/internal/{annotations → Annotation}/util.d.ts +2 -2
- package/dist/types/src/internal/Annotation/util.d.ts.map +1 -0
- package/dist/types/src/internal/{api/entity.d.ts → Entity/api.d.ts} +2 -2
- package/dist/types/src/internal/Entity/api.d.ts.map +1 -0
- package/dist/types/src/internal/{entities → Entity}/entity.d.ts +3 -3
- package/dist/types/src/internal/Entity/entity.d.ts.map +1 -0
- package/dist/types/src/internal/{entities → Entity}/index.d.ts +2 -0
- package/dist/types/src/internal/Entity/index.d.ts.map +1 -0
- package/dist/types/src/internal/{entities → Entity}/model.d.ts +2 -26
- package/dist/types/src/internal/Entity/model.d.ts.map +1 -0
- package/dist/types/src/internal/{entities → Entity}/object.d.ts +2 -2
- package/dist/types/src/internal/Entity/object.d.ts.map +1 -0
- package/dist/types/src/internal/{entities → Entity}/relation.d.ts +3 -30
- package/dist/types/src/internal/Entity/relation.d.ts.map +1 -0
- package/dist/types/src/internal/Entity/util.d.ts.map +1 -0
- package/dist/types/src/internal/{api → Entity}/version.d.ts +1 -1
- package/dist/types/src/internal/Entity/version.d.ts.map +1 -0
- package/dist/types/src/internal/Format/date.d.ts.map +1 -0
- package/dist/types/src/internal/Format/date.test.d.ts.map +1 -0
- package/dist/types/src/internal/Format/format.d.ts.map +1 -0
- package/dist/types/src/internal/Format/format.test.d.ts.map +1 -0
- package/dist/types/src/internal/Format/index.d.ts.map +1 -0
- package/dist/types/src/internal/Format/number.d.ts.map +1 -0
- package/dist/types/src/internal/Format/object.d.ts.map +1 -0
- package/dist/types/src/internal/Format/select.d.ts.map +1 -0
- package/dist/types/src/internal/Format/string.d.ts.map +1 -0
- package/dist/types/src/internal/{formats → Format}/types.d.ts +1 -1
- package/dist/types/src/internal/Format/types.d.ts.map +1 -0
- package/dist/types/src/internal/{json-schema → JsonSchema}/annotations.d.ts +1 -1
- package/dist/types/src/internal/JsonSchema/annotations.d.ts.map +1 -0
- package/dist/types/src/internal/JsonSchema/effect-schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/JsonSchema/index.d.ts.map +1 -0
- package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -0
- package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-type.d.ts +37 -37
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -0
- package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.d.ts +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -0
- package/dist/types/src/internal/JsonSchema/json-schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/clone.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/common.d.ts.map +1 -0
- package/dist/types/src/internal/{object → Obj}/create-object.d.ts +2 -2
- package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/create-object.test.d.ts.map +1 -0
- package/dist/types/src/internal/{object → Obj}/deleted.d.ts +1 -1
- package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/ids.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/index.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/inspect.d.ts.map +1 -0
- package/dist/types/src/internal/{object → Obj}/json-serializer.d.ts +13 -5
- package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/json-serializer.test.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/schema-validator.d.ts +2 -0
- package/dist/types/src/internal/Obj/schema-validator.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/schema-validator.test.d.ts.map +1 -0
- package/dist/types/src/internal/{object → Obj}/set-value.d.ts +2 -2
- package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/set-value.test.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -0
- package/dist/types/src/internal/{object → Obj}/typed-object.d.ts +4 -4
- package/dist/types/src/internal/Obj/typed-object.d.ts.map +1 -0
- package/dist/types/src/internal/Obj/typed-object.test.d.ts.map +1 -0
- 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/index.d.ts.map +1 -0
- package/dist/types/src/internal/{ref → Ref}/ref-array.d.ts +1 -1
- package/dist/types/src/internal/Ref/ref-array.d.ts.map +1 -0
- package/dist/types/src/internal/{ref → Ref}/ref.d.ts +15 -2
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/ref.test.d.ts.map +1 -0
- package/dist/types/src/internal/{schema → Type}/compose.d.ts +1 -1
- package/dist/types/src/internal/Type/compose.d.ts.map +1 -0
- package/dist/types/src/internal/Type/compose.test.d.ts.map +1 -0
- package/dist/types/src/internal/{schema → Type}/echo-schema.d.ts +7 -7
- package/dist/types/src/internal/Type/echo-schema.d.ts.map +1 -0
- package/dist/types/src/internal/Type/index.d.ts.map +1 -0
- package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -0
- package/dist/types/src/internal/{schema → Type}/persistent-schema.d.ts +2 -2
- package/dist/types/src/internal/Type/persistent-schema.d.ts.map +1 -0
- package/dist/types/src/internal/{api → common/api}/index.d.ts +0 -4
- package/dist/types/src/internal/common/api/index.d.ts.map +1 -0
- package/dist/types/src/internal/{api → common/api}/meta.d.ts +3 -3
- package/dist/types/src/internal/common/api/meta.d.ts.map +1 -0
- package/dist/types/src/internal/common/index.d.ts +4 -0
- package/dist/types/src/internal/common/index.d.ts.map +1 -0
- package/dist/types/src/internal/{proxy → common/proxy}/change-context.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/change.test.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -0
- package/dist/types/src/internal/{proxy → common/proxy}/errors.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/handler.test.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/index.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/proxy-types.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -0
- package/dist/types/src/internal/{proxy → common/proxy}/reactive-array.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/reactive-array.d.ts.map +1 -0
- package/dist/types/src/internal/{proxy → common/proxy}/reactive.d.ts +2 -2
- package/dist/types/src/internal/{proxy → 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 -0
- package/dist/types/src/internal/common/proxy/schema.test.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/symbols.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/typed-handler.test.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/typed-object.test.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/base.d.ts +1 -0
- package/dist/types/src/internal/common/types/base.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/entity.d.ts +5 -5
- package/dist/types/src/internal/common/types/entity.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/index.d.ts +1 -0
- package/dist/types/src/internal/common/types/index.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/meta.d.ts +2 -1
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -0
- package/dist/types/src/internal/common/types/model-symbols.d.ts +54 -0
- package/dist/types/src/internal/common/types/model-symbols.d.ts.map +1 -0
- package/dist/types/src/internal/common/types/typename.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/version.d.ts +2 -2
- package/dist/types/src/internal/common/types/version.d.ts.map +1 -0
- package/dist/types/src/internal/index.d.ts +9 -10
- 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 +47 -46
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/dist/types/src/testing/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -14
- package/src/Annotation.ts +7 -3
- package/src/Collection.ts +37 -0
- package/src/Database.ts +63 -64
- package/src/Dataset.ts +26 -0
- package/src/Entity.ts +87 -61
- package/src/Err.ts +2 -0
- package/src/Extension.test.ts +235 -0
- package/src/Extension.ts +122 -0
- package/src/Feed.ts +304 -0
- package/src/Filter.test.ts +90 -0
- package/src/Filter.ts +85 -7
- package/src/Format.ts +3 -3
- package/src/Hypergraph.ts +9 -4
- package/src/Json.test.ts +175 -0
- package/src/Json.ts +102 -0
- package/src/JsonSchema.ts +14 -4
- package/src/Migration.ts +94 -0
- package/src/Obj.test.ts +112 -15
- package/src/Obj.ts +302 -166
- package/src/Order.ts +3 -1
- package/src/Query.test.ts +372 -15
- package/src/Query.ts +269 -26
- package/src/Ref.ts +64 -11
- package/src/Relation.test.ts +8 -2
- package/src/Relation.ts +183 -147
- package/src/SchemaRegistry.ts +5 -4
- package/src/Tag.ts +6 -5
- package/src/Type.test.ts +10 -10
- package/src/Type.ts +70 -303
- package/src/View.ts +107 -0
- package/src/exemplars.test.ts +21 -0
- package/src/index.ts +8 -0
- package/src/internal/{annotations → Annotation}/annotations.test.ts +56 -7
- package/src/internal/{annotations → Annotation}/annotations.ts +122 -19
- package/src/internal/{annotations → Annotation}/index.ts +1 -0
- package/src/internal/{api → Annotation}/sorting.ts +2 -4
- package/src/internal/{annotations → Annotation}/util.ts +1 -1
- package/src/internal/{api/entity.ts → Entity/api.ts} +3 -2
- package/src/internal/{entities → Entity}/entity.ts +6 -4
- package/src/internal/{entities → Entity}/index.ts +2 -0
- package/src/internal/{entities → Entity}/model.ts +13 -42
- package/src/internal/{entities → Entity}/object.ts +2 -3
- package/src/internal/{entities → Entity}/relation.ts +19 -36
- package/src/internal/{api → Entity}/version.ts +2 -2
- package/src/internal/{formats → Format}/date.test.ts +1 -2
- package/src/internal/{formats → Format}/format.test.ts +1 -2
- package/src/internal/{formats → Format}/types.ts +2 -2
- package/src/internal/{json-schema → JsonSchema}/annotations.ts +3 -3
- package/src/internal/{json-schema → JsonSchema}/json-schema-type.ts +4 -4
- package/src/internal/{json-schema → JsonSchema}/json-schema.test.ts +48 -49
- package/src/internal/{json-schema → JsonSchema}/json-schema.ts +6 -5
- package/src/internal/{object → Obj}/clone.ts +3 -3
- package/src/internal/{object → Obj}/common.ts +2 -2
- package/src/internal/{object → Obj}/create-object.test.ts +5 -7
- package/src/internal/{object → Obj}/create-object.ts +5 -6
- package/src/internal/{object → Obj}/deleted.ts +2 -2
- package/src/internal/{object → Obj}/inspect.ts +2 -2
- package/src/internal/{object → Obj}/json-serializer.test.ts +31 -9
- package/src/internal/{object → Obj}/json-serializer.ts +52 -27
- package/src/internal/{object → Obj}/schema-validator.ts +1 -1
- package/src/internal/{object → Obj}/set-value.test.ts +24 -24
- package/src/internal/{object → Obj}/set-value.ts +3 -3
- package/src/internal/{object → Obj}/snapshot.ts +35 -23
- package/src/internal/{object → Obj}/typed-object.test.ts +3 -3
- package/src/internal/{object → Obj}/typed-object.ts +4 -4
- package/src/internal/Query.ts +137 -0
- package/src/internal/{ref → Ref}/ref-array.ts +1 -2
- package/src/internal/{ref → Ref}/ref.test.ts +4 -5
- package/src/internal/{ref → Ref}/ref.ts +20 -3
- package/src/internal/{schema → Type}/compose.test.ts +5 -6
- package/src/internal/{schema → Type}/compose.ts +1 -1
- package/src/internal/{schema → Type}/echo-schema.ts +9 -10
- package/src/internal/{schema → Type}/manipulation.ts +1 -1
- package/src/internal/{schema → Type}/persistent-schema.ts +9 -4
- package/src/internal/{README.md → common/README.md} +2 -2
- package/src/internal/{api → common/api}/index.ts +0 -4
- package/src/internal/{api → common/api}/meta.ts +3 -3
- package/src/internal/common/index.ts +7 -0
- package/src/internal/{proxy → common/proxy}/change-context.ts +1 -1
- package/src/internal/{proxy → common/proxy}/change.test.ts +97 -97
- package/src/internal/{proxy → common/proxy}/errors.ts +2 -2
- package/src/internal/{proxy → common/proxy}/handler.test.ts +2 -4
- package/src/internal/{proxy → common/proxy}/json-serializer.ts +6 -3
- package/src/internal/{proxy → common/proxy}/make-object.ts +1 -2
- package/src/internal/{proxy → common/proxy}/ownership.ts +0 -1
- package/src/internal/{proxy → common/proxy}/reactive-array.ts +1 -1
- package/src/internal/common/proxy/reactive.test.ts +54 -0
- package/src/internal/{proxy → common/proxy}/reactive.ts +12 -4
- package/src/internal/{proxy → common/proxy}/schema.test.ts +10 -10
- package/src/internal/{proxy → common/proxy}/typed-handler.test.ts +6 -7
- package/src/internal/{proxy → common/proxy}/typed-handler.ts +10 -13
- package/src/internal/{proxy → common/proxy}/typed-object.test.ts +5 -6
- package/src/internal/{types → common/types}/base.ts +1 -1
- package/src/internal/{types → common/types}/entity.ts +2 -2
- package/src/internal/{types → common/types}/index.ts +1 -0
- package/src/internal/{types → common/types}/meta.ts +3 -1
- package/src/internal/common/types/model-symbols.ts +69 -0
- package/src/internal/{types → common/types}/version.ts +2 -3
- package/src/internal/index.ts +9 -31
- package/src/testing/api.test.ts +4 -5
- package/src/testing/test-data.ts +157 -98
- package/src/testing/test-schema.ts +20 -18
- package/dist/lib/neutral/chunk-7WE7SBA2.mjs.map +0 -7
- package/dist/lib/neutral/chunk-7YWDDFPH.mjs.map +0 -7
- package/dist/lib/neutral/chunk-B4FLOYG7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-EXAYCLIM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-F6BTBXL7.mjs +0 -171
- package/dist/lib/neutral/chunk-F6BTBXL7.mjs.map +0 -7
- package/dist/lib/neutral/chunk-HQXQWXLH.mjs.map +0 -7
- package/dist/lib/neutral/chunk-MXQJZCPY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-RCBBZLVM.mjs +0 -142
- package/dist/lib/neutral/chunk-RCBBZLVM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-RIMHNJ3E.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ROKO4RKJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TMLVKIMX.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UMECVTXM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VJ2H5MOJ.mjs +0 -3905
- package/dist/lib/neutral/chunk-VJ2H5MOJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VYEWMV5U.mjs.map +0 -7
- package/dist/lib/neutral/chunk-X2MPMYYN.mjs +0 -13
- package/dist/lib/neutral/chunk-X2MPMYYN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-XAJMXQ4H.mjs.map +0 -7
- package/dist/lib/neutral/chunk-YPIP3WGI.mjs.map +0 -7
- package/dist/types/src/internal/annotations/annotations.d.ts.map +0 -1
- package/dist/types/src/internal/annotations/annotations.test.d.ts.map +0 -1
- package/dist/types/src/internal/annotations/index.d.ts +0 -3
- package/dist/types/src/internal/annotations/index.d.ts.map +0 -1
- package/dist/types/src/internal/annotations/util.d.ts.map +0 -1
- package/dist/types/src/internal/api/annotations.d.ts +0 -23
- package/dist/types/src/internal/api/annotations.d.ts.map +0 -1
- package/dist/types/src/internal/api/entity.d.ts.map +0 -1
- package/dist/types/src/internal/api/index.d.ts.map +0 -1
- package/dist/types/src/internal/api/meta.d.ts.map +0 -1
- package/dist/types/src/internal/api/sorting.d.ts.map +0 -1
- package/dist/types/src/internal/api/version.d.ts.map +0 -1
- package/dist/types/src/internal/entities/entity.d.ts.map +0 -1
- package/dist/types/src/internal/entities/index.d.ts.map +0 -1
- package/dist/types/src/internal/entities/model.d.ts.map +0 -1
- package/dist/types/src/internal/entities/object.d.ts.map +0 -1
- package/dist/types/src/internal/entities/relation.d.ts.map +0 -1
- package/dist/types/src/internal/entities/util.d.ts.map +0 -1
- package/dist/types/src/internal/formats/date.d.ts.map +0 -1
- package/dist/types/src/internal/formats/date.test.d.ts.map +0 -1
- package/dist/types/src/internal/formats/format.d.ts.map +0 -1
- package/dist/types/src/internal/formats/format.test.d.ts.map +0 -1
- package/dist/types/src/internal/formats/index.d.ts.map +0 -1
- package/dist/types/src/internal/formats/number.d.ts.map +0 -1
- package/dist/types/src/internal/formats/object.d.ts.map +0 -1
- package/dist/types/src/internal/formats/select.d.ts.map +0 -1
- package/dist/types/src/internal/formats/string.d.ts.map +0 -1
- package/dist/types/src/internal/formats/types.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/annotations.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/effect-schema.test.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/index.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/json-schema-normalize.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/json-schema-type.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/json-schema.d.ts.map +0 -1
- package/dist/types/src/internal/json-schema/json-schema.test.d.ts.map +0 -1
- package/dist/types/src/internal/object/clone.d.ts.map +0 -1
- package/dist/types/src/internal/object/common.d.ts.map +0 -1
- package/dist/types/src/internal/object/create-object.d.ts.map +0 -1
- package/dist/types/src/internal/object/create-object.test.d.ts.map +0 -1
- package/dist/types/src/internal/object/deleted.d.ts.map +0 -1
- package/dist/types/src/internal/object/ids.d.ts.map +0 -1
- package/dist/types/src/internal/object/index.d.ts.map +0 -1
- package/dist/types/src/internal/object/inspect.d.ts.map +0 -1
- package/dist/types/src/internal/object/json-serializer.d.ts.map +0 -1
- package/dist/types/src/internal/object/json-serializer.test.d.ts.map +0 -1
- package/dist/types/src/internal/object/schema-validator.d.ts +0 -2
- package/dist/types/src/internal/object/schema-validator.d.ts.map +0 -1
- package/dist/types/src/internal/object/schema-validator.test.d.ts.map +0 -1
- package/dist/types/src/internal/object/set-value.d.ts.map +0 -1
- package/dist/types/src/internal/object/set-value.test.d.ts.map +0 -1
- package/dist/types/src/internal/object/snapshot.d.ts.map +0 -1
- package/dist/types/src/internal/object/typed-object.d.ts.map +0 -1
- package/dist/types/src/internal/object/typed-object.test.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/change-context.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/change.test.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/define-hidden-property.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/errors.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/event-batch.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/handler.test.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/index.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/json-serializer.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/make-object.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/ownership.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/proxy-types.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/proxy-utils.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/reactive-array.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/schema-validator.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/schema.test.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/symbols.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/typed-handler.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/typed-handler.test.d.ts.map +0 -1
- package/dist/types/src/internal/proxy/typed-object.test.d.ts.map +0 -1
- package/dist/types/src/internal/ref/index.d.ts.map +0 -1
- package/dist/types/src/internal/ref/ref-array.d.ts.map +0 -1
- package/dist/types/src/internal/ref/ref.d.ts.map +0 -1
- package/dist/types/src/internal/ref/ref.test.d.ts.map +0 -1
- package/dist/types/src/internal/schema/compose.d.ts.map +0 -1
- package/dist/types/src/internal/schema/compose.test.d.ts.map +0 -1
- package/dist/types/src/internal/schema/echo-schema.d.ts.map +0 -1
- package/dist/types/src/internal/schema/index.d.ts.map +0 -1
- package/dist/types/src/internal/schema/manipulation.d.ts.map +0 -1
- package/dist/types/src/internal/schema/persistent-schema.d.ts.map +0 -1
- package/dist/types/src/internal/types/base.d.ts.map +0 -1
- package/dist/types/src/internal/types/entity.d.ts.map +0 -1
- package/dist/types/src/internal/types/index.d.ts.map +0 -1
- package/dist/types/src/internal/types/meta.d.ts.map +0 -1
- package/dist/types/src/internal/types/typename.d.ts.map +0 -1
- package/dist/types/src/internal/types/version.d.ts.map +0 -1
- package/src/internal/api/annotations.ts +0 -60
- /package/dist/lib/neutral/{chunk-ANHVGJI4.mjs.map → chunk-7RVZT53K.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-OMUPQMLR.mjs.map → chunk-V72DY6LU.mjs.map} +0 -0
- /package/dist/types/src/internal/{annotations → Annotation}/annotations.test.d.ts +0 -0
- /package/dist/types/src/internal/{entities → Entity}/util.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/date.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/date.test.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/format.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/format.test.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/index.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/number.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/object.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/select.d.ts +0 -0
- /package/dist/types/src/internal/{formats → Format}/string.d.ts +0 -0
- /package/dist/types/src/internal/{json-schema → JsonSchema}/effect-schema.test.d.ts +0 -0
- /package/dist/types/src/internal/{json-schema → JsonSchema}/index.d.ts +0 -0
- /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema-normalize.d.ts +0 -0
- /package/dist/types/src/internal/{json-schema → JsonSchema}/json-schema.test.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/clone.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/common.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/create-object.test.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/ids.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/index.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/inspect.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/json-serializer.test.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/schema-validator.test.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/set-value.test.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/snapshot.d.ts +0 -0
- /package/dist/types/src/internal/{object → Obj}/typed-object.test.d.ts +0 -0
- /package/dist/types/src/internal/{ref → Ref}/index.d.ts +0 -0
- /package/dist/types/src/internal/{ref → Ref}/ref.test.d.ts +0 -0
- /package/dist/types/src/internal/{schema → Type}/compose.test.d.ts +0 -0
- /package/dist/types/src/internal/{schema → Type}/index.d.ts +0 -0
- /package/dist/types/src/internal/{schema → Type}/manipulation.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/change.test.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/define-hidden-property.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/event-batch.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/handler.test.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/index.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/json-serializer.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/make-object.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/ownership.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/proxy-types.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/proxy-utils.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/schema-validator.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/schema.test.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/symbols.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/typed-handler.test.d.ts +0 -0
- /package/dist/types/src/internal/{proxy → common/proxy}/typed-object.test.d.ts +0 -0
- /package/dist/types/src/internal/{types → common/types}/typename.d.ts +0 -0
- /package/src/internal/{entities → Entity}/util.ts +0 -0
- /package/src/internal/{formats → Format}/date.ts +0 -0
- /package/src/internal/{formats → Format}/format.ts +0 -0
- /package/src/internal/{formats → Format}/index.ts +0 -0
- /package/src/internal/{formats → Format}/number.ts +0 -0
- /package/src/internal/{formats → Format}/object.ts +0 -0
- /package/src/internal/{formats → Format}/select.ts +0 -0
- /package/src/internal/{formats → Format}/string.ts +0 -0
- /package/src/internal/{json-schema → JsonSchema}/effect-schema.test.ts +0 -0
- /package/src/internal/{json-schema → JsonSchema}/index.ts +0 -0
- /package/src/internal/{json-schema → JsonSchema}/json-schema-normalize.ts +0 -0
- /package/src/internal/{object → Obj}/ids.ts +0 -0
- /package/src/internal/{object → Obj}/index.ts +0 -0
- /package/src/internal/{object → Obj}/schema-validator.test.ts +0 -0
- /package/src/internal/{ref → Ref}/index.ts +0 -0
- /package/src/internal/{schema → Type}/index.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/define-hidden-property.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/event-batch.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/index.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/proxy-types.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/proxy-utils.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/schema-validator.ts +0 -0
- /package/src/internal/{proxy → common/proxy}/symbols.ts +0 -0
- /package/src/internal/{types → common/types}/typename.ts +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Option from 'effect/Option';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
7
|
+
import { describe, test } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import * as Extension from './Extension';
|
|
10
|
+
|
|
11
|
+
describe('Extension', () => {
|
|
12
|
+
describe('make', () => {
|
|
13
|
+
test('creates an extension with a string schema', ({ expect }) => {
|
|
14
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
15
|
+
|
|
16
|
+
expect(ColorExtension.key).toBe('color');
|
|
17
|
+
expect(ColorExtension.valueSchema).toBe(Schema.String);
|
|
18
|
+
expect(ColorExtension[Extension.TypeId]).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('creates an extension with a number schema', ({ expect }) => {
|
|
22
|
+
const PriorityExtension = Extension.make('priority', Schema.Number);
|
|
23
|
+
|
|
24
|
+
expect(PriorityExtension.key).toBe('priority');
|
|
25
|
+
expect(PriorityExtension.valueSchema).toBe(Schema.Number);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('creates an extension with a complex schema', ({ expect }) => {
|
|
29
|
+
const MetadataSchema = Schema.Struct({
|
|
30
|
+
author: Schema.String,
|
|
31
|
+
version: Schema.Number,
|
|
32
|
+
tags: Schema.Array(Schema.String),
|
|
33
|
+
});
|
|
34
|
+
const MetadataExtension = Extension.make('metadata', MetadataSchema);
|
|
35
|
+
|
|
36
|
+
expect(MetadataExtension.key).toBe('metadata');
|
|
37
|
+
expect(MetadataExtension.valueSchema).toBe(MetadataSchema);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('get and set', () => {
|
|
42
|
+
test('set and get a string value', ({ expect }) => {
|
|
43
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
44
|
+
const values: Extension.Values = {};
|
|
45
|
+
|
|
46
|
+
Extension.set(values, ColorExtension, 'red');
|
|
47
|
+
const result = Extension.get(values, ColorExtension);
|
|
48
|
+
|
|
49
|
+
expect(Option.isSome(result)).toBe(true);
|
|
50
|
+
expect(Option.getOrThrow(result)).toBe('red');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('set and get a number value', ({ expect }) => {
|
|
54
|
+
const PriorityExtension = Extension.make('priority', Schema.Number);
|
|
55
|
+
const values: Extension.Values = {};
|
|
56
|
+
|
|
57
|
+
Extension.set(values, PriorityExtension, 42);
|
|
58
|
+
const result = Extension.get(values, PriorityExtension);
|
|
59
|
+
|
|
60
|
+
expect(Option.isSome(result)).toBe(true);
|
|
61
|
+
expect(Option.getOrThrow(result)).toBe(42);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('set and get a boolean value', ({ expect }) => {
|
|
65
|
+
const EnabledExtension = Extension.make('enabled', Schema.Boolean);
|
|
66
|
+
const values: Extension.Values = {};
|
|
67
|
+
|
|
68
|
+
Extension.set(values, EnabledExtension, true);
|
|
69
|
+
const result = Extension.get(values, EnabledExtension);
|
|
70
|
+
|
|
71
|
+
expect(Option.isSome(result)).toBe(true);
|
|
72
|
+
expect(Option.getOrThrow(result)).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('set and get a complex object value', ({ expect }) => {
|
|
76
|
+
const ConfigSchema = Schema.Struct({
|
|
77
|
+
theme: Schema.String,
|
|
78
|
+
fontSize: Schema.Number,
|
|
79
|
+
darkMode: Schema.Boolean,
|
|
80
|
+
});
|
|
81
|
+
const ConfigExtension = Extension.make('config', ConfigSchema);
|
|
82
|
+
const values: Extension.Values = {};
|
|
83
|
+
|
|
84
|
+
const config = { theme: 'modern', fontSize: 14, darkMode: true };
|
|
85
|
+
Extension.set(values, ConfigExtension, config);
|
|
86
|
+
const result = Extension.get(values, ConfigExtension);
|
|
87
|
+
|
|
88
|
+
expect(Option.isSome(result)).toBe(true);
|
|
89
|
+
expect(Option.getOrThrow(result)).toEqual(config);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('set and get an array value', ({ expect }) => {
|
|
93
|
+
const TagsExtension = Extension.make('tags', Schema.Array(Schema.String));
|
|
94
|
+
const values: Extension.Values = {};
|
|
95
|
+
|
|
96
|
+
const tags = ['important', 'urgent', 'review'];
|
|
97
|
+
Extension.set(values, TagsExtension, tags);
|
|
98
|
+
const result = Extension.get(values, TagsExtension);
|
|
99
|
+
|
|
100
|
+
expect(Option.isSome(result)).toBe(true);
|
|
101
|
+
expect(Option.getOrThrow(result)).toEqual(tags);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('get returns None for missing extension', ({ expect }) => {
|
|
105
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
106
|
+
const values: Extension.Values = {};
|
|
107
|
+
|
|
108
|
+
const result = Extension.get(values, ColorExtension);
|
|
109
|
+
|
|
110
|
+
expect(Option.isNone(result)).toBe(true);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('overwriting an extension value', ({ expect }) => {
|
|
114
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
115
|
+
const values: Extension.Values = {};
|
|
116
|
+
|
|
117
|
+
Extension.set(values, ColorExtension, 'red');
|
|
118
|
+
Extension.set(values, ColorExtension, 'blue');
|
|
119
|
+
const result = Extension.get(values, ColorExtension);
|
|
120
|
+
|
|
121
|
+
expect(Option.isSome(result)).toBe(true);
|
|
122
|
+
expect(Option.getOrThrow(result)).toBe('blue');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('multiple extensions on the same values object', ({ expect }) => {
|
|
126
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
127
|
+
const PriorityExtension = Extension.make('priority', Schema.Number);
|
|
128
|
+
const EnabledExtension = Extension.make('enabled', Schema.Boolean);
|
|
129
|
+
const values: Extension.Values = {};
|
|
130
|
+
|
|
131
|
+
Extension.set(values, ColorExtension, 'green');
|
|
132
|
+
Extension.set(values, PriorityExtension, 5);
|
|
133
|
+
Extension.set(values, EnabledExtension, false);
|
|
134
|
+
|
|
135
|
+
expect(Option.getOrThrow(Extension.get(values, ColorExtension))).toBe('green');
|
|
136
|
+
expect(Option.getOrThrow(Extension.get(values, PriorityExtension))).toBe(5);
|
|
137
|
+
expect(Option.getOrThrow(Extension.get(values, EnabledExtension))).toBe(false);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
describe('curried forms', () => {
|
|
142
|
+
test('get curried form', ({ expect }) => {
|
|
143
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
144
|
+
const values: Extension.Values = {};
|
|
145
|
+
Extension.set(values, ColorExtension, 'purple');
|
|
146
|
+
|
|
147
|
+
const getColor = Extension.get(ColorExtension);
|
|
148
|
+
const result = getColor(values);
|
|
149
|
+
|
|
150
|
+
expect(Option.isSome(result)).toBe(true);
|
|
151
|
+
expect(Option.getOrThrow(result)).toBe('purple');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('set curried form', ({ expect }) => {
|
|
155
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
156
|
+
const values: Extension.Values = {};
|
|
157
|
+
|
|
158
|
+
const setOrange = Extension.set(ColorExtension, 'orange');
|
|
159
|
+
setOrange(values);
|
|
160
|
+
const result = Extension.get(values, ColorExtension);
|
|
161
|
+
|
|
162
|
+
expect(Option.isSome(result)).toBe(true);
|
|
163
|
+
expect(Option.getOrThrow(result)).toBe('orange');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('curried forms work in pipelines', ({ expect }) => {
|
|
167
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
168
|
+
const values: Extension.Values = {};
|
|
169
|
+
|
|
170
|
+
Extension.set(ColorExtension, 'cyan')(values);
|
|
171
|
+
const result = Extension.get(ColorExtension)(values);
|
|
172
|
+
|
|
173
|
+
expect(Option.isSome(result)).toBe(true);
|
|
174
|
+
expect(Option.getOrThrow(result)).toBe('cyan');
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
describe('Key', () => {
|
|
179
|
+
test('Key.make creates a branded key', ({ expect }) => {
|
|
180
|
+
const key = Extension.Key.make('my-extension');
|
|
181
|
+
|
|
182
|
+
expect(key).toBe('my-extension');
|
|
183
|
+
expect(typeof key).toBe('string');
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe('Values schema', () => {
|
|
188
|
+
test('Values can be used as a schema', ({ expect }) => {
|
|
189
|
+
const PersonWithExtensions = Schema.Struct({
|
|
190
|
+
name: Schema.String,
|
|
191
|
+
extensions: Extension.Values,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const person = Schema.decodeUnknownSync(PersonWithExtensions)({
|
|
195
|
+
name: 'Alice',
|
|
196
|
+
extensions: {},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
expect(person.name).toBe('Alice');
|
|
200
|
+
expect(person.extensions).toEqual({});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test('Values schema accepts extension data', ({ expect }) => {
|
|
204
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
205
|
+
const values: Extension.Values = {};
|
|
206
|
+
Extension.set(values, ColorExtension, 'red');
|
|
207
|
+
|
|
208
|
+
const PersonWithExtensions = Schema.Struct({
|
|
209
|
+
name: Schema.String,
|
|
210
|
+
extensions: Extension.Values,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const person = Schema.decodeUnknownSync(PersonWithExtensions)({
|
|
214
|
+
name: 'Bob',
|
|
215
|
+
extensions: values,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
expect(person.name).toBe('Bob');
|
|
219
|
+
const color = Extension.get(person.extensions, ColorExtension);
|
|
220
|
+
expect(Option.getOrThrow(color)).toBe('red');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('TypeId', () => {
|
|
225
|
+
test('TypeId is a unique symbol-like string', ({ expect }) => {
|
|
226
|
+
expect(Extension.TypeId).toBe('~@dxos/echo/Extension');
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
test('extensions have TypeId property', ({ expect }) => {
|
|
230
|
+
const ColorExtension = Extension.make('color', Schema.String);
|
|
231
|
+
|
|
232
|
+
expect(Extension.TypeId in ColorExtension).toBe(true);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
});
|
package/src/Extension.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// @import-as-namespace
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2026 DXOS.org
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
import * as Function from 'effect/Function';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
8
|
+
import * as Schema from 'effect/Schema';
|
|
9
|
+
import type * as Types from 'effect/Types';
|
|
10
|
+
|
|
11
|
+
// @import-as-namespace
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Extensions allow objects to contain typed properties that are not part of the schema.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const TypeId = '~@dxos/echo/Extension' as const;
|
|
18
|
+
export type TypeId = typeof TypeId;
|
|
19
|
+
|
|
20
|
+
export interface Extension<T> extends Record<
|
|
21
|
+
TypeId,
|
|
22
|
+
{
|
|
23
|
+
_Type: T;
|
|
24
|
+
}
|
|
25
|
+
> {
|
|
26
|
+
readonly [TypeId]: {
|
|
27
|
+
_Type: T;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
readonly key: Key;
|
|
31
|
+
readonly valueSchema: Schema.Schema<T>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Create a new typed extension.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* const ColorExtension = Extension.make('color', Schema.String);
|
|
39
|
+
*
|
|
40
|
+
* const obj = Obj.make(Person, {
|
|
41
|
+
* [Obj.Meta]: { keys: [{ source: 'external', id: '123' }] },
|
|
42
|
+
* name: 'John',
|
|
43
|
+
* email: 'john@example.com',
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* Obj.update(obj, (obj) => {
|
|
47
|
+
* Extension.set(obj.extensions, ColorExtension, 'red');
|
|
48
|
+
* });
|
|
49
|
+
*
|
|
50
|
+
* console.log(Extension.get(obj.extensions, ColorExtension)); // 'red'
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const make = <S extends Schema.Schema.AnyNoContext>(
|
|
54
|
+
key: string,
|
|
55
|
+
valueSchema: S,
|
|
56
|
+
): Extension<Schema.Schema.Type<S>> => {
|
|
57
|
+
return {
|
|
58
|
+
[TypeId]: {} as any,
|
|
59
|
+
key: Key.make(key),
|
|
60
|
+
valueSchema,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Unique identifier for an extension.
|
|
66
|
+
*/
|
|
67
|
+
// TODO(dmaretskyi): filter to be fully qualified: (e.g., org.dxos.extension.color)
|
|
68
|
+
export const Key = Schema.String.pipe(Schema.brand('~@dxos/echo/ExtensionKey'));
|
|
69
|
+
export type Key = Schema.Schema.Type<typeof Key>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Set of extension values.
|
|
73
|
+
*
|
|
74
|
+
* Can be used inside an object/relation schema:
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* const Person = Schema.Struct({
|
|
78
|
+
* name: Schema.String,
|
|
79
|
+
* extensions: Extension.Values,
|
|
80
|
+
* });
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export const Values = Schema.Record({ key: Key, value: Schema.Unknown });
|
|
84
|
+
export interface Values extends Schema.Schema.Type<typeof Values> {}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get the value of an extension from a set of values.
|
|
88
|
+
*/
|
|
89
|
+
export const get: {
|
|
90
|
+
<T>(extension: Extension<T>): (values: Values) => Option.Option<T>;
|
|
91
|
+
<T>(values: Values, extension: Extension<T>): Option.Option<T>;
|
|
92
|
+
} = Function.dual<
|
|
93
|
+
<T>(extension: Extension<T>) => (values: Values) => Option.Option<T>,
|
|
94
|
+
<T>(values: Values, extension: Extension<T>) => Option.Option<T>
|
|
95
|
+
>(2, (values, extension) => {
|
|
96
|
+
if (!(extension.key in values)) {
|
|
97
|
+
return Option.none();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return Function.pipe(values[extension.key], Schema.decodeUnknownSync(extension.valueSchema), Option.some);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Set the value of an extension in a set of values.
|
|
105
|
+
*
|
|
106
|
+
* Can also be used within Obj.update callback:
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* Obj.update(obj, (obj) => {
|
|
110
|
+
* Extension.set(obj.extensions, ColorExtension, 'red');
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export const set: {
|
|
115
|
+
<T>(extension: Extension<T>, value: T): (values: Values) => void;
|
|
116
|
+
<T>(values: Types.Mutable<Values>, extension: Extension<T>, value: T): void;
|
|
117
|
+
} = Function.dual<
|
|
118
|
+
<T>(extension: Extension<T>, value: T) => (values: Values) => void,
|
|
119
|
+
<T>(values: Types.Mutable<Values>, extension: Extension<T>, value: T) => void
|
|
120
|
+
>(3, (values, extension, value) => {
|
|
121
|
+
values[extension.key] = Schema.encodeSync(extension.valueSchema)(value);
|
|
122
|
+
});
|
package/src/Feed.ts
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
7
|
+
import * as Context from 'effect/Context';
|
|
8
|
+
import * as Effect from 'effect/Effect';
|
|
9
|
+
import * as Layer from 'effect/Layer';
|
|
10
|
+
import type * as Option from 'effect/Option';
|
|
11
|
+
import * as Schema from 'effect/Schema';
|
|
12
|
+
|
|
13
|
+
import { DXN, type ObjectId } from '@dxos/keys';
|
|
14
|
+
|
|
15
|
+
import * as Annotation from './Annotation';
|
|
16
|
+
import type * as Entity from './Entity';
|
|
17
|
+
import type * as Filter from './Filter';
|
|
18
|
+
import * as internal from './internal';
|
|
19
|
+
import * as Obj from './Obj';
|
|
20
|
+
import type * as Query from './Query';
|
|
21
|
+
import type * as QueryResult from './QueryResult';
|
|
22
|
+
import * as Type from './Type';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Runtime schema for a Feed object.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export const Feed = Schema.Struct({
|
|
33
|
+
/** User-facing display name. */
|
|
34
|
+
name: Schema.String.pipe(Schema.optional),
|
|
35
|
+
/** Identifier for the feed's kind (e.g., plugin id). */
|
|
36
|
+
kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Feed namespace.
|
|
40
|
+
* Controls how feed data is stored and replicated.
|
|
41
|
+
* - `data`: Data feed (default).
|
|
42
|
+
* - `trace`: Trace feed.
|
|
43
|
+
*/
|
|
44
|
+
namespace: Schema.optional(Schema.Literal('data', 'trace')),
|
|
45
|
+
}).pipe(
|
|
46
|
+
Type.object({
|
|
47
|
+
typename: 'org.dxos.type.feed',
|
|
48
|
+
version: '0.1.0',
|
|
49
|
+
}),
|
|
50
|
+
internal.SystemTypeAnnotation.set(true),
|
|
51
|
+
Annotation.IconAnnotation.set({
|
|
52
|
+
icon: 'ph--rows--regular',
|
|
53
|
+
hue: 'yellow',
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* TypeScript instance type for a Feed object.
|
|
59
|
+
*/
|
|
60
|
+
export interface Feed extends Schema.Schema.Type<typeof Feed> {}
|
|
61
|
+
|
|
62
|
+
//
|
|
63
|
+
// Types
|
|
64
|
+
//
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Opaque cursor for iterating over feed items.
|
|
68
|
+
*/
|
|
69
|
+
// TODO(dmaretskyi): T needs to be referenced in the type structure for typescript to respect it during inference and type-checking.
|
|
70
|
+
export interface Cursor<T = Obj.Snapshot> {
|
|
71
|
+
readonly _tag: 'Cursor';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Retention options for a feed.
|
|
76
|
+
*/
|
|
77
|
+
export interface RetentionOptions {
|
|
78
|
+
/** Retain items after this cursor position. */
|
|
79
|
+
// TODO(wittjosiah): Use FeedCursor from @dxos/feed?
|
|
80
|
+
cursor?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//
|
|
84
|
+
// Factory
|
|
85
|
+
//
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Creates a new feed object.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
// TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?
|
|
96
|
+
export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Derives the queue DXN from the feed object's DXN.
|
|
100
|
+
* Returns `undefined` when the feed is not stored in a space yet.
|
|
101
|
+
*
|
|
102
|
+
* Used internally by the feed service layer.
|
|
103
|
+
*/
|
|
104
|
+
export const getQueueDxn = (feed: Feed): DXN | undefined => {
|
|
105
|
+
const self = Obj.getDXN(feed).asEchoDXN();
|
|
106
|
+
if (!self || !self.spaceId) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return new DXN(DXN.kind.QUEUE, [feed.namespace ?? 'data', self.spaceId, self.echoId]);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Creates a Feed object from a queue DXN, inferring the feed's id and namespace from the DXN parts.
|
|
114
|
+
*
|
|
115
|
+
* The resulting Feed, when added to the same space as the queue, will have a queue DXN
|
|
116
|
+
* equal to the input (see `Feed.getQueueDxn`). Useful when migrating `Ref(Queue)` fields to
|
|
117
|
+
* `Ref(Feed.Feed)`.
|
|
118
|
+
*
|
|
119
|
+
* @remarks Unsafe because the caller must ensure the queue DXN's space matches the database
|
|
120
|
+
* the feed is added to; the feed id is set from the queue id, bypassing id generation.
|
|
121
|
+
*/
|
|
122
|
+
export const unsafeFromQueueDXN = (queueDxn: DXN): Feed => {
|
|
123
|
+
const parts = queueDxn.asQueueDXN();
|
|
124
|
+
if (!parts) {
|
|
125
|
+
throw new Error(`Expected a queue DXN, got: ${queueDxn.toString()}`);
|
|
126
|
+
}
|
|
127
|
+
return Obj.make(Feed, {
|
|
128
|
+
id: parts.queueId as ObjectId,
|
|
129
|
+
namespace: parts.subspaceTag === 'trace' ? 'trace' : undefined,
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
//
|
|
134
|
+
// Service
|
|
135
|
+
//
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Effect service for feed operations.
|
|
139
|
+
* Provides the bridge to the underlying storage implementation.
|
|
140
|
+
* Must be provided by the application layer (e.g., echo-db).
|
|
141
|
+
*/
|
|
142
|
+
export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
|
|
143
|
+
FeedService,
|
|
144
|
+
{
|
|
145
|
+
/**
|
|
146
|
+
* Appends items to a feed.
|
|
147
|
+
*/
|
|
148
|
+
append(feed: Feed, items: Entity.Unknown[]): Promise<void>;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Removes items from a feed by ID.
|
|
152
|
+
*/
|
|
153
|
+
// TODO(dmaretskyi): Change type to ObjectId.
|
|
154
|
+
remove(feed: Feed, ids: string[]): Promise<void>;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Queries items in a feed.
|
|
158
|
+
*/
|
|
159
|
+
query: {
|
|
160
|
+
<Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;
|
|
161
|
+
<F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
>() {}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @deprecated Use `FeedService` instead.
|
|
168
|
+
*/
|
|
169
|
+
export type Service = FeedService;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @deprecated Use `FeedService` instead.
|
|
173
|
+
*/
|
|
174
|
+
export const Service = FeedService;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Layer that provides a Feed service that throws when accessed.
|
|
178
|
+
* Useful as a default layer when no feed service is available.
|
|
179
|
+
*/
|
|
180
|
+
export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {
|
|
181
|
+
append: () => {
|
|
182
|
+
throw new Error('Feed.FeedService not available');
|
|
183
|
+
},
|
|
184
|
+
remove: () => {
|
|
185
|
+
throw new Error('Feed.FeedService not available');
|
|
186
|
+
},
|
|
187
|
+
query: () => {
|
|
188
|
+
throw new Error('Feed.FeedService not available');
|
|
189
|
+
},
|
|
190
|
+
} as Context.Tag.Service<FeedService>);
|
|
191
|
+
|
|
192
|
+
//
|
|
193
|
+
// Operations
|
|
194
|
+
//
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Appends items to a feed.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```ts
|
|
201
|
+
* yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>
|
|
205
|
+
Effect.gen(function* () {
|
|
206
|
+
const service = yield* FeedService;
|
|
207
|
+
yield* Effect.promise(() => service.append(feed, items));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Removes items from a feed.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* yield* Feed.remove(feed, [item]);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
// TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?
|
|
219
|
+
export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>
|
|
220
|
+
Effect.gen(function* () {
|
|
221
|
+
const service = yield* FeedService;
|
|
222
|
+
const ids = items.map((item) => item.id);
|
|
223
|
+
yield* Effect.promise(() => service.remove(feed, ids));
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Creates a reactive query over items in a feed.
|
|
228
|
+
*
|
|
229
|
+
* @example
|
|
230
|
+
* ```ts
|
|
231
|
+
* const result = yield* Feed.query(feed, Filter.type(Person));
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
// TODO(dmaretskyi): Suport chained queries:
|
|
235
|
+
// const result = yield* feed.pipe(Feed.query(Filter.type(Person))); result.subscribe(...)
|
|
236
|
+
// const objects = yield* feed.pipe(Feed.query(Filter.type(Person))).run;
|
|
237
|
+
// const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;
|
|
238
|
+
// ... unify for Database and schema queries.
|
|
239
|
+
export const query: {
|
|
240
|
+
<Q extends Query.Any>(
|
|
241
|
+
feed: Feed,
|
|
242
|
+
query: Q,
|
|
243
|
+
): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, FeedService>;
|
|
244
|
+
<F extends Filter.Any>(
|
|
245
|
+
feed: Feed,
|
|
246
|
+
filter: F,
|
|
247
|
+
): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, FeedService>;
|
|
248
|
+
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
249
|
+
FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Executes a feed query once and returns the results.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```ts
|
|
256
|
+
* const items = yield* Feed.runQuery(feed, Filter.type(Person));
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
export const runQuery: {
|
|
260
|
+
<Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, FeedService>;
|
|
261
|
+
<F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, FeedService>;
|
|
262
|
+
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
263
|
+
query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Creates a cursor for iterating over feed items.
|
|
267
|
+
* Currently stubbed — cursor operations are not yet implemented.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```ts
|
|
271
|
+
* const cursor = yield* Feed.cursor<Person>(feed);
|
|
272
|
+
* const item = yield* Feed.next(cursor);
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
// TODO(wittjosiah): Implement cursor operations. Use Effect streams?
|
|
276
|
+
export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>
|
|
277
|
+
Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Returns the next item from a feed cursor.
|
|
281
|
+
* Currently stubbed — cursor operations are not yet implemented.
|
|
282
|
+
*/
|
|
283
|
+
export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>
|
|
284
|
+
Effect.die('Feed.next is not yet implemented');
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Returns the next item from a feed cursor as an Option.
|
|
288
|
+
* Currently stubbed — cursor operations are not yet implemented.
|
|
289
|
+
*/
|
|
290
|
+
export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>
|
|
291
|
+
Effect.die('Feed.nextOption is not yet implemented');
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Sets the local retention policy for a feed.
|
|
295
|
+
* Currently stubbed — queues do not yet support retention.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```ts
|
|
299
|
+
* yield* Feed.setRetention(feed, { count: 1000 });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
// TODO(feed): Implement when queue retention is supported.
|
|
303
|
+
export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
|
|
304
|
+
Effect.void;
|