@dxos/echo 0.9.1-main.c7dcc2e112 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/neutral/Annotation.mjs +22 -8
- package/dist/lib/neutral/Database.mjs +3 -3
- package/dist/lib/neutral/Entity.mjs +11 -11
- package/dist/lib/neutral/Err.mjs +7 -3
- package/dist/lib/neutral/Feed.mjs +15 -19
- package/dist/lib/neutral/Filter.mjs +13 -11
- package/dist/lib/neutral/Format.mjs +3 -7
- package/dist/lib/neutral/JsonSchema.mjs +7 -7
- package/dist/lib/neutral/Migration.mjs +11 -11
- package/dist/lib/neutral/Obj.mjs +15 -13
- package/dist/lib/neutral/Order.mjs +1 -1
- package/dist/lib/neutral/Query.mjs +17 -17
- package/dist/lib/neutral/QueryResult.mjs +1 -1
- package/dist/lib/neutral/Ref.mjs +6 -6
- package/dist/lib/neutral/Registry.mjs +1 -1
- package/dist/lib/neutral/Relation.mjs +12 -12
- package/dist/lib/neutral/Tag.mjs +15 -15
- package/dist/lib/neutral/Text.mjs +25 -0
- package/dist/lib/neutral/Text.mjs.map +7 -0
- package/dist/lib/neutral/Type.mjs +10 -10
- package/dist/lib/neutral/chunk-2HKGAQM4.mjs +1394 -0
- package/dist/lib/neutral/chunk-2HKGAQM4.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-O6BH7EPN.mjs → chunk-2ZHECXUR.mjs} +5 -4
- package/dist/lib/neutral/chunk-2ZHECXUR.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-AFANXSGV.mjs → chunk-3KTE2Y7Q.mjs} +20 -20
- package/dist/lib/neutral/chunk-3KTE2Y7Q.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WZ32BF53.mjs → chunk-3TN2VMI4.mjs} +49 -37
- package/dist/lib/neutral/chunk-3TN2VMI4.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-E7IOTOZD.mjs → chunk-42L4HJ3Z.mjs} +11 -15
- package/dist/lib/neutral/chunk-42L4HJ3Z.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-K3S7D5PR.mjs → chunk-4A2NWKRJ.mjs} +5 -5
- package/dist/lib/neutral/chunk-ACFAOTKJ.mjs +1531 -0
- package/dist/lib/neutral/chunk-ACFAOTKJ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-Z3WMRRAZ.mjs → chunk-BEFR7LEA.mjs} +11 -9
- package/dist/lib/neutral/{chunk-Z3WMRRAZ.mjs.map → chunk-BEFR7LEA.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-6M2Z6WBH.mjs → chunk-BXIKXT7Q.mjs} +2 -6
- package/dist/lib/neutral/{chunk-6M2Z6WBH.mjs.map → chunk-BXIKXT7Q.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-3JXQUMUI.mjs → chunk-C57XMMBY.mjs} +21 -20
- package/dist/lib/neutral/chunk-C57XMMBY.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-JZ6LFQU5.mjs → chunk-C62JYFAD.mjs} +82 -8
- package/dist/lib/neutral/chunk-C62JYFAD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TF5BSLF6.mjs → chunk-FSGX2R62.mjs} +3 -3
- package/dist/lib/neutral/chunk-FSGX2R62.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-6CEISA3V.mjs → chunk-HBXT3GSB.mjs} +29 -15
- package/dist/lib/neutral/chunk-HBXT3GSB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WU3GIANS.mjs → chunk-IQR45HAD.mjs} +1 -1
- package/dist/lib/neutral/chunk-IQR45HAD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TFEWTY5A.mjs → chunk-KCBW4BR6.mjs} +4 -8
- package/dist/lib/neutral/chunk-KCBW4BR6.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-4TPQZPLY.mjs → chunk-L3E5IXAE.mjs} +198 -30
- package/dist/lib/neutral/chunk-L3E5IXAE.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-EVK6XBXO.mjs → chunk-PRC4FEKJ.mjs} +2 -2
- package/dist/lib/neutral/chunk-PRC4FEKJ.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-NOL7O3BL.mjs → chunk-SCT6FFCR.mjs} +9 -4
- package/dist/lib/neutral/chunk-SCT6FFCR.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-BBFJWWAV.mjs → chunk-TOCVVFK2.mjs} +26 -2
- package/dist/lib/neutral/chunk-TOCVVFK2.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-A53NTBHE.mjs → chunk-U53LSQQA.mjs} +3 -3
- package/dist/lib/neutral/{chunk-A53NTBHE.mjs.map → chunk-U53LSQQA.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-PLDMJJJC.mjs → chunk-UGFFV2FR.mjs} +2 -2
- package/dist/lib/neutral/{chunk-35INCYOE.mjs → chunk-UWLP4RFM.mjs} +1 -1
- package/dist/lib/neutral/chunk-UWLP4RFM.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-SZ5WB6HF.mjs → chunk-UZHCQ6NI.mjs} +13 -11
- package/dist/lib/neutral/{chunk-SZ5WB6HF.mjs.map → chunk-UZHCQ6NI.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-L3OBWBV2.mjs → chunk-WKIT2YY5.mjs} +2 -2
- package/dist/lib/neutral/{chunk-HGWQR5KH.mjs → chunk-XB6ISRAO.mjs} +27 -15
- package/dist/lib/neutral/chunk-XB6ISRAO.mjs.map +7 -0
- package/dist/lib/neutral/chunk-XXL42WCB.mjs +84 -0
- package/dist/lib/neutral/chunk-XXL42WCB.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-5GAIWRQB.mjs → chunk-XXWK4J53.mjs} +27 -42
- package/dist/lib/neutral/chunk-XXWK4J53.mjs.map +7 -0
- package/dist/lib/neutral/index.mjs +30 -26
- package/dist/lib/neutral/internal/index.mjs +91 -69
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +79 -60
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/types/src/Annotation.d.ts +35 -1
- package/dist/types/src/Annotation.d.ts.map +1 -1
- package/dist/types/src/Collection.d.ts +9 -8
- package/dist/types/src/Collection.d.ts.map +1 -1
- package/dist/types/src/Database.d.ts +16 -0
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +1 -16
- package/dist/types/src/Dataset.d.ts.map +1 -1
- package/dist/types/src/Err.d.ts +67 -0
- package/dist/types/src/Err.d.ts.map +1 -1
- package/dist/types/src/Feed.d.ts +56 -80
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts +9 -1
- package/dist/types/src/Filter.d.ts.map +1 -1
- package/dist/types/src/Hypergraph.d.ts +2 -9
- package/dist/types/src/Hypergraph.d.ts.map +1 -1
- package/dist/types/src/Migration.d.ts +1 -1
- package/dist/types/src/Migration.d.ts.map +1 -1
- package/dist/types/src/Obj.d.ts +31 -6
- package/dist/types/src/Obj.d.ts.map +1 -1
- package/dist/types/src/Order.d.ts +1 -1
- package/dist/types/src/Order.d.ts.map +1 -1
- package/dist/types/src/Query.d.ts +1 -1
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/QueryResult.d.ts +2 -2
- package/dist/types/src/QueryResult.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +8 -4
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Registry.d.ts +1 -1
- package/dist/types/src/Relation.d.ts.map +1 -1
- package/dist/types/src/Tag.d.ts +11 -13
- package/dist/types/src/Tag.d.ts.map +1 -1
- package/dist/types/src/Text.d.ts +41 -0
- package/dist/types/src/Text.d.ts.map +1 -0
- package/dist/types/src/Text.test.d.ts +2 -0
- package/dist/types/src/Text.test.d.ts.map +1 -0
- package/dist/types/src/Type.d.ts +33 -20
- package/dist/types/src/Type.d.ts.map +1 -1
- package/dist/types/src/View.d.ts +8 -9
- package/dist/types/src/View.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/annotations.d.ts +9 -0
- package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/atoms.d.ts +14 -0
- package/dist/types/src/internal/Annotation/atoms.d.ts.map +1 -0
- package/dist/types/src/internal/Annotation/entity-dictionary.d.ts +13 -0
- package/dist/types/src/internal/Annotation/entity-dictionary.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/guard.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/model.d.ts +1 -1
- package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/object.d.ts +5 -1
- package/dist/types/src/internal/Entity/object.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/relation.d.ts +7 -0
- package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/type-uri.d.ts.map +1 -1
- package/dist/types/src/internal/Filter/index.d.ts +2 -0
- package/dist/types/src/internal/Filter/index.d.ts.map +1 -0
- package/dist/types/src/internal/Filter/match.d.ts +22 -0
- package/dist/types/src/internal/Filter/match.d.ts.map +1 -0
- package/dist/types/src/internal/Format/format.d.ts +0 -2
- package/dist/types/src/internal/Format/format.d.ts.map +1 -1
- package/dist/types/src/internal/Format/index.d.ts +2 -2
- package/dist/types/src/internal/Format/index.d.ts.map +1 -1
- package/dist/types/src/internal/Format/string.d.ts +0 -8
- package/dist/types/src/internal/Format/string.d.ts.map +1 -1
- package/dist/types/src/internal/Format/types.d.ts +2 -1
- package/dist/types/src/internal/Format/types.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/atoms.d.ts +7 -3
- package/dist/types/src/internal/Obj/atoms.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/clone.d.ts +2 -1
- package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/create-object.d.ts +3 -4
- package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
- package/dist/types/src/internal/Query/index.d.ts +1 -0
- package/dist/types/src/internal/Query/index.d.ts.map +1 -1
- package/dist/types/src/internal/Query/query-result-effect.d.ts +9 -0
- package/dist/types/src/internal/Query/query-result-effect.d.ts.map +1 -0
- package/dist/types/src/internal/Ref/atoms.d.ts +1 -2
- package/dist/types/src/internal/Ref/atoms.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref.d.ts +13 -6
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/common/atom-snapshot.d.ts +8 -0
- package/dist/types/src/internal/common/atom-snapshot.d.ts.map +1 -0
- package/dist/types/src/internal/common/proxy/make-object.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/proxy-types.d.ts +12 -0
- package/dist/types/src/internal/common/proxy/proxy-types.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/proxy-utils.d.ts +25 -0
- package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/schema-validator.d.ts +5 -0
- package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts +17 -0
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/entity.d.ts +4 -4
- package/dist/types/src/internal/common/types/entity.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/meta.d.ts +2 -4
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
- package/dist/types/src/internal/index.d.ts +1 -0
- package/dist/types/src/internal/index.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +42 -171
- package/dist/types/src/testing/test-schema.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -13
- package/src/Annotation.test.ts +257 -10
- package/src/Annotation.ts +55 -6
- package/src/Collection.ts +10 -12
- package/src/Database.ts +22 -20
- package/src/Err.ts +22 -0
- package/src/Feed.ts +114 -141
- package/src/Filter.test.ts +38 -0
- package/src/Filter.ts +17 -3
- package/src/Hypergraph.ts +2 -11
- package/src/Migration.ts +1 -1
- package/src/Obj.test.ts +92 -12
- package/src/Obj.ts +36 -5
- package/src/Order.ts +3 -3
- package/src/Query.test.ts +2 -2
- package/src/Query.ts +16 -16
- package/src/QueryResult.ts +2 -2
- package/src/Ref.ts +12 -4
- package/src/Registry.ts +1 -1
- package/src/Relation.ts +1 -1
- package/src/Tag.ts +12 -16
- package/src/Text.test.ts +186 -0
- package/src/Text.ts +116 -0
- package/src/Type.test.ts +52 -24
- package/src/Type.ts +69 -31
- package/src/View.ts +22 -30
- package/src/index.ts +1 -1
- package/src/internal/Annotation/annotations.ts +15 -2
- package/src/internal/Annotation/atoms.ts +107 -0
- package/src/internal/Annotation/entity-dictionary.ts +40 -37
- package/src/internal/Entity/api.ts +1 -1
- package/src/internal/Entity/guard.ts +2 -1
- package/src/internal/Entity/model.ts +2 -2
- package/src/internal/Entity/object.ts +14 -1
- package/src/internal/Entity/relation.ts +19 -0
- package/src/internal/Entity/type-uri.ts +3 -1
- package/src/internal/Filter/index.ts +5 -0
- package/src/internal/Filter/match.ts +284 -0
- package/src/internal/Format/format.ts +0 -2
- package/src/internal/Format/index.ts +2 -2
- package/src/internal/Format/string.ts +0 -12
- package/src/internal/Format/types.ts +4 -2
- package/src/internal/JsonSchema/json-schema.test.ts +82 -54
- package/src/internal/Obj/atoms.ts +31 -18
- package/src/internal/Obj/clone.ts +61 -20
- package/src/internal/Obj/create-object.test.ts +3 -3
- package/src/internal/Obj/create-object.ts +3 -4
- package/src/internal/Obj/inspect.ts +1 -1
- package/src/internal/Obj/json-serializer.test.ts +7 -5
- package/src/internal/Obj/json-serializer.ts +1 -1
- package/src/internal/Obj/schema-validator.test.ts +53 -0
- package/src/internal/Obj/set-value.test.ts +29 -19
- package/src/internal/Query/index.ts +1 -0
- package/src/internal/Query/query-result-effect.ts +35 -0
- package/src/internal/Ref/atoms.ts +23 -3
- package/src/internal/Ref/ref.test.ts +8 -8
- package/src/internal/Ref/ref.ts +26 -20
- package/src/internal/common/atom-snapshot.ts +19 -0
- package/src/internal/common/proxy/make-object.ts +1 -1
- package/src/internal/common/proxy/proxy-types.ts +20 -0
- package/src/internal/common/proxy/proxy-utils.ts +37 -1
- package/src/internal/common/proxy/reactive-array.ts +3 -3
- package/src/internal/common/proxy/reactive.test.ts +1 -1
- package/src/internal/common/proxy/schema-validator.ts +181 -8
- package/src/internal/common/proxy/typed-handler.ts +254 -76
- package/src/internal/common/types/entity.ts +15 -7
- package/src/internal/index.ts +1 -0
- package/src/testing/test-schema.ts +75 -90
- package/dist/lib/neutral/chunk-35INCYOE.mjs.map +0 -7
- package/dist/lib/neutral/chunk-3JXQUMUI.mjs.map +0 -7
- package/dist/lib/neutral/chunk-4TPQZPLY.mjs.map +0 -7
- package/dist/lib/neutral/chunk-5GAIWRQB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-6CEISA3V.mjs.map +0 -7
- package/dist/lib/neutral/chunk-AFANXSGV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-E7IOTOZD.mjs.map +0 -7
- package/dist/lib/neutral/chunk-EVK6XBXO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-HGWQR5KH.mjs.map +0 -7
- package/dist/lib/neutral/chunk-JZ6LFQU5.mjs.map +0 -7
- package/dist/lib/neutral/chunk-NOL7O3BL.mjs.map +0 -7
- package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TF5BSLF6.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +0 -7
- package/dist/lib/neutral/chunk-VQYL2OQF.mjs +0 -2353
- package/dist/lib/neutral/chunk-VQYL2OQF.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WZ32BF53.mjs.map +0 -7
- package/dist/lib/neutral/chunk-X3NUUON4.mjs +0 -184
- package/dist/lib/neutral/chunk-X3NUUON4.mjs.map +0 -7
- package/dist/types/src/exemplars.test.d.ts +0 -2
- package/dist/types/src/exemplars.test.d.ts.map +0 -1
- package/dist/types/src/hierarchy.test.d.ts +0 -2
- package/dist/types/src/hierarchy.test.d.ts.map +0 -1
- package/src/exemplars.test.ts +0 -21
- package/src/hierarchy.test.ts +0 -33
- /package/dist/lib/neutral/{chunk-K3S7D5PR.mjs.map → chunk-4A2NWKRJ.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-PLDMJJJC.mjs.map → chunk-UGFFV2FR.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-L3OBWBV2.mjs.map → chunk-WKIT2YY5.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "ECHO API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -123,6 +123,11 @@
|
|
|
123
123
|
"types": "./dist/types/src/Tag.d.ts",
|
|
124
124
|
"default": "./dist/lib/neutral/Tag.mjs"
|
|
125
125
|
},
|
|
126
|
+
"./Text": {
|
|
127
|
+
"source": "./src/Text.ts",
|
|
128
|
+
"types": "./dist/types/src/Text.d.ts",
|
|
129
|
+
"default": "./dist/lib/neutral/Text.mjs"
|
|
130
|
+
},
|
|
126
131
|
"./Type": {
|
|
127
132
|
"source": "./src/Type.ts",
|
|
128
133
|
"types": "./dist/types/src/Type.d.ts",
|
|
@@ -135,20 +140,22 @@
|
|
|
135
140
|
],
|
|
136
141
|
"dependencies": {
|
|
137
142
|
"@effect-atom/atom": "^0.5.3",
|
|
138
|
-
"effect": "3.21.
|
|
139
|
-
"
|
|
140
|
-
"@dxos/
|
|
141
|
-
"@dxos/
|
|
142
|
-
"@dxos/
|
|
143
|
-
"@dxos/
|
|
144
|
-
"@dxos/
|
|
145
|
-
"@dxos/
|
|
146
|
-
"@dxos/
|
|
147
|
-
"@dxos/util": "0.
|
|
148
|
-
"@dxos/
|
|
143
|
+
"effect": "3.21.4",
|
|
144
|
+
"semver": "^7.7.4",
|
|
145
|
+
"@dxos/async": "0.10.0",
|
|
146
|
+
"@dxos/debug": "0.10.0",
|
|
147
|
+
"@dxos/echo-protocol": "0.10.0",
|
|
148
|
+
"@dxos/effect": "0.10.0",
|
|
149
|
+
"@dxos/errors": "0.10.0",
|
|
150
|
+
"@dxos/keys": "0.10.0",
|
|
151
|
+
"@dxos/invariant": "0.10.0",
|
|
152
|
+
"@dxos/util": "0.10.0",
|
|
153
|
+
"@dxos/log": "0.10.0",
|
|
154
|
+
"@dxos/node-std": "0.10.0"
|
|
149
155
|
},
|
|
150
156
|
"devDependencies": {
|
|
151
|
-
"@types/node": "22.10.2"
|
|
157
|
+
"@types/node": "22.10.2",
|
|
158
|
+
"@types/semver": "^7.7.1"
|
|
152
159
|
},
|
|
153
160
|
"publishConfig": {
|
|
154
161
|
"access": "public"
|
package/src/Annotation.test.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Copyright 2026 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
+
import * as Registry from '@effect-atom/atom/Registry';
|
|
5
6
|
import * as Option from 'effect/Option';
|
|
6
7
|
import * as Schema from 'effect/Schema';
|
|
7
8
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
@@ -11,6 +12,7 @@ import { DXN } from '@dxos/keys';
|
|
|
11
12
|
|
|
12
13
|
import * as Annotation from './Annotation';
|
|
13
14
|
import * as Obj from './Obj';
|
|
15
|
+
import * as Ref from './Ref';
|
|
14
16
|
import * as Type from './Type';
|
|
15
17
|
|
|
16
18
|
describe('Annotation', () => {
|
|
@@ -347,11 +349,11 @@ describe('Annotation', () => {
|
|
|
347
349
|
schema: Schema.String,
|
|
348
350
|
});
|
|
349
351
|
|
|
350
|
-
const TaggedPerson =
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
.pipe(ColorAnnotation.set('teal'))
|
|
354
|
-
|
|
352
|
+
const TaggedPerson = Type.makeObject(DXN.make('com.example.type.taggedperson', '0.1.0'))(
|
|
353
|
+
Schema.Struct({
|
|
354
|
+
name: Schema.String,
|
|
355
|
+
}).pipe(ColorAnnotation.set('teal')),
|
|
356
|
+
);
|
|
355
357
|
|
|
356
358
|
const schema = Type.getSchema(TaggedPerson);
|
|
357
359
|
const result = ColorAnnotation.get(schema);
|
|
@@ -366,11 +368,11 @@ describe('Annotation', () => {
|
|
|
366
368
|
id: 'org.dxos.annotation.color',
|
|
367
369
|
schema: Schema.String,
|
|
368
370
|
});
|
|
369
|
-
const Person =
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
.pipe(ColorAnnotation.set('schema-teal'))
|
|
373
|
-
|
|
371
|
+
const Person = Type.makeObject(DXN.make('com.example.type.taggedperson', '0.1.0'))(
|
|
372
|
+
Schema.Struct({
|
|
373
|
+
name: Schema.String,
|
|
374
|
+
}).pipe(ColorAnnotation.set('schema-teal')),
|
|
375
|
+
);
|
|
374
376
|
|
|
375
377
|
test('set and get on Obj.make instance', ({ expect }) => {
|
|
376
378
|
const person = Obj.make(Person, { name: 'Alice' });
|
|
@@ -436,4 +438,249 @@ describe('Annotation', () => {
|
|
|
436
438
|
expect(Option.getOrThrow(Annotation.get(snapshot, ColorAnnotation))).toBe('snapshot-color');
|
|
437
439
|
});
|
|
438
440
|
});
|
|
441
|
+
|
|
442
|
+
describe('atom', () => {
|
|
443
|
+
// Record-valued annotation mirroring a per-key ordering (e.g. SectionOrderAnnotation).
|
|
444
|
+
const OrderAnnotation = Annotation.make({
|
|
445
|
+
id: 'org.dxos.test.order',
|
|
446
|
+
schema: Schema.Record({ key: Schema.String, value: Schema.Array(Schema.String) }),
|
|
447
|
+
});
|
|
448
|
+
const Container = Type.makeObject(DXN.make('com.example.type.container', '0.1.0'))(
|
|
449
|
+
Schema.Struct({ name: Schema.String }),
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
const setOrder = (obj: Obj.Unknown, order: Record<string, string[]>) =>
|
|
453
|
+
Obj.update(obj, (obj) => {
|
|
454
|
+
Annotation.set(obj, OrderAnnotation, order);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test('atomProperty reads the typed slice for a key', ({ expect }) => {
|
|
458
|
+
const registry = Registry.make();
|
|
459
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
460
|
+
setOrder(obj, { typeA: ['x', 'y'], typeB: ['m'] });
|
|
461
|
+
|
|
462
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
463
|
+
expect(registry.get(atomA)).toEqual(['x', 'y']);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test('atomProperty returns undefined for a missing key or annotation', ({ expect }) => {
|
|
467
|
+
const registry = Registry.make();
|
|
468
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
469
|
+
|
|
470
|
+
const missingAnnotation = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
471
|
+
expect(registry.get(missingAnnotation)).toBeUndefined();
|
|
472
|
+
|
|
473
|
+
setOrder(obj, { typeA: ['x'] });
|
|
474
|
+
const missingKey = Annotation.atomProperty(obj, OrderAnnotation, 'typeZ');
|
|
475
|
+
expect(registry.get(missingKey)).toBeUndefined();
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test('atomProperty updates when its own key changes', ({ expect }) => {
|
|
479
|
+
const registry = Registry.make();
|
|
480
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
481
|
+
setOrder(obj, { typeA: ['x', 'y'] });
|
|
482
|
+
|
|
483
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
484
|
+
let fires = 0;
|
|
485
|
+
registry.subscribe(atomA, () => {
|
|
486
|
+
fires++;
|
|
487
|
+
});
|
|
488
|
+
expect(registry.get(atomA)).toEqual(['x', 'y']);
|
|
489
|
+
|
|
490
|
+
setOrder(obj, { typeA: ['y', 'x'] });
|
|
491
|
+
expect(registry.get(atomA)).toEqual(['y', 'x']);
|
|
492
|
+
expect(fires).toBeGreaterThan(0);
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
test('atomProperty reflects only its own key', ({ expect }) => {
|
|
496
|
+
const registry = Registry.make();
|
|
497
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
498
|
+
setOrder(obj, { typeA: ['x', 'y'], typeB: ['m'] });
|
|
499
|
+
|
|
500
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
501
|
+
expect(registry.get(atomA)).toEqual(['x', 'y']);
|
|
502
|
+
|
|
503
|
+
// Changing a different key leaves typeA's value content unchanged.
|
|
504
|
+
setOrder(obj, { typeA: ['x', 'y'], typeB: ['m', 'n'] });
|
|
505
|
+
expect(registry.get(atomA)).toEqual(['x', 'y']);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
test('atom exposes the whole annotation value as an Option', ({ expect }) => {
|
|
509
|
+
const registry = Registry.make();
|
|
510
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
511
|
+
|
|
512
|
+
const wholeAtom = Annotation.atom(obj, OrderAnnotation);
|
|
513
|
+
expect(Option.isNone(registry.get(wholeAtom))).toBe(true);
|
|
514
|
+
|
|
515
|
+
setOrder(obj, { typeA: ['x'] });
|
|
516
|
+
expect(Option.getOrThrow(registry.get(wholeAtom))).toEqual({ typeA: ['x'] });
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
describe('reactive in-place mutation', () => {
|
|
521
|
+
const OrderAnnotation = Annotation.make({
|
|
522
|
+
id: 'org.dxos.test.mutable-order',
|
|
523
|
+
schema: Schema.Record({ key: Schema.String, value: Schema.Array(Schema.String) }),
|
|
524
|
+
});
|
|
525
|
+
const RefOrderAnnotation = Annotation.make({
|
|
526
|
+
id: 'org.dxos.test.mutable-ref-order',
|
|
527
|
+
schema: Schema.Record({ key: Schema.String, value: Schema.Array(Ref.Ref(Obj.Unknown)) }),
|
|
528
|
+
});
|
|
529
|
+
const Item = Type.makeObject(DXN.make('com.example.type.mutableItem', '0.1.0'))(
|
|
530
|
+
Schema.Struct({ name: Schema.String }),
|
|
531
|
+
);
|
|
532
|
+
const Container = Type.makeObject(DXN.make('com.example.type.mutableContainer', '0.1.0'))(
|
|
533
|
+
Schema.Struct({ name: Schema.String }),
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
test('push to an annotation array in place without Annotation.set', ({ expect }) => {
|
|
537
|
+
const registry = Registry.make();
|
|
538
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
539
|
+
Obj.update(obj, (obj) => Annotation.set(obj, OrderAnnotation, { typeA: ['x', 'y'] }));
|
|
540
|
+
|
|
541
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
542
|
+
expect(registry.get(atomA)).toEqual(['x', 'y']);
|
|
543
|
+
|
|
544
|
+
Annotation.update(obj, OrderAnnotation, (order) => {
|
|
545
|
+
order.typeA.push('z');
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
expect(registry.get(atomA)).toEqual(['x', 'y', 'z']);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
test('splice an annotation array in place reorders the value', ({ expect }) => {
|
|
552
|
+
const registry = Registry.make();
|
|
553
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
554
|
+
Obj.update(obj, (obj) => Annotation.set(obj, OrderAnnotation, { typeA: ['x', 'y', 'z'] }));
|
|
555
|
+
|
|
556
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
557
|
+
|
|
558
|
+
Annotation.update(obj, OrderAnnotation, (order) => {
|
|
559
|
+
order.typeA.splice(0, order.typeA.length, 'z', 'x', 'y');
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
expect(registry.get(atomA)).toEqual(['z', 'x', 'y']);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
test('in-place mutation of one key leaves other keys untouched', ({ expect }) => {
|
|
566
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
567
|
+
Obj.update(obj, (obj) => Annotation.set(obj, OrderAnnotation, { typeA: ['x'], typeB: ['m'] }));
|
|
568
|
+
|
|
569
|
+
Annotation.update(obj, OrderAnnotation, (order) => {
|
|
570
|
+
order.typeA.push('y');
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
expect(Option.getOrThrow(Annotation.get(obj, OrderAnnotation))).toEqual({ typeA: ['x', 'y'], typeB: ['m'] });
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
test('push a Ref to an annotation array in place', ({ expect }) => {
|
|
577
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
578
|
+
const a = Obj.make(Item, { name: 'a' });
|
|
579
|
+
const b = Obj.make(Item, { name: 'b' });
|
|
580
|
+
Obj.update(obj, (obj) => Annotation.set(obj, RefOrderAnnotation, { typeA: [Ref.make(a)] }));
|
|
581
|
+
|
|
582
|
+
Annotation.update(obj, RefOrderAnnotation, (order) => {
|
|
583
|
+
order.typeA.push(Ref.make(b));
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
const result = Annotation.get(obj, RefOrderAnnotation).pipe(Option.getOrThrow);
|
|
587
|
+
expect(result.typeA.map((ref) => ref.target?.id)).toEqual([a.id, b.id]);
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
test('atomProperty notifies subscribers when a Ref array is reordered in place', ({ expect }) => {
|
|
591
|
+
const registry = Registry.make();
|
|
592
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
593
|
+
const a = Obj.make(Item, { name: 'a' });
|
|
594
|
+
const b = Obj.make(Item, { name: 'b' });
|
|
595
|
+
const c = Obj.make(Item, { name: 'c' });
|
|
596
|
+
Obj.update(obj, (obj) =>
|
|
597
|
+
Annotation.set(obj, RefOrderAnnotation, { typeA: [Ref.make(a), Ref.make(b), Ref.make(c)] }),
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
const atomA = Annotation.atomProperty(obj, RefOrderAnnotation, 'typeA');
|
|
601
|
+
let fires = 0;
|
|
602
|
+
registry.subscribe(atomA, () => {
|
|
603
|
+
fires++;
|
|
604
|
+
});
|
|
605
|
+
registry.get(atomA);
|
|
606
|
+
|
|
607
|
+
Annotation.update(obj, RefOrderAnnotation, (order) => {
|
|
608
|
+
order.typeA.splice(0, order.typeA.length, Ref.make(c), Ref.make(a), Ref.make(b));
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
expect(fires).toBeGreaterThan(0);
|
|
612
|
+
// The atom emits a shallow snapshot of the ref array (refs kept intact).
|
|
613
|
+
expect(registry.get(atomA)?.map((ref) => ref.target?.id)).toEqual([c.id, a.id, b.id]);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
test('reorder snapshot does not touch ref targets (tolerates cyclic targets)', ({ expect }) => {
|
|
617
|
+
const registry = Registry.make();
|
|
618
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
619
|
+
const a = Obj.make(Item, { name: 'a' });
|
|
620
|
+
// The annotation on `obj` holds a ref back to `obj`, so a loaded target forms a cycle —
|
|
621
|
+
// the shallow snapshot copies the array without dereferencing its ref elements, so it tolerates this.
|
|
622
|
+
Obj.update(obj, (obj) => Annotation.set(obj, RefOrderAnnotation, { typeA: [Ref.make(a), Ref.make(obj)] }));
|
|
623
|
+
|
|
624
|
+
const atomA = Annotation.atomProperty(obj, RefOrderAnnotation, 'typeA');
|
|
625
|
+
let fires = 0;
|
|
626
|
+
registry.subscribe(atomA, () => {
|
|
627
|
+
fires++;
|
|
628
|
+
});
|
|
629
|
+
registry.get(atomA);
|
|
630
|
+
|
|
631
|
+
Annotation.update(obj, RefOrderAnnotation, (order) => {
|
|
632
|
+
order.typeA.splice(0, order.typeA.length, Ref.make(obj), Ref.make(a));
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
expect(fires).toBeGreaterThan(0);
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
test('Annotation.update mutates in place (wraps its own change)', ({ expect }) => {
|
|
639
|
+
const registry = Registry.make();
|
|
640
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
641
|
+
Obj.update(obj, (obj) => Annotation.set(obj, OrderAnnotation, { typeA: ['x', 'y'] }));
|
|
642
|
+
|
|
643
|
+
const atomA = Annotation.atomProperty(obj, OrderAnnotation, 'typeA');
|
|
644
|
+
|
|
645
|
+
// No surrounding Obj.update — Annotation.update opens its own change transaction.
|
|
646
|
+
Annotation.update(obj, OrderAnnotation, (order) => {
|
|
647
|
+
order.typeA.push('z');
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
expect(registry.get(atomA)).toEqual(['x', 'y', 'z']);
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
test('Annotation.update is a no-op when the annotation is absent', ({ expect }) => {
|
|
654
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
655
|
+
let called = false;
|
|
656
|
+
Annotation.update(obj, OrderAnnotation, () => {
|
|
657
|
+
called = true;
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
expect(called).toBe(false);
|
|
661
|
+
expect(Option.isNone(Annotation.get(obj, OrderAnnotation))).toBe(true);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
test('Annotation.update validates the mutated value against the annotation schema', ({ expect }) => {
|
|
665
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
666
|
+
Obj.update(obj, (obj) => Annotation.set(obj, OrderAnnotation, { typeA: ['x'] }));
|
|
667
|
+
|
|
668
|
+
expect(() =>
|
|
669
|
+
Annotation.update(obj, OrderAnnotation, (order) => {
|
|
670
|
+
// Pushing a number into a string array violates the annotation schema.
|
|
671
|
+
// @ts-expect-error intentional type violation to exercise runtime validation
|
|
672
|
+
order.typeA.push(42);
|
|
673
|
+
}),
|
|
674
|
+
).toThrow();
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
test('set validates the value against the annotation schema', ({ expect }) => {
|
|
678
|
+
const obj = Obj.make(Container, { name: 'A' });
|
|
679
|
+
Obj.update(obj, (obj) => {
|
|
680
|
+
// OrderAnnotation values must be string arrays; a number element violates the schema.
|
|
681
|
+
// @ts-expect-error intentional type violation to exercise runtime validation
|
|
682
|
+
expect(() => Annotation.set(obj, OrderAnnotation, { typeA: [1] })).toThrow();
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
});
|
|
439
686
|
});
|
package/src/Annotation.ts
CHANGED
|
@@ -5,23 +5,27 @@
|
|
|
5
5
|
// @import-as-namespace
|
|
6
6
|
|
|
7
7
|
export {
|
|
8
|
+
DEFAULT_LAYOUT_NAME,
|
|
8
9
|
DescriptionAnnotation,
|
|
9
10
|
FieldLookupAnnotationId,
|
|
10
|
-
|
|
11
|
+
FormCreateAnnotation,
|
|
12
|
+
FormCreateAnnotationId,
|
|
11
13
|
FormInlineAnnotation,
|
|
12
|
-
|
|
14
|
+
FormInputAnnotation,
|
|
13
15
|
FormLayoutAnnotation,
|
|
14
16
|
FormLayoutAnnotationId,
|
|
15
17
|
type FormLayoutMap,
|
|
16
|
-
|
|
18
|
+
FormOrderedAnnotation,
|
|
17
19
|
GeneratorAnnotation,
|
|
18
20
|
GeneratorAnnotationId,
|
|
19
21
|
type GeneratorAnnotationValue,
|
|
22
|
+
HiddenAnnotation,
|
|
23
|
+
IconAnnotation,
|
|
24
|
+
IconFromRefAnnotation,
|
|
20
25
|
LabelAnnotation,
|
|
21
26
|
ReferenceAnnotation,
|
|
22
27
|
ReferenceAnnotationId,
|
|
23
28
|
type ReferenceAnnotationValue,
|
|
24
|
-
HiddenAnnotation,
|
|
25
29
|
TypeAnnotation,
|
|
26
30
|
getDescriptionWithSchema,
|
|
27
31
|
getLabelWithSchema,
|
|
@@ -29,8 +33,6 @@ export {
|
|
|
29
33
|
getTypeIdentifierAnnotation,
|
|
30
34
|
setDescriptionWithSchema,
|
|
31
35
|
setLabelWithSchema,
|
|
32
|
-
IconAnnotation,
|
|
33
|
-
IconFromRefAnnotation,
|
|
34
36
|
} from './internal/Annotation';
|
|
35
37
|
|
|
36
38
|
import * as Function from 'effect/Function';
|
|
@@ -41,6 +43,7 @@ import * as Types from 'effect/Types';
|
|
|
41
43
|
|
|
42
44
|
import * as Entity from './Entity';
|
|
43
45
|
import * as internalAnnotations from './internal/Annotation';
|
|
46
|
+
import * as annotationAtoms from './internal/Annotation/atoms';
|
|
44
47
|
|
|
45
48
|
export const TypeId = '~@dxos/echo/Annotation' as const;
|
|
46
49
|
export type TypeId = typeof TypeId;
|
|
@@ -121,6 +124,11 @@ export const make: <T>(props: MakeProps<T>) => Annotation<T> = internalAnnotatio
|
|
|
121
124
|
* Get the value of an annotation from an entity instance or snapshot.
|
|
122
125
|
* For schema-level reads use the annotation instance method (e.g. `ColorAnnotation.get(schema)`).
|
|
123
126
|
* For getting an annotation value from a dictionary, use `getDictionary`.
|
|
127
|
+
*
|
|
128
|
+
* The value is read-only (schema types are readonly by default): to mutate an annotation (including
|
|
129
|
+
* in-place array splices) use `Annotation.update` or `Annotation.set`, which open a change transaction.
|
|
130
|
+
* A read-only return is sound regardless of context — the reactive proxy rejects mutation outside an
|
|
131
|
+
* `Obj.update`.
|
|
124
132
|
*/
|
|
125
133
|
export const get: {
|
|
126
134
|
<T>(annotation: Annotation<T>): (target: Entity.Unknown | Entity.Snapshot) => Option.Option<T>;
|
|
@@ -147,6 +155,18 @@ export const set: {
|
|
|
147
155
|
return internalAnnotations.set(target, annotation, value);
|
|
148
156
|
});
|
|
149
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Mutate an existing annotation value in place via a callback, wrapping the mutation in a change
|
|
160
|
+
* transaction (like `Obj.update`). The result is validated against the annotation's schema. Use when
|
|
161
|
+
* only an annotation needs to change; to mutate it alongside other changes (unvalidated), call
|
|
162
|
+
* `Annotation.get` inside an existing `Obj.update` instead. No-op when absent.
|
|
163
|
+
*/
|
|
164
|
+
export const update = <T>(
|
|
165
|
+
target: Entity.Unknown,
|
|
166
|
+
annotation: Annotation<T>,
|
|
167
|
+
mutator: (value: Entity.Mutable<T>) => void,
|
|
168
|
+
): void => internalAnnotations.update(target, annotation, mutator);
|
|
169
|
+
|
|
150
170
|
export const getFromAst: {
|
|
151
171
|
<T>(annotation: Annotation<T>): (ast: SchemaAST.AST) => Option.Option<T>;
|
|
152
172
|
<T>(ast: SchemaAST.AST, annotation: Annotation<T>): Option.Option<T>;
|
|
@@ -157,6 +177,18 @@ export const getFromAst: {
|
|
|
157
177
|
return internalAnnotations.getFromAst(ast, annotation);
|
|
158
178
|
});
|
|
159
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Reactive atom for an annotation value on an entity instance.
|
|
182
|
+
* Fires only when the annotation value changes (mirrors `Obj.atom`, scoped to one annotation).
|
|
183
|
+
*/
|
|
184
|
+
export const atom = annotationAtoms.makeAtom;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Reactive atom for a single key of a record-valued annotation on an entity instance.
|
|
188
|
+
* Reactivity is scoped to that key, and the value type is preserved (mirrors `Obj.atomProperty`).
|
|
189
|
+
*/
|
|
190
|
+
export const atomProperty = annotationAtoms.makeProperty;
|
|
191
|
+
|
|
160
192
|
/**
|
|
161
193
|
* Set of annotation values.
|
|
162
194
|
*
|
|
@@ -205,3 +237,20 @@ export const setDictionary: {
|
|
|
205
237
|
>(3, (values, annotation, value) => {
|
|
206
238
|
return internalAnnotations.setDictionary(values, annotation, value);
|
|
207
239
|
});
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Build a dictionary by mutating it in a callback.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* const dictionary = Annotation.buildDictionary((dictionary) => {
|
|
247
|
+
* Annotation.setDictionary(dictionary, ColorAnnotation, 'red');
|
|
248
|
+
* Annotation.setDictionary(dictionary, SizeAnnotation, '10px');
|
|
249
|
+
* });
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
export const buildDictionary = (build: (dictionary: Types.Mutable<Dictionary>) => void): Dictionary => {
|
|
253
|
+
const dictionary = Schema.encodeSync(Dictionary)({});
|
|
254
|
+
build(dictionary);
|
|
255
|
+
return dictionary;
|
|
256
|
+
};
|
package/src/Collection.ts
CHANGED
|
@@ -17,17 +17,15 @@ import * as Type from './Type';
|
|
|
17
17
|
/**
|
|
18
18
|
* A an ordered set of objects.
|
|
19
19
|
*/
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Annotation.IconAnnotation.set({ icon: 'ph--folder--regular', hue: '
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export type Collection = Type.InstanceType<typeof Collection>;
|
|
29
|
-
|
|
30
|
-
export const make = (props: Partial<Obj.MakeProps<typeof Collection>> = {}): Collection =>
|
|
20
|
+
export class Collection extends Type.makeObject<Collection>(DXN.make('org.dxos.type.collection', '0.1.0'))(
|
|
21
|
+
Schema.Struct({
|
|
22
|
+
name: Schema.String.pipe(Schema.optional),
|
|
23
|
+
objects: Schema.Array(Ref.Ref(Obj.Unknown)).pipe(internal.FormInputAnnotation.set(false)),
|
|
24
|
+
}).pipe(Annotation.IconAnnotation.set({ icon: 'ph--folder--regular', hue: 'indigo' })),
|
|
25
|
+
) {}
|
|
26
|
+
|
|
27
|
+
export const make = (props: Partial<Obj.MakeProps<typeof Collection>> = {}): Type.InstanceType<typeof Collection> =>
|
|
31
28
|
Obj.make(Collection, { objects: [], ...props });
|
|
32
29
|
|
|
33
|
-
export const isCollection: (value: unknown) => value is Collection =
|
|
30
|
+
export const isCollection: (value: unknown) => value is Type.InstanceType<typeof Collection> =
|
|
31
|
+
Obj.instanceOf(Collection);
|
package/src/Database.ts
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import * as Context from 'effect/Context';
|
|
8
8
|
import * as Effect from 'effect/Effect';
|
|
9
|
-
import * as Effectable from 'effect/Effectable';
|
|
10
9
|
import * as Layer from 'effect/Layer';
|
|
11
|
-
import * as Option from 'effect/Option';
|
|
12
10
|
import * as Schema from 'effect/Schema';
|
|
13
11
|
|
|
14
12
|
import { EffectEx } from '@dxos/effect';
|
|
@@ -24,6 +22,7 @@ import { type AnyProperties, EntityKind, KindId } from './internal/common/types'
|
|
|
24
22
|
// Deep import (not the `./internal/Entity` barrel) to avoid a cycle:
|
|
25
23
|
// Database → internal/Entity → entity → JsonSchema → Ref → Database.
|
|
26
24
|
import { isInstanceOf } from './internal/Entity/type-uri';
|
|
25
|
+
import * as queryInternal from './internal/Query';
|
|
27
26
|
import type { Ref } from './internal/Ref/ref';
|
|
28
27
|
import type * as Obj from './Obj';
|
|
29
28
|
import type * as Query from './Query';
|
|
@@ -185,6 +184,26 @@ export interface Database extends Queryable {
|
|
|
185
184
|
* Optionaly waits for changes to be propagated to indexes and event handlers.
|
|
186
185
|
*/
|
|
187
186
|
flush(opts?: FlushOptions): Promise<void>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Removes feed items by ID.
|
|
190
|
+
*/
|
|
191
|
+
removeFeedItemsByIds(feed: Feed.Feed, ids: string[]): Promise<void>;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Queries items in a feed associated with this database.
|
|
195
|
+
*/
|
|
196
|
+
queryFeed(feed: Feed.Feed, queryOrFilter: Query.Any | Filter.Any): QueryResult.QueryResult<any>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Syncs a feed with the server.
|
|
200
|
+
*/
|
|
201
|
+
syncFeed(feed: Feed.Feed, options?: Feed.SyncOptions): Promise<void>;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Returns queue replication backlog for the feed's namespace.
|
|
205
|
+
*/
|
|
206
|
+
getFeedSyncState(feed: Feed.Feed): Promise<Feed.SyncState>;
|
|
188
207
|
}
|
|
189
208
|
|
|
190
209
|
export const isDatabase = (obj: unknown): obj is Database => {
|
|
@@ -356,22 +375,5 @@ export const query: {
|
|
|
356
375
|
Service.pipe(
|
|
357
376
|
Effect.map(({ db }) => db.query(queryOrFilter as any) as QueryResult.QueryResult<any>),
|
|
358
377
|
Effect.withSpan('Database.query'),
|
|
359
|
-
makeQueryResultEffect,
|
|
378
|
+
queryInternal.makeQueryResultEffect,
|
|
360
379
|
);
|
|
361
|
-
|
|
362
|
-
const makeQueryResultEffect = <T>(
|
|
363
|
-
eff: Effect.Effect<QueryResult.QueryResult<T>, never, Service>,
|
|
364
|
-
): QueryResult.QueryResultEffect<T, never, Service> => {
|
|
365
|
-
return {
|
|
366
|
-
run: Effect.flatMap(eff, (result) => EffectEx.promiseWithCauseCapture(() => result.run())),
|
|
367
|
-
first: Effect.flatMap(eff, (result) =>
|
|
368
|
-
EffectEx.promiseWithCauseCapture(async () => Option.fromNullable(await result.firstOrUndefined())),
|
|
369
|
-
),
|
|
370
|
-
|
|
371
|
-
// Effect internals
|
|
372
|
-
...Effectable.CommitPrototype,
|
|
373
|
-
commit() {
|
|
374
|
-
return eff;
|
|
375
|
-
},
|
|
376
|
-
} as any;
|
|
377
|
-
};
|
package/src/Err.ts
CHANGED
|
@@ -19,6 +19,28 @@ export class EntityNotFoundError extends BaseError.extend('EntityNotFoundError',
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Thrown when a `Text` mutation is attempted on an object whose reactive handler does not implement
|
|
24
|
+
* string CRDT editing (e.g. a snapshot or a non-reactive value).
|
|
25
|
+
*/
|
|
26
|
+
export class TextNotSupportedError extends BaseError.extend(
|
|
27
|
+
'TextNotSupportedError',
|
|
28
|
+
'Text operation is not supported for this object',
|
|
29
|
+
) {
|
|
30
|
+
constructor(operation: string, options?: BaseErrorOptions) {
|
|
31
|
+
super({ context: { operation }, ...options });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Thrown by `Text.apply` when a non-`replaceAll` edit's `oldString` is not found in the text.
|
|
37
|
+
*/
|
|
38
|
+
export class TextEditNotFoundError extends BaseError.extend('TextEditNotFoundError', 'Edit text not found') {
|
|
39
|
+
constructor(oldString: string, options?: BaseErrorOptions) {
|
|
40
|
+
super({ context: { oldString }, ...options });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
22
44
|
/**
|
|
23
45
|
* Reason why getting a reactive object from a snapshot failed.
|
|
24
46
|
* - `no-database`: The snapshot is not associated with a database.
|