@dxos/echo 0.8.4-main.c85a9c8dae → 0.8.4-main.cb12b3f963
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/dist/lib/neutral/Annotation.mjs +3 -3
- package/dist/lib/neutral/Database.mjs +8 -4
- package/dist/lib/neutral/Entity.mjs +16 -11
- 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 +21 -14
- package/dist/lib/neutral/Filter.mjs +21 -10
- package/dist/lib/neutral/Format.mjs +3 -3
- package/dist/lib/neutral/JsonSchema.mjs +8 -7
- 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 +16 -10
- package/dist/lib/neutral/Order.mjs +1 -1
- package/dist/lib/neutral/Query.mjs +19 -13
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +7 -7
- package/dist/lib/neutral/Relation.mjs +15 -11
- package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
- package/dist/lib/neutral/Tag.mjs +14 -10
- package/dist/lib/neutral/Type.mjs +10 -7
- package/dist/lib/neutral/{chunk-ALOGSVBP.mjs → chunk-3U5PIVPZ.mjs} +59 -4
- package/dist/lib/neutral/chunk-3U5PIVPZ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-DZQSL6RW.mjs → chunk-44HT3MEC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-DZQSL6RW.mjs.map → chunk-44HT3MEC.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-5ELDDYWE.mjs → chunk-4VTRFJV3.mjs} +17 -19
- package/dist/lib/neutral/chunk-4VTRFJV3.mjs.map +7 -0
- package/dist/lib/neutral/chunk-5NR2KWDU.mjs +34 -0
- package/dist/lib/neutral/chunk-5NR2KWDU.mjs.map +7 -0
- package/dist/lib/neutral/chunk-62RJTYOZ.mjs +346 -0
- package/dist/lib/neutral/chunk-62RJTYOZ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OVUBTQLT.mjs → chunk-7OO5B5DD.mjs} +2 -2
- package/dist/lib/neutral/chunk-7OO5B5DD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7RVZT53K.mjs} +1 -1
- package/dist/lib/neutral/{chunk-GAWKQ5DZ.mjs → chunk-AG7JS76F.mjs} +5 -5
- package/dist/lib/neutral/chunk-AG7JS76F.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-PP4DNUZU.mjs → chunk-AVPYX7FF.mjs} +1399 -2882
- package/dist/lib/neutral/chunk-AVPYX7FF.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ZWKJ4LZJ.mjs → chunk-BCKTAKBX.mjs} +23 -51
- package/dist/lib/neutral/chunk-BCKTAKBX.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-T6JEFNP6.mjs → chunk-BICZKPQG.mjs} +1 -1
- package/dist/lib/neutral/{chunk-T6JEFNP6.mjs.map → chunk-BICZKPQG.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-F7KMHDPJ.mjs → chunk-GECFB2UL.mjs} +49 -31
- package/dist/lib/neutral/chunk-GECFB2UL.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-BRJSLACP.mjs → chunk-M7ET73JD.mjs} +71 -17
- package/dist/lib/neutral/chunk-M7ET73JD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-4KG6IGL4.mjs → chunk-N4B7FHQT.mjs} +4 -4
- package/dist/lib/neutral/{chunk-4KG6IGL4.mjs.map → chunk-N4B7FHQT.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-KGV3QIRX.mjs → chunk-NCSIQP3L.mjs} +124 -17
- package/dist/lib/neutral/chunk-NCSIQP3L.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-QXF3LGN2.mjs → chunk-NGQNU3KX.mjs} +5 -3
- package/dist/lib/neutral/chunk-NGQNU3KX.mjs.map +7 -0
- package/dist/lib/neutral/chunk-PRCRETDK.mjs +36 -0
- package/dist/lib/neutral/chunk-PRCRETDK.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-AQP4QKYP.mjs → chunk-S4JXD2RO.mjs} +44 -9
- package/dist/lib/neutral/chunk-S4JXD2RO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-W7OP5HGZ.mjs → chunk-SVEGO3DJ.mjs} +14 -10
- package/dist/lib/neutral/chunk-SVEGO3DJ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-M2KVTHZM.mjs → chunk-TRPZU2HV.mjs} +10 -10
- package/dist/lib/neutral/chunk-TRPZU2HV.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ZTUBYOGB.mjs → chunk-TTCSATUD.mjs} +1 -1
- package/dist/lib/neutral/chunk-TTCSATUD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-GFNCSK7F.mjs → chunk-TTUIJXGD.mjs} +54 -23
- package/dist/lib/neutral/chunk-TTUIJXGD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
- package/dist/lib/neutral/{chunk-T4MPQJ7X.mjs → chunk-WGMPVUUL.mjs} +6 -22
- package/dist/lib/neutral/chunk-WGMPVUUL.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-O3TZFQCT.mjs → chunk-YDRLYZKW.mjs} +2 -2
- package/dist/lib/neutral/chunk-YDRLYZKW.mjs.map +7 -0
- package/dist/lib/neutral/chunk-Z25FPDXG.mjs +734 -0
- package/dist/lib/neutral/chunk-Z25FPDXG.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 +38 -25
- package/dist/lib/neutral/internal/index.mjs +48 -38
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +41 -35
- package/dist/lib/neutral/testing/index.mjs.map +2 -2
- 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.map +1 -1
- package/dist/types/src/Database.d.ts +15 -3
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +2 -1
- package/dist/types/src/Dataset.d.ts.map +1 -1
- package/dist/types/src/Entity.d.ts +17 -11
- 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 +40 -23
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts +33 -4
- 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 +1 -1
- package/dist/types/src/Format.d.ts.map +1 -1
- package/dist/types/src/Hypergraph.d.ts +6 -1
- 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 +5 -5
- 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 +45 -29
- 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 +13 -2
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +11 -11
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +16 -16
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/SchemaRegistry.d.ts +1 -1
- package/dist/types/src/Tag.d.ts +2 -2
- package/dist/types/src/Tag.d.ts.map +1 -1
- package/dist/types/src/Type.d.ts +10 -9
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +1 -1
- package/dist/types/src/View.d.ts.map +1 -1
- package/dist/types/src/exemplars.test.d.ts +2 -0
- package/dist/types/src/exemplars.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/{annotations → Annotation}/annotations.d.ts +24 -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 +2 -2
- 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 +23 -23
- 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 +2 -2
- 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 +6 -6
- 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/common/types/base.d.ts.map +1 -0
- package/dist/types/src/internal/{types → common/types}/entity.d.ts +4 -4
- 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 +3 -3
- 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 +1 -1
- 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.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +53 -53
- 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 +24 -14
- package/src/Annotation.ts +5 -3
- package/src/Collection.ts +8 -1
- package/src/Database.ts +54 -17
- package/src/Dataset.ts +2 -0
- package/src/Entity.ts +20 -11
- package/src/Err.ts +2 -0
- package/src/Extension.test.ts +235 -0
- package/src/Extension.ts +122 -0
- package/src/Feed.ts +86 -36
- package/src/Filter.test.ts +90 -0
- package/src/Filter.ts +68 -3
- package/src/Format.ts +1 -1
- package/src/Hypergraph.ts +7 -2
- package/src/Json.test.ts +175 -0
- package/src/Json.ts +102 -0
- package/src/JsonSchema.ts +7 -5
- package/src/Migration.ts +94 -0
- package/src/Obj.test.ts +107 -15
- package/src/Obj.ts +166 -40
- package/src/Order.ts +2 -0
- package/src/Query.test.ts +221 -31
- package/src/Query.ts +50 -3
- package/src/Ref.ts +14 -12
- package/src/Relation.test.ts +2 -2
- package/src/Relation.ts +28 -21
- package/src/SchemaRegistry.ts +1 -1
- package/src/Tag.ts +3 -1
- package/src/Type.ts +14 -11
- package/src/View.ts +9 -2
- package/src/exemplars.test.ts +21 -0
- package/src/index.ts +4 -0
- package/src/internal/{annotations → Annotation}/annotations.test.ts +56 -7
- package/src/internal/{annotations → Annotation}/annotations.ts +71 -20
- 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 +2 -2
- 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 +3 -4
- 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 +8 -9
- package/src/internal/{object → Obj}/json-serializer.ts +36 -18
- 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 +14 -5
- package/src/internal/{object → Obj}/typed-object.test.ts +3 -3
- package/src/internal/{object → Obj}/typed-object.ts +2 -2
- 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 +7 -8
- package/src/internal/{schema → Type}/manipulation.ts +1 -1
- package/src/internal/{schema → Type}/persistent-schema.ts +7 -7
- package/src/internal/{README.md → common/README.md} +1 -1
- 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}/entity.ts +1 -1
- package/src/internal/{types → common/types}/index.ts +1 -0
- package/src/internal/{types → common/types}/meta.ts +1 -2
- package/src/internal/common/types/model-symbols.ts +69 -0
- package/src/internal/index.ts +9 -31
- package/src/testing/api.test.ts +2 -3
- package/src/testing/test-data.ts +0 -1
- package/src/testing/test-schema.ts +9 -9
- package/dist/lib/neutral/chunk-5ELDDYWE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ALOGSVBP.mjs.map +0 -7
- package/dist/lib/neutral/chunk-AQP4QKYP.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BRJSLACP.mjs.map +0 -7
- package/dist/lib/neutral/chunk-F7KMHDPJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GAWKQ5DZ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GFNCSK7F.mjs.map +0 -7
- package/dist/lib/neutral/chunk-KGV3QIRX.mjs.map +0 -7
- package/dist/lib/neutral/chunk-M2KVTHZM.mjs.map +0 -7
- package/dist/lib/neutral/chunk-MXQJZCPY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-O3TZFQCT.mjs.map +0 -7
- package/dist/lib/neutral/chunk-OVUBTQLT.mjs.map +0 -7
- package/dist/lib/neutral/chunk-PP4DNUZU.mjs.map +0 -7
- package/dist/lib/neutral/chunk-QXF3LGN2.mjs.map +0 -7
- package/dist/lib/neutral/chunk-T4MPQJ7X.mjs.map +0 -7
- package/dist/lib/neutral/chunk-W7OP5HGZ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ZTUBYOGB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ZWKJ4LZJ.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}/base.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}/base.ts +0 -0
- /package/src/internal/{types → common/types}/typename.ts +0 -0
- /package/src/internal/{types → common/types}/version.ts +0 -0
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
CHANGED
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
5
7
|
import * as Context from 'effect/Context';
|
|
6
8
|
import * as Effect from 'effect/Effect';
|
|
7
9
|
import * as Layer from 'effect/Layer';
|
|
8
10
|
import type * as Option from 'effect/Option';
|
|
9
11
|
import * as Schema from 'effect/Schema';
|
|
10
12
|
|
|
11
|
-
import { DXN } from '@dxos/keys';
|
|
13
|
+
import { DXN, type ObjectId } from '@dxos/keys';
|
|
12
14
|
|
|
15
|
+
import * as Annotation from './Annotation';
|
|
13
16
|
import type * as Entity from './Entity';
|
|
14
17
|
import type * as Filter from './Filter';
|
|
15
18
|
import * as internal from './internal';
|
|
@@ -23,7 +26,7 @@ import * as Type from './Type';
|
|
|
23
26
|
*
|
|
24
27
|
* @example
|
|
25
28
|
* ```ts
|
|
26
|
-
* const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'dxos.
|
|
29
|
+
* const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
|
|
27
30
|
* ```
|
|
28
31
|
*/
|
|
29
32
|
export const Feed = Schema.Struct({
|
|
@@ -31,11 +34,24 @@ export const Feed = Schema.Struct({
|
|
|
31
34
|
name: Schema.String.pipe(Schema.optional),
|
|
32
35
|
/** Identifier for the feed's kind (e.g., plugin id). */
|
|
33
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')),
|
|
34
45
|
}).pipe(
|
|
35
46
|
Type.object({
|
|
36
|
-
typename: 'dxos.
|
|
47
|
+
typename: 'org.dxos.type.feed',
|
|
37
48
|
version: '0.1.0',
|
|
38
49
|
}),
|
|
50
|
+
internal.SystemTypeAnnotation.set(true),
|
|
51
|
+
Annotation.IconAnnotation.set({
|
|
52
|
+
icon: 'ph--rows--regular',
|
|
53
|
+
hue: 'yellow',
|
|
54
|
+
}),
|
|
39
55
|
);
|
|
40
56
|
|
|
41
57
|
/**
|
|
@@ -47,12 +63,6 @@ export interface Feed extends Schema.Schema.Type<typeof Feed> {}
|
|
|
47
63
|
// Types
|
|
48
64
|
//
|
|
49
65
|
|
|
50
|
-
/**
|
|
51
|
-
* Meta key source for storing the backing DXN bound to a feed object.
|
|
52
|
-
*/
|
|
53
|
-
// TODO(dmaretskyi): Enforce that Feed ObjectId = feed storage ID. And remove this key.
|
|
54
|
-
export const DXN_KEY = 'dxos.org/key/feed';
|
|
55
|
-
|
|
56
66
|
/**
|
|
57
67
|
* Opaque cursor for iterating over feed items.
|
|
58
68
|
*/
|
|
@@ -79,21 +89,45 @@ export interface RetentionOptions {
|
|
|
79
89
|
*
|
|
80
90
|
* @example
|
|
81
91
|
* ```ts
|
|
82
|
-
* const feed = Feed.make({ name: 'notifications', kind: 'dxos.
|
|
92
|
+
* const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });
|
|
83
93
|
* ```
|
|
84
94
|
*/
|
|
85
95
|
// TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?
|
|
86
|
-
export const make = (props: Obj.MakeProps<typeof Feed>): Feed => Obj.make(Feed, props);
|
|
96
|
+
export const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);
|
|
87
97
|
|
|
88
98
|
/**
|
|
89
|
-
*
|
|
99
|
+
* Derives the queue DXN from the feed object's DXN.
|
|
100
|
+
* Returns `undefined` when the feed is not stored in a space yet.
|
|
90
101
|
*
|
|
91
|
-
*
|
|
102
|
+
* Used internally by the feed service layer.
|
|
92
103
|
*/
|
|
93
|
-
// TODO(wittjosiah): Align backing feed dxn's with object DXN.
|
|
94
104
|
export const getQueueDxn = (feed: Feed): DXN | undefined => {
|
|
95
|
-
const
|
|
96
|
-
|
|
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
|
+
});
|
|
97
131
|
};
|
|
98
132
|
|
|
99
133
|
//
|
|
@@ -105,8 +139,8 @@ export const getQueueDxn = (feed: Feed): DXN | undefined => {
|
|
|
105
139
|
* Provides the bridge to the underlying storage implementation.
|
|
106
140
|
* Must be provided by the application layer (e.g., echo-db).
|
|
107
141
|
*/
|
|
108
|
-
export class
|
|
109
|
-
|
|
142
|
+
export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
|
|
143
|
+
FeedService,
|
|
110
144
|
{
|
|
111
145
|
/**
|
|
112
146
|
* Appends items to a feed.
|
|
@@ -129,21 +163,31 @@ export class Service extends Context.Tag('@dxos/echo/Feed/Service')<
|
|
|
129
163
|
}
|
|
130
164
|
>() {}
|
|
131
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
|
+
|
|
132
176
|
/**
|
|
133
177
|
* Layer that provides a Feed service that throws when accessed.
|
|
134
178
|
* Useful as a default layer when no feed service is available.
|
|
135
179
|
*/
|
|
136
|
-
export const notAvailable: Layer.Layer<
|
|
180
|
+
export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {
|
|
137
181
|
append: () => {
|
|
138
|
-
throw new Error('Feed.
|
|
182
|
+
throw new Error('Feed.FeedService not available');
|
|
139
183
|
},
|
|
140
184
|
remove: () => {
|
|
141
|
-
throw new Error('Feed.
|
|
185
|
+
throw new Error('Feed.FeedService not available');
|
|
142
186
|
},
|
|
143
187
|
query: () => {
|
|
144
|
-
throw new Error('Feed.
|
|
188
|
+
throw new Error('Feed.FeedService not available');
|
|
145
189
|
},
|
|
146
|
-
} as Context.Tag.Service<
|
|
190
|
+
} as Context.Tag.Service<FeedService>);
|
|
147
191
|
|
|
148
192
|
//
|
|
149
193
|
// Operations
|
|
@@ -157,9 +201,9 @@ export const notAvailable: Layer.Layer<Service> = Layer.succeed(Service, {
|
|
|
157
201
|
* yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);
|
|
158
202
|
* ```
|
|
159
203
|
*/
|
|
160
|
-
export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never,
|
|
204
|
+
export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>
|
|
161
205
|
Effect.gen(function* () {
|
|
162
|
-
const service = yield*
|
|
206
|
+
const service = yield* FeedService;
|
|
163
207
|
yield* Effect.promise(() => service.append(feed, items));
|
|
164
208
|
});
|
|
165
209
|
|
|
@@ -172,9 +216,9 @@ export const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void,
|
|
|
172
216
|
* ```
|
|
173
217
|
*/
|
|
174
218
|
// TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?
|
|
175
|
-
export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never,
|
|
219
|
+
export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>
|
|
176
220
|
Effect.gen(function* () {
|
|
177
|
-
const service = yield*
|
|
221
|
+
const service = yield* FeedService;
|
|
178
222
|
const ids = items.map((item) => item.id);
|
|
179
223
|
yield* Effect.promise(() => service.remove(feed, ids));
|
|
180
224
|
});
|
|
@@ -193,10 +237,16 @@ export const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Ef
|
|
|
193
237
|
// const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;
|
|
194
238
|
// ... unify for Database and schema queries.
|
|
195
239
|
export const query: {
|
|
196
|
-
<Q extends Query.Any>(
|
|
197
|
-
|
|
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>;
|
|
198
248
|
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
199
|
-
|
|
249
|
+
FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));
|
|
200
250
|
|
|
201
251
|
/**
|
|
202
252
|
* Executes a feed query once and returns the results.
|
|
@@ -207,8 +257,8 @@ export const query: {
|
|
|
207
257
|
* ```
|
|
208
258
|
*/
|
|
209
259
|
export const runQuery: {
|
|
210
|
-
<Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never,
|
|
211
|
-
<F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never,
|
|
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>;
|
|
212
262
|
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
213
263
|
query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
|
|
214
264
|
|
|
@@ -223,21 +273,21 @@ export const runQuery: {
|
|
|
223
273
|
* ```
|
|
224
274
|
*/
|
|
225
275
|
// TODO(wittjosiah): Implement cursor operations. Use Effect streams?
|
|
226
|
-
export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never,
|
|
276
|
+
export const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>
|
|
227
277
|
Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);
|
|
228
278
|
|
|
229
279
|
/**
|
|
230
280
|
* Returns the next item from a feed cursor.
|
|
231
281
|
* Currently stubbed — cursor operations are not yet implemented.
|
|
232
282
|
*/
|
|
233
|
-
export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never,
|
|
283
|
+
export const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>
|
|
234
284
|
Effect.die('Feed.next is not yet implemented');
|
|
235
285
|
|
|
236
286
|
/**
|
|
237
287
|
* Returns the next item from a feed cursor as an Option.
|
|
238
288
|
* Currently stubbed — cursor operations are not yet implemented.
|
|
239
289
|
*/
|
|
240
|
-
export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never,
|
|
290
|
+
export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>
|
|
241
291
|
Effect.die('Feed.nextOption is not yet implemented');
|
|
242
292
|
|
|
243
293
|
/**
|
|
@@ -250,5 +300,5 @@ export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<
|
|
|
250
300
|
* ```
|
|
251
301
|
*/
|
|
252
302
|
// TODO(feed): Implement when queue retention is supported.
|
|
253
|
-
export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never,
|
|
303
|
+
export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
|
|
254
304
|
Effect.void;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import * as Filter from './Filter';
|
|
8
|
+
|
|
9
|
+
describe('Filter timestamp builders', () => {
|
|
10
|
+
test('updated({ after }) produces correct AST', () => {
|
|
11
|
+
const ts = 1700000000000;
|
|
12
|
+
const f = Filter.updated({ after: ts });
|
|
13
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'updatedAt', operator: 'gte', value: ts });
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('updated({ before }) produces correct AST', () => {
|
|
17
|
+
const ts = 1700000000000;
|
|
18
|
+
const f = Filter.updated({ before: ts });
|
|
19
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'updatedAt', operator: 'lte', value: ts });
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('created({ after }) produces correct AST', () => {
|
|
23
|
+
const ts = 1700000000000;
|
|
24
|
+
const f = Filter.created({ after: ts });
|
|
25
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'createdAt', operator: 'gte', value: ts });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('created({ before }) produces correct AST', () => {
|
|
29
|
+
const ts = 1700000000000;
|
|
30
|
+
const f = Filter.created({ before: ts });
|
|
31
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'createdAt', operator: 'lte', value: ts });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('updated() accepts Date objects', () => {
|
|
35
|
+
const date = new Date('2026-03-20T21:00:00Z');
|
|
36
|
+
const f = Filter.updated({ after: date });
|
|
37
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'updatedAt', operator: 'gte', value: date.getTime() });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('created() accepts Date objects', () => {
|
|
41
|
+
const date = new Date('2026-03-20T09:00:00Z');
|
|
42
|
+
const f = Filter.created({ before: date });
|
|
43
|
+
expect(f.ast).toEqual({ type: 'timestamp', field: 'createdAt', operator: 'lte', value: date.getTime() });
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('updated({ after, before }) produces AND of two timestamp nodes', () => {
|
|
47
|
+
const from = 1700000000000;
|
|
48
|
+
const to = 1700086400000;
|
|
49
|
+
const f = Filter.updated({ after: from, before: to });
|
|
50
|
+
expect(f.ast).toEqual({
|
|
51
|
+
type: 'and',
|
|
52
|
+
filters: [
|
|
53
|
+
{ type: 'timestamp', field: 'updatedAt', operator: 'gte', value: from },
|
|
54
|
+
{ type: 'timestamp', field: 'updatedAt', operator: 'lte', value: to },
|
|
55
|
+
],
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('updated({ after, before }) accepts Date objects', () => {
|
|
60
|
+
const from = new Date('2026-03-19T00:00:00Z');
|
|
61
|
+
const to = new Date('2026-03-20T00:00:00Z');
|
|
62
|
+
const f = Filter.updated({ after: from, before: to });
|
|
63
|
+
expect(f.ast).toEqual({
|
|
64
|
+
type: 'and',
|
|
65
|
+
filters: [
|
|
66
|
+
{ type: 'timestamp', field: 'updatedAt', operator: 'gte', value: from.getTime() },
|
|
67
|
+
{ type: 'timestamp', field: 'updatedAt', operator: 'lte', value: to.getTime() },
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('timestamp filters compose with and()', () => {
|
|
73
|
+
const typeFilter = Filter.everything();
|
|
74
|
+
const timeFilter = Filter.updated({ after: 1700000000000 });
|
|
75
|
+
const combined = Filter.and(typeFilter, timeFilter);
|
|
76
|
+
expect(combined.ast.type).toBe('and');
|
|
77
|
+
expect((combined.ast as any).filters).toHaveLength(2);
|
|
78
|
+
expect((combined.ast as any).filters[1]).toEqual({
|
|
79
|
+
type: 'timestamp',
|
|
80
|
+
field: 'updatedAt',
|
|
81
|
+
operator: 'gte',
|
|
82
|
+
value: 1700000000000,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('timestamp filters pass the is() check', () => {
|
|
87
|
+
const f = Filter.updated({ after: Date.now() });
|
|
88
|
+
expect(Filter.is(f)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
package/src/Filter.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
// @import-as-namespace
|
|
6
|
+
|
|
5
7
|
import * as Match from 'effect/Match';
|
|
6
8
|
import * as Schema from 'effect/Schema';
|
|
7
9
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
@@ -12,11 +14,12 @@ import { assertArgument } from '@dxos/invariant';
|
|
|
12
14
|
import { DXN, ObjectId } from '@dxos/keys';
|
|
13
15
|
|
|
14
16
|
import * as internal from './internal';
|
|
17
|
+
import type * as Obj from './Obj';
|
|
15
18
|
import * as Ref from './Ref';
|
|
16
19
|
|
|
17
20
|
export interface Filter<T> {
|
|
18
21
|
// TODO(dmaretskyi): See new effect-schema approach to variance.
|
|
19
|
-
'~Filter': { value: Types.
|
|
22
|
+
'~Filter': { value: Types.Covariant<T> };
|
|
20
23
|
|
|
21
24
|
ast: QueryAST.Filter;
|
|
22
25
|
}
|
|
@@ -276,7 +279,7 @@ export const lte = <T>(value: T): Filter<T | undefined> => {
|
|
|
276
279
|
* Predicate for property to be in the provided array.
|
|
277
280
|
* @param values - Values to check against.
|
|
278
281
|
*/
|
|
279
|
-
const in$ = <T>(...values: T[]): Filter<T
|
|
282
|
+
const in$ = <T>(...values: T[]): Filter<T> => {
|
|
280
283
|
return new FilterClass({
|
|
281
284
|
type: 'in',
|
|
282
285
|
values,
|
|
@@ -300,7 +303,7 @@ export const contains = <T>(value: T): Filter<readonly T[] | undefined> => {
|
|
|
300
303
|
* @param from - Start of the range (inclusive).
|
|
301
304
|
* @param to - End of the range (exclusive).
|
|
302
305
|
*/
|
|
303
|
-
export const between = <T>(from: T, to: T): Filter<
|
|
306
|
+
export const between = <T>(from: T, to: T): Filter<T> => {
|
|
304
307
|
return new FilterClass({
|
|
305
308
|
type: 'range',
|
|
306
309
|
from,
|
|
@@ -308,6 +311,63 @@ export const between = <T>(from: T, to: T): Filter<unknown> => {
|
|
|
308
311
|
});
|
|
309
312
|
};
|
|
310
313
|
|
|
314
|
+
type TimeRange = { after?: Date | number; before?: Date | number };
|
|
315
|
+
|
|
316
|
+
const _toUnixMs = (date: Date | number): number => (typeof date === 'number' ? date : date.getTime());
|
|
317
|
+
|
|
318
|
+
const _timeRangeFilter = (field: 'updatedAt' | 'createdAt', range: TimeRange): Any => {
|
|
319
|
+
const filters: Any[] = [];
|
|
320
|
+
if (range.after != null) {
|
|
321
|
+
filters.push(new FilterClass({ type: 'timestamp', field, operator: 'gte', value: _toUnixMs(range.after) }));
|
|
322
|
+
}
|
|
323
|
+
if (range.before != null) {
|
|
324
|
+
filters.push(new FilterClass({ type: 'timestamp', field, operator: 'lte', value: _toUnixMs(range.before) }));
|
|
325
|
+
}
|
|
326
|
+
if (filters.length === 0) {
|
|
327
|
+
return everything();
|
|
328
|
+
}
|
|
329
|
+
return filters.length === 1 ? filters[0] : and(...filters);
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Filter objects by updatedAt timestamp.
|
|
334
|
+
*/
|
|
335
|
+
export const updated = (range: TimeRange): Any => _timeRangeFilter('updatedAt', range);
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Filter objects by createdAt timestamp.
|
|
339
|
+
*/
|
|
340
|
+
export const created = (range: TimeRange): Any => _timeRangeFilter('createdAt', range);
|
|
341
|
+
|
|
342
|
+
export type ChildOfOptions = {
|
|
343
|
+
/** Whether to match transitively (grandchildren, etc.). Defaults to true. */
|
|
344
|
+
transitive?: boolean;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Filter objects that are children of the specified parent(s).
|
|
349
|
+
* Accepts ECHO objects, Refs, or arrays of either.
|
|
350
|
+
* Refs are resolved to DXNs without loading; objects use {@link Obj.getDXN}.
|
|
351
|
+
* With transitive=true (default), also matches grandchildren and beyond.
|
|
352
|
+
*/
|
|
353
|
+
export const childOf = (
|
|
354
|
+
parents: Obj.Unknown | Ref.Unknown | readonly (Obj.Unknown | Ref.Unknown)[],
|
|
355
|
+
options?: ChildOfOptions,
|
|
356
|
+
): Any => {
|
|
357
|
+
const items = Array.isArray(parents) ? parents : [parents];
|
|
358
|
+
const dxns = items.map((item) => {
|
|
359
|
+
if (Ref.isRef(item)) {
|
|
360
|
+
return item.dxn.toString();
|
|
361
|
+
}
|
|
362
|
+
return internal.getDXN(item).toString();
|
|
363
|
+
});
|
|
364
|
+
return new FilterClass({
|
|
365
|
+
type: 'child-of',
|
|
366
|
+
parents: dxns,
|
|
367
|
+
transitive: options?.transitive ?? true,
|
|
368
|
+
});
|
|
369
|
+
};
|
|
370
|
+
|
|
311
371
|
/**
|
|
312
372
|
* Negate the filter.
|
|
313
373
|
*/
|
|
@@ -387,3 +447,8 @@ const processPredicate = (predicate: any): QueryAST.Filter => {
|
|
|
387
447
|
Match.orElse((value) => eq(value).ast),
|
|
388
448
|
);
|
|
389
449
|
};
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Returns a human-readable string representation of a Filter AST.
|
|
453
|
+
*/
|
|
454
|
+
export const pretty = (filter: Any): string => internal.prettyFilter(filter.ast);
|
package/src/Format.ts
CHANGED
package/src/Hypergraph.ts
CHANGED
|
@@ -43,9 +43,8 @@ export interface RefResolverOptions {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
46
|
+
* Manages cross-space database interactions.
|
|
47
47
|
*/
|
|
48
|
-
// TODO(burdon): Comment required.
|
|
49
48
|
export interface Hypergraph extends Database.Queryable {
|
|
50
49
|
get schemaRegistry(): SchemaRegistry.SchemaRegistry;
|
|
51
50
|
|
|
@@ -71,4 +70,10 @@ export interface Hypergraph extends Database.Queryable {
|
|
|
71
70
|
*/
|
|
72
71
|
// TODO(dmaretskyi): Restructure API: Remove middleware.
|
|
73
72
|
createRefResolver(options: RefResolverOptions): Ref.Resolver;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get a database by space ID.
|
|
76
|
+
* @returns The database for the given space ID, or undefined if not found.
|
|
77
|
+
*/
|
|
78
|
+
getDatabase(spaceId: Key.SpaceId): Database.Database | undefined;
|
|
74
79
|
}
|