@dxos/echo 0.8.4-main.422d1c7879 → 0.8.4-main.4f23b4e393
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/lib/neutral/Annotation.mjs +5 -3
- package/dist/lib/neutral/Database.mjs +4 -4
- package/dist/lib/neutral/Entity.mjs +14 -14
- package/dist/lib/neutral/Err.mjs +1 -1
- package/dist/lib/neutral/Extension.mjs +1 -1
- package/dist/lib/neutral/Feed.mjs +19 -17
- package/dist/lib/neutral/Filter.mjs +11 -11
- package/dist/lib/neutral/Format.mjs +3 -3
- package/dist/lib/neutral/JsonSchema.mjs +8 -8
- package/dist/lib/neutral/Key.mjs +1 -1
- package/dist/lib/neutral/Migration.mjs +10 -10
- package/dist/lib/neutral/Obj.mjs +14 -14
- 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 +9 -7
- package/dist/lib/neutral/Relation.mjs +15 -15
- package/dist/lib/neutral/SchemaRegistry.mjs +1 -1
- package/dist/lib/neutral/Tag.mjs +14 -14
- package/dist/lib/neutral/Type.mjs +10 -10
- package/dist/lib/neutral/{chunk-GZQTCRJB.mjs → chunk-44HT3MEC.mjs} +2 -2
- package/dist/lib/neutral/{chunk-4P3IXBLT.mjs → chunk-5SL5LDLD.mjs} +4 -2
- package/dist/lib/neutral/chunk-5SL5LDLD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-ANHVGJI4.mjs → chunk-7RVZT53K.mjs} +1 -1
- package/dist/lib/neutral/{chunk-A2WIDONZ.mjs → chunk-AHWSAJHU.mjs} +6 -22
- package/dist/lib/neutral/{chunk-A2WIDONZ.mjs.map → chunk-AHWSAJHU.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-XEU2Q5CI.mjs → chunk-APHSOTIX.mjs} +2 -2
- package/dist/lib/neutral/{chunk-BNCCGLJN.mjs → chunk-BICZKPQG.mjs} +1 -1
- package/dist/lib/neutral/{chunk-JPWH3QJD.mjs → chunk-BMB7IHGB.mjs} +10 -66
- package/dist/lib/neutral/{chunk-JPWH3QJD.mjs.map → chunk-BMB7IHGB.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-EJJFH3XB.mjs → chunk-C6LDQTNO.mjs} +10 -10
- package/dist/lib/neutral/chunk-C6LDQTNO.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-GMYNDEMT.mjs → chunk-GKBXQFQK.mjs} +11 -27
- package/dist/lib/neutral/{chunk-GMYNDEMT.mjs.map → chunk-GKBXQFQK.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-YS6Q3XAD.mjs → chunk-GWFFC34K.mjs} +1 -1
- package/dist/lib/neutral/{chunk-YS6Q3XAD.mjs.map → chunk-GWFFC34K.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-PHU22NLC.mjs → chunk-I2DARWPX.mjs} +4 -12
- package/dist/lib/neutral/chunk-I2DARWPX.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-RP37BQF7.mjs → chunk-KBZ4RAXR.mjs} +20 -16
- package/dist/lib/neutral/chunk-KBZ4RAXR.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-QW7YUKSA.mjs → chunk-MLS7U7AT.mjs} +12 -65
- package/dist/lib/neutral/{chunk-QW7YUKSA.mjs.map → chunk-MLS7U7AT.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-TBKX6JQO.mjs → chunk-N4B7FHQT.mjs} +1 -1
- package/dist/lib/neutral/{chunk-H5F7C2UO.mjs → chunk-N7VOEPSV.mjs} +6 -3
- package/dist/lib/neutral/{chunk-H5F7C2UO.mjs.map → chunk-N7VOEPSV.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-ZUGFUCUK.mjs → chunk-NWXJZVWD.mjs} +8 -8
- package/dist/lib/neutral/{chunk-ZUGFUCUK.mjs.map → chunk-NWXJZVWD.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-JIN4EVUK.mjs → chunk-OMJN6VCR.mjs} +4 -4
- package/dist/lib/neutral/{chunk-EULNZHTP.mjs → chunk-PHOHAIEE.mjs} +4 -4
- package/dist/lib/neutral/{chunk-7I3YIAT2.mjs → chunk-QRZ2I3ZM.mjs} +2 -2
- package/dist/lib/neutral/{chunk-6ASBHRDG.mjs → chunk-SRX3EZY3.mjs} +38 -17
- package/dist/lib/neutral/chunk-SRX3EZY3.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-WAK4DMFV.mjs → chunk-SUZMWP3Y.mjs} +2 -2
- package/dist/lib/neutral/{chunk-2KHZ36F5.mjs → chunk-TNBK56IN.mjs} +10 -21
- package/dist/lib/neutral/{chunk-2KHZ36F5.mjs.map → chunk-TNBK56IN.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-DQYLD2RB.mjs → chunk-TRPZU2HV.mjs} +2 -2
- package/dist/lib/neutral/{chunk-UI6MWK5W.mjs → chunk-TTCSATUD.mjs} +1 -1
- package/dist/lib/neutral/{chunk-OMUPQMLR.mjs → chunk-V72DY6LU.mjs} +1 -1
- package/dist/lib/neutral/{chunk-O26EPPBW.mjs → chunk-W7U2XGZ3.mjs} +11 -19
- package/dist/lib/neutral/{chunk-O26EPPBW.mjs.map → chunk-W7U2XGZ3.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-UBEZSGXY.mjs → chunk-ZISMEVKD.mjs} +1 -1
- package/dist/lib/neutral/{chunk-UBEZSGXY.mjs.map → chunk-ZISMEVKD.mjs.map} +2 -2
- package/dist/lib/neutral/{chunk-BQN7EDPH.mjs → chunk-ZVQ26DCR.mjs} +76 -478
- package/dist/lib/neutral/{chunk-BQN7EDPH.mjs.map → chunk-ZVQ26DCR.mjs.map} +3 -3
- package/dist/lib/neutral/index.mjs +28 -28
- package/dist/lib/neutral/internal/index.mjs +11 -9
- package/dist/lib/neutral/meta.json +1 -1
- package/dist/lib/neutral/testing/index.mjs +183 -129
- package/dist/lib/neutral/testing/index.mjs.map +3 -3
- package/dist/types/src/Annotation.d.ts +1 -1
- 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 +1 -1
- package/dist/types/src/Database.d.ts.map +1 -1
- package/dist/types/src/Dataset.d.ts +1 -1
- package/dist/types/src/Entity.d.ts +9 -9
- 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 +4 -4
- package/dist/types/src/Extension.d.ts.map +1 -1
- package/dist/types/src/Feed.d.ts +37 -13
- package/dist/types/src/Feed.d.ts.map +1 -1
- package/dist/types/src/Filter.d.ts.map +1 -1
- package/dist/types/src/Hypergraph.d.ts +3 -3
- package/dist/types/src/Hypergraph.d.ts.map +1 -1
- package/dist/types/src/Json.d.ts.map +1 -1
- package/dist/types/src/JsonSchema.d.ts +1 -1
- package/dist/types/src/Migration.d.ts.map +1 -1
- package/dist/types/src/Obj.d.ts +19 -19
- 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 +5 -1
- package/dist/types/src/Query.d.ts.map +1 -1
- package/dist/types/src/Ref.d.ts +1 -0
- package/dist/types/src/Ref.d.ts.map +1 -1
- package/dist/types/src/Relation.d.ts +15 -15
- package/dist/types/src/Relation.d.ts.map +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.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/internal/Annotation/annotations.d.ts +11 -2
- package/dist/types/src/internal/Annotation/annotations.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/sorting.d.ts.map +1 -1
- package/dist/types/src/internal/Annotation/util.d.ts +1 -1
- package/dist/types/src/internal/Annotation/util.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/api.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/relation.d.ts.map +1 -1
- package/dist/types/src/internal/Entity/version.d.ts.map +1 -1
- package/dist/types/src/internal/Format/date.d.ts.map +1 -1
- package/dist/types/src/internal/Format/format.d.ts.map +1 -1
- package/dist/types/src/internal/Format/number.d.ts.map +1 -1
- package/dist/types/src/internal/Format/object.d.ts.map +1 -1
- package/dist/types/src/internal/Format/types.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema-normalize.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts +28 -28
- package/dist/types/src/internal/JsonSchema/json-schema-type.d.ts.map +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts +1 -1
- package/dist/types/src/internal/JsonSchema/json-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/clone.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/common.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/create-object.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/deleted.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/ids.d.ts +1 -1
- package/dist/types/src/internal/Obj/ids.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/json-serializer.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/set-value.d.ts +1 -1
- package/dist/types/src/internal/Obj/set-value.d.ts.map +1 -1
- package/dist/types/src/internal/Obj/snapshot.d.ts.map +1 -1
- package/dist/types/src/internal/Query.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Type/compose.d.ts.map +1 -1
- package/dist/types/src/internal/Type/echo-schema.d.ts +1 -1
- package/dist/types/src/internal/Type/echo-schema.d.ts.map +1 -1
- package/dist/types/src/internal/Type/manipulation.d.ts.map +1 -1
- package/dist/types/src/internal/common/api/meta.d.ts +3 -3
- package/dist/types/src/internal/common/api/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/change-context.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/change-context.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/define-hidden-property.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/errors.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/errors.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/event-batch.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/json-serializer.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/ownership.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/proxy-utils.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/reactive-array.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/reactive.d.ts +1 -1
- package/dist/types/src/internal/common/proxy/reactive.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/schema-validator.d.ts.map +1 -1
- package/dist/types/src/internal/common/proxy/typed-handler.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/base.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/entity.d.ts +3 -3
- package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
- package/dist/types/src/internal/common/types/version.d.ts +1 -1
- package/dist/types/src/testing/test-data.d.ts +8 -8
- package/dist/types/src/testing/test-data.d.ts.map +1 -1
- package/dist/types/src/testing/test-schema.d.ts +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 +13 -13
- package/src/Annotation.ts +1 -0
- package/src/Collection.ts +1 -1
- package/src/Database.ts +1 -1
- package/src/Entity.ts +9 -9
- package/src/Extension.ts +3 -3
- package/src/Feed.ts +55 -24
- package/src/Hypergraph.ts +3 -3
- package/src/Obj.test.ts +12 -12
- package/src/Obj.ts +19 -19
- package/src/Query.test.ts +32 -16
- package/src/Query.ts +32 -7
- package/src/Ref.ts +2 -0
- package/src/Relation.ts +15 -15
- package/src/exemplars.test.ts +21 -0
- package/src/internal/Annotation/annotations.ts +16 -3
- package/src/internal/Obj/ids.ts +1 -1
- package/src/internal/Obj/json-serializer.test.ts +1 -1
- package/src/internal/Obj/json-serializer.ts +9 -9
- package/src/internal/Obj/set-value.test.ts +15 -15
- package/src/internal/Obj/set-value.ts +1 -1
- package/src/internal/Query.ts +7 -4
- package/src/internal/Type/echo-schema.ts +1 -1
- package/src/internal/common/README.md +1 -1
- package/src/internal/common/api/meta.ts +3 -3
- package/src/internal/common/proxy/change-context.ts +1 -1
- package/src/internal/common/proxy/change.test.ts +59 -59
- package/src/internal/common/proxy/errors.ts +2 -2
- package/src/internal/common/proxy/reactive-array.ts +1 -1
- package/src/internal/common/proxy/reactive.test.ts +3 -3
- package/src/internal/common/proxy/reactive.ts +1 -1
- package/src/internal/common/proxy/typed-handler.ts +7 -7
- package/src/internal/common/proxy/typed-object.test.ts +1 -1
- package/src/testing/test-data.ts +157 -97
- package/dist/lib/neutral/chunk-4P3IXBLT.mjs.map +0 -7
- package/dist/lib/neutral/chunk-6ASBHRDG.mjs.map +0 -7
- package/dist/lib/neutral/chunk-EJJFH3XB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-PHU22NLC.mjs.map +0 -7
- package/dist/lib/neutral/chunk-RP37BQF7.mjs.map +0 -7
- /package/dist/lib/neutral/{chunk-GZQTCRJB.mjs.map → chunk-44HT3MEC.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-ANHVGJI4.mjs.map → chunk-7RVZT53K.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-XEU2Q5CI.mjs.map → chunk-APHSOTIX.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-BNCCGLJN.mjs.map → chunk-BICZKPQG.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-TBKX6JQO.mjs.map → chunk-N4B7FHQT.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-JIN4EVUK.mjs.map → chunk-OMJN6VCR.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-EULNZHTP.mjs.map → chunk-PHOHAIEE.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-7I3YIAT2.mjs.map → chunk-QRZ2I3ZM.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-WAK4DMFV.mjs.map → chunk-SUZMWP3Y.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-DQYLD2RB.mjs.map → chunk-TRPZU2HV.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-UI6MWK5W.mjs.map → chunk-TTCSATUD.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-OMUPQMLR.mjs.map → chunk-V72DY6LU.mjs.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/echo",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.4f23b4e393",
|
|
4
4
|
"description": "ECHO API",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -135,18 +135,18 @@
|
|
|
135
135
|
],
|
|
136
136
|
"dependencies": {
|
|
137
137
|
"effect": "3.20.0",
|
|
138
|
-
"@dxos/
|
|
139
|
-
"@dxos/
|
|
140
|
-
"@dxos/debug": "0.8.4-main.
|
|
141
|
-
"@dxos/echo-protocol": "0.8.4-main.
|
|
142
|
-
"@dxos/effect": "0.8.4-main.
|
|
143
|
-
"@dxos/
|
|
144
|
-
"@dxos/
|
|
145
|
-
"@dxos/
|
|
146
|
-
"@dxos/
|
|
147
|
-
"@dxos/node-std": "0.8.4-main.
|
|
148
|
-
"@dxos/
|
|
149
|
-
"@dxos/
|
|
138
|
+
"@dxos/context": "0.8.4-main.4f23b4e393",
|
|
139
|
+
"@dxos/async": "0.8.4-main.4f23b4e393",
|
|
140
|
+
"@dxos/debug": "0.8.4-main.4f23b4e393",
|
|
141
|
+
"@dxos/echo-protocol": "0.8.4-main.4f23b4e393",
|
|
142
|
+
"@dxos/effect": "0.8.4-main.4f23b4e393",
|
|
143
|
+
"@dxos/errors": "0.8.4-main.4f23b4e393",
|
|
144
|
+
"@dxos/invariant": "0.8.4-main.4f23b4e393",
|
|
145
|
+
"@dxos/keys": "0.8.4-main.4f23b4e393",
|
|
146
|
+
"@dxos/log": "0.8.4-main.4f23b4e393",
|
|
147
|
+
"@dxos/node-std": "0.8.4-main.4f23b4e393",
|
|
148
|
+
"@dxos/protocols": "0.8.4-main.4f23b4e393",
|
|
149
|
+
"@dxos/util": "0.8.4-main.4f23b4e393"
|
|
150
150
|
},
|
|
151
151
|
"publishConfig": {
|
|
152
152
|
"access": "public"
|
package/src/Annotation.ts
CHANGED
package/src/Collection.ts
CHANGED
package/src/Database.ts
CHANGED
package/src/Entity.ts
CHANGED
|
@@ -198,7 +198,7 @@ export const subscribe = (entity: Unknown, callback: () => void): (() => void) =
|
|
|
198
198
|
//
|
|
199
199
|
|
|
200
200
|
/**
|
|
201
|
-
* Used to provide a mutable view of an entity within `Entity.
|
|
201
|
+
* Used to provide a mutable view of an entity within `Entity.update`.
|
|
202
202
|
*/
|
|
203
203
|
export type Mutable<T> = internal.Mutable<T>;
|
|
204
204
|
|
|
@@ -206,7 +206,7 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
206
206
|
* Perform mutations on an entity (object or relation) within a change context.
|
|
207
207
|
*
|
|
208
208
|
* Entities are read-only by default. Mutations are batched and notifications fire
|
|
209
|
-
* when the callback completes. Direct mutations outside of `Entity.
|
|
209
|
+
* when the callback completes. Direct mutations outside of `Entity.update` will throw
|
|
210
210
|
* at runtime.
|
|
211
211
|
*
|
|
212
212
|
* @param entity - The echo entity (object or relation) to mutate.
|
|
@@ -214,30 +214,30 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
214
214
|
*
|
|
215
215
|
* @example
|
|
216
216
|
* ```typescript
|
|
217
|
-
* // Mutate within Entity.
|
|
218
|
-
* Entity.
|
|
217
|
+
* // Mutate within Entity.update
|
|
218
|
+
* Entity.update(entity, (obj) => {
|
|
219
219
|
* obj.name = 'Updated';
|
|
220
220
|
* obj.count = 42;
|
|
221
221
|
* });
|
|
222
222
|
*
|
|
223
223
|
* // Direct mutation throws
|
|
224
|
-
* entity.name = 'Bob'; // Error: Cannot modify outside Entity.
|
|
224
|
+
* entity.name = 'Bob'; // Error: Cannot modify outside Entity.update()
|
|
225
225
|
* ```
|
|
226
226
|
*
|
|
227
|
-
* Note: For type-specific operations, prefer `Obj.
|
|
227
|
+
* Note: For type-specific operations, prefer `Obj.update` or `Relation.update`.
|
|
228
228
|
*/
|
|
229
|
-
export const
|
|
229
|
+
export const update = <T extends Unknown>(entity: T, callback: internal.ChangeCallback<T>): void => {
|
|
230
230
|
internal.change(entity, callback);
|
|
231
231
|
};
|
|
232
232
|
|
|
233
233
|
/**
|
|
234
234
|
* Add a tag to an entity.
|
|
235
|
-
* Must be called within an `Entity.
|
|
235
|
+
* Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
|
|
236
236
|
*/
|
|
237
237
|
export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.addTag(entity, tag);
|
|
238
238
|
|
|
239
239
|
/**
|
|
240
240
|
* Remove a tag from an entity.
|
|
241
|
-
* Must be called within an `Entity.
|
|
241
|
+
* Must be called within an `Entity.update`, `Obj.update`, or `Relation.update` callback.
|
|
242
242
|
*/
|
|
243
243
|
export const removeTag = (entity: Mutable<Unknown>, tag: string): void => internal.removeTag(entity, tag);
|
package/src/Extension.ts
CHANGED
|
@@ -43,7 +43,7 @@ export interface Extension<T> extends Record<
|
|
|
43
43
|
* email: 'john@example.com',
|
|
44
44
|
* });
|
|
45
45
|
*
|
|
46
|
-
* Obj.
|
|
46
|
+
* Obj.update(obj, (obj) => {
|
|
47
47
|
* Extension.set(obj.extensions, ColorExtension, 'red');
|
|
48
48
|
* });
|
|
49
49
|
*
|
|
@@ -103,10 +103,10 @@ export const get: {
|
|
|
103
103
|
/**
|
|
104
104
|
* Set the value of an extension in a set of values.
|
|
105
105
|
*
|
|
106
|
-
* Can also be used within Obj.
|
|
106
|
+
* Can also be used within Obj.update callback:
|
|
107
107
|
*
|
|
108
108
|
* ```ts
|
|
109
|
-
* Obj.
|
|
109
|
+
* Obj.update(obj, (obj) => {
|
|
110
110
|
* Extension.set(obj.extensions, ColorExtension, 'red');
|
|
111
111
|
* });
|
|
112
112
|
* ```
|
package/src/Feed.ts
CHANGED
|
@@ -10,7 +10,7 @@ import * as Layer from 'effect/Layer';
|
|
|
10
10
|
import type * as Option from 'effect/Option';
|
|
11
11
|
import * as Schema from 'effect/Schema';
|
|
12
12
|
|
|
13
|
-
import { DXN
|
|
13
|
+
import { DXN } from '@dxos/keys';
|
|
14
14
|
|
|
15
15
|
import * as Annotation from './Annotation';
|
|
16
16
|
import type * as Entity from './Entity';
|
|
@@ -80,6 +80,16 @@ export interface RetentionOptions {
|
|
|
80
80
|
cursor?: string;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Sync options for a feed.
|
|
85
|
+
*/
|
|
86
|
+
export interface SyncOptions {
|
|
87
|
+
/** Push local changes to the server. Defaults to true. */
|
|
88
|
+
shouldPush?: boolean;
|
|
89
|
+
/** Pull remote changes from the server. Defaults to true. */
|
|
90
|
+
shouldPull?: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
//
|
|
84
94
|
// Factory
|
|
85
95
|
//
|
|
@@ -109,27 +119,6 @@ export const getQueueDxn = (feed: Feed): DXN | undefined => {
|
|
|
109
119
|
return new DXN(DXN.kind.QUEUE, [feed.namespace ?? 'data', self.spaceId, self.echoId]);
|
|
110
120
|
};
|
|
111
121
|
|
|
112
|
-
/**
|
|
113
|
-
* Creates a Feed object from a queue DXN, inferring the feed's id and namespace from the DXN parts.
|
|
114
|
-
*
|
|
115
|
-
* The resulting Feed, when added to the same space as the queue, will have a queue DXN
|
|
116
|
-
* equal to the input (see `Feed.getQueueDxn`). Useful when migrating `Ref(Queue)` fields to
|
|
117
|
-
* `Ref(Feed.Feed)`.
|
|
118
|
-
*
|
|
119
|
-
* @remarks Unsafe because the caller must ensure the queue DXN's space matches the database
|
|
120
|
-
* the feed is added to; the feed id is set from the queue id, bypassing id generation.
|
|
121
|
-
*/
|
|
122
|
-
export const unsafeFromQueueDXN = (queueDxn: DXN): Feed => {
|
|
123
|
-
const parts = queueDxn.asQueueDXN();
|
|
124
|
-
if (!parts) {
|
|
125
|
-
throw new Error(`Expected a queue DXN, got: ${queueDxn.toString()}`);
|
|
126
|
-
}
|
|
127
|
-
return Obj.make(Feed, {
|
|
128
|
-
id: parts.queueId as ObjectId,
|
|
129
|
-
namespace: parts.subspaceTag === 'trace' ? 'trace' : undefined,
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
|
|
133
122
|
//
|
|
134
123
|
// Service
|
|
135
124
|
//
|
|
@@ -160,6 +149,11 @@ export class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<
|
|
|
160
149
|
<Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;
|
|
161
150
|
<F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;
|
|
162
151
|
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Syncs the feed with the server.
|
|
155
|
+
*/
|
|
156
|
+
sync(feed: Feed, options?: SyncOptions): Promise<void>;
|
|
163
157
|
}
|
|
164
158
|
>() {}
|
|
165
159
|
|
|
@@ -187,8 +181,30 @@ export const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService,
|
|
|
187
181
|
query: () => {
|
|
188
182
|
throw new Error('Feed.FeedService not available');
|
|
189
183
|
},
|
|
184
|
+
sync: () => {
|
|
185
|
+
throw new Error('Feed.FeedService not available');
|
|
186
|
+
},
|
|
190
187
|
} as Context.Tag.Service<FeedService>);
|
|
191
188
|
|
|
189
|
+
//
|
|
190
|
+
// Context (per-call) service
|
|
191
|
+
//
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Effect service exposing a single `Feed.Feed` as the "current" feed for a call site.
|
|
195
|
+
*
|
|
196
|
+
* @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures
|
|
197
|
+
* over hiding it behind a context service.
|
|
198
|
+
*/
|
|
199
|
+
export class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<
|
|
200
|
+
ContextFeedService,
|
|
201
|
+
{
|
|
202
|
+
readonly feed: Feed;
|
|
203
|
+
}
|
|
204
|
+
>() {
|
|
205
|
+
static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });
|
|
206
|
+
}
|
|
207
|
+
|
|
192
208
|
//
|
|
193
209
|
// Operations
|
|
194
210
|
//
|
|
@@ -262,6 +278,21 @@ export const runQuery: {
|
|
|
262
278
|
} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>
|
|
263
279
|
query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
|
|
264
280
|
|
|
281
|
+
/**
|
|
282
|
+
* Syncs the feed with the server.
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```ts
|
|
286
|
+
* yield* Feed.sync(feed);
|
|
287
|
+
* yield* Feed.sync(feed, { shouldPush: false });
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
export const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>
|
|
291
|
+
Effect.gen(function* () {
|
|
292
|
+
const service = yield* FeedService;
|
|
293
|
+
yield* Effect.promise(() => service.sync(feed, options));
|
|
294
|
+
});
|
|
295
|
+
|
|
265
296
|
/**
|
|
266
297
|
* Creates a cursor for iterating over feed items.
|
|
267
298
|
* Currently stubbed — cursor operations are not yet implemented.
|
|
@@ -292,13 +323,13 @@ export const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<
|
|
|
292
323
|
|
|
293
324
|
/**
|
|
294
325
|
* Sets the local retention policy for a feed.
|
|
295
|
-
* Currently stubbed —
|
|
326
|
+
* Currently stubbed — feeds do not yet support retention.
|
|
296
327
|
*
|
|
297
328
|
* @example
|
|
298
329
|
* ```ts
|
|
299
330
|
* yield* Feed.setRetention(feed, { count: 1000 });
|
|
300
331
|
* ```
|
|
301
332
|
*/
|
|
302
|
-
// TODO(
|
|
333
|
+
// TODO(dmaretskyi): Implement when feed retention is supported.
|
|
303
334
|
export const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>
|
|
304
335
|
Effect.void;
|
package/src/Hypergraph.ts
CHANGED
|
@@ -22,10 +22,10 @@ export interface RefResolutionContext {
|
|
|
22
22
|
space?: Key.SpaceId;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
* This
|
|
25
|
+
* Feed that the resolution is happening from (as the underlying queue DXN).
|
|
26
|
+
* This feed will be searched first, and then the space it belongs to.
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
feed?: DXN;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export interface RefResolverOptions {
|
package/src/Obj.test.ts
CHANGED
|
@@ -117,7 +117,7 @@ describe('Obj', () => {
|
|
|
117
117
|
|
|
118
118
|
test('returns keys from reactive object and snapshot', ({ expect }) => {
|
|
119
119
|
const obj = Obj.make(TestSchema.Person, { name: 'Test' });
|
|
120
|
-
Obj.
|
|
120
|
+
Obj.update(obj, (obj) => {
|
|
121
121
|
const meta = Obj.getMeta(obj);
|
|
122
122
|
meta.keys.push({ source: SOURCE, id: 'key-1' });
|
|
123
123
|
meta.keys.push({ source: SOURCE, id: 'key-2' });
|
|
@@ -166,7 +166,7 @@ describe('Obj', () => {
|
|
|
166
166
|
|
|
167
167
|
const cloned = Obj.clone(original);
|
|
168
168
|
|
|
169
|
-
Obj.
|
|
169
|
+
Obj.update(original, (original) => {
|
|
170
170
|
original.name = 'Bob';
|
|
171
171
|
});
|
|
172
172
|
|
|
@@ -206,7 +206,7 @@ describe('Obj', () => {
|
|
|
206
206
|
expect(cloned.employer?.target).toBe(person.employer?.target);
|
|
207
207
|
|
|
208
208
|
// Modifying the referenced object affects both
|
|
209
|
-
Obj.
|
|
209
|
+
Obj.update(employer, (employer) => {
|
|
210
210
|
employer.name = 'Updated DXOS';
|
|
211
211
|
});
|
|
212
212
|
|
|
@@ -234,7 +234,7 @@ describe('Obj', () => {
|
|
|
234
234
|
expect(cloned.employer?.target?.name).toBe(employer.name);
|
|
235
235
|
|
|
236
236
|
// Modifying the original referenced object does not affect the clone
|
|
237
|
-
Obj.
|
|
237
|
+
Obj.update(employer, (employer) => {
|
|
238
238
|
employer.name = 'Updated DXOS';
|
|
239
239
|
});
|
|
240
240
|
|
|
@@ -333,7 +333,7 @@ describe('Obj', () => {
|
|
|
333
333
|
expect(cloned.address?.coordinates.lng).toBe(-122.4194);
|
|
334
334
|
|
|
335
335
|
// Modifying nested properties should be independent
|
|
336
|
-
Obj.
|
|
336
|
+
Obj.update(person, (person) => {
|
|
337
337
|
person.address!.city = 'New York';
|
|
338
338
|
});
|
|
339
339
|
|
|
@@ -366,7 +366,7 @@ describe('Obj', () => {
|
|
|
366
366
|
expect(cloned.tasks?.[2]?.target).not.toBe(task3);
|
|
367
367
|
|
|
368
368
|
// Modifying original tasks should not affect cloned ones
|
|
369
|
-
Obj.
|
|
369
|
+
Obj.update(task1, (task1) => {
|
|
370
370
|
task1.title = 'Updated Task 1';
|
|
371
371
|
});
|
|
372
372
|
|
|
@@ -449,7 +449,7 @@ describe('Obj', () => {
|
|
|
449
449
|
test('returns false when values already match', () => {
|
|
450
450
|
const target = Obj.make(TestSchema.Organization, { name: 'Acme', properties: { region: 'EU' } });
|
|
451
451
|
const source = Obj.make(TestSchema.Organization, { name: 'Acme', properties: { region: 'EU' } });
|
|
452
|
-
Obj.
|
|
452
|
+
Obj.update(target, (target) => {
|
|
453
453
|
expect(Obj.updateFrom(target, source)).toBe(false);
|
|
454
454
|
});
|
|
455
455
|
});
|
|
@@ -463,7 +463,7 @@ describe('Obj', () => {
|
|
|
463
463
|
name: 'New',
|
|
464
464
|
properties: { a: '2', b: '3' },
|
|
465
465
|
});
|
|
466
|
-
Obj.
|
|
466
|
+
Obj.update(target, (target) => {
|
|
467
467
|
expect(Obj.updateFrom(target, source)).toBe(true);
|
|
468
468
|
});
|
|
469
469
|
expect(target.name).toBe('New');
|
|
@@ -487,7 +487,7 @@ describe('Obj', () => {
|
|
|
487
487
|
employer: Ref.make(orgB),
|
|
488
488
|
address: { city: 'Portland', state: 'OR', zip: '97201', coordinates: { lat: 45.5, lng: -122.6 } },
|
|
489
489
|
});
|
|
490
|
-
Obj.
|
|
490
|
+
Obj.update(target, (target) => {
|
|
491
491
|
expect(Obj.updateFrom(target, source)).toBe(true);
|
|
492
492
|
});
|
|
493
493
|
expect(target.employer?.dxn.toString()).toBe(Ref.make(orgB).dxn.toString());
|
|
@@ -510,7 +510,7 @@ describe('Obj', () => {
|
|
|
510
510
|
email: 'bob@x.test',
|
|
511
511
|
tasks: [Ref.make(t1), Ref.make(t3)],
|
|
512
512
|
});
|
|
513
|
-
Obj.
|
|
513
|
+
Obj.update(target, (target) => {
|
|
514
514
|
expect(Obj.updateFrom(target, source)).toBe(true);
|
|
515
515
|
});
|
|
516
516
|
expect(target.tasks?.map((r) => r.dxn.toString())).toEqual(source.tasks?.map((r) => r.dxn.toString()));
|
|
@@ -519,7 +519,7 @@ describe('Obj', () => {
|
|
|
519
519
|
test('respects include option', () => {
|
|
520
520
|
const target = Obj.make(TestSchema.Organization, { name: 'Keep', properties: { x: '1' } });
|
|
521
521
|
const source = Obj.make(TestSchema.Organization, { name: 'Drop', properties: { x: '2' } });
|
|
522
|
-
Obj.
|
|
522
|
+
Obj.update(target, (target) => {
|
|
523
523
|
expect(Obj.updateFrom(target, source, { include: ['properties'] })).toBe(true);
|
|
524
524
|
});
|
|
525
525
|
expect(target.name).toBe('Keep');
|
|
@@ -529,7 +529,7 @@ describe('Obj', () => {
|
|
|
529
529
|
test('respects exclude option', () => {
|
|
530
530
|
const target = Obj.make(TestSchema.Organization, { name: 'Old', properties: { x: '1' } });
|
|
531
531
|
const source = Obj.make(TestSchema.Organization, { name: 'New', properties: { x: '2' } });
|
|
532
|
-
Obj.
|
|
532
|
+
Obj.update(target, (target) => {
|
|
533
533
|
expect(Obj.updateFrom(target, source, { exclude: ['name'] })).toBe(true);
|
|
534
534
|
});
|
|
535
535
|
expect(target.name).toBe('Old');
|
package/src/Obj.ts
CHANGED
|
@@ -304,7 +304,7 @@ export const clone: <T extends Unknown>(obj: T, opts?: CloneOptions) => T = objI
|
|
|
304
304
|
|
|
305
305
|
/**
|
|
306
306
|
* Makes all properties mutable recursively.
|
|
307
|
-
* Used to provide a mutable view of an object within `Obj.
|
|
307
|
+
* Used to provide a mutable view of an object within `Obj.update`.
|
|
308
308
|
*/
|
|
309
309
|
export type Mutable<T> = internal.Mutable<T>;
|
|
310
310
|
|
|
@@ -312,33 +312,33 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
312
312
|
* Perform mutations on an echo object within a controlled context.
|
|
313
313
|
*
|
|
314
314
|
* All mutations within the callback are batched and trigger a single notification
|
|
315
|
-
* when the callback completes. Direct mutations outside of `Obj.
|
|
315
|
+
* when the callback completes. Direct mutations outside of `Obj.update` will throw
|
|
316
316
|
* an error for echo objects.
|
|
317
317
|
*
|
|
318
318
|
* This function also works with nested objects within echo objects (e.g., Template structs)
|
|
319
319
|
* that are reactive at runtime.
|
|
320
320
|
*
|
|
321
|
-
* @param obj - The echo object to mutate. Use `Relation.
|
|
321
|
+
* @param obj - The echo object to mutate. Use `Relation.update` for relations.
|
|
322
322
|
* @param callback - The callback that performs mutations on the object.
|
|
323
323
|
*
|
|
324
324
|
* @example
|
|
325
325
|
* ```ts
|
|
326
326
|
* const person = Obj.make(Person, { name: 'John', age: 25 });
|
|
327
327
|
*
|
|
328
|
-
* // Mutate within Obj.
|
|
329
|
-
* Obj.
|
|
328
|
+
* // Mutate within Obj.update
|
|
329
|
+
* Obj.update(person, (obj) => {
|
|
330
330
|
* obj.name = 'Jane';
|
|
331
331
|
* obj.age = 30;
|
|
332
332
|
* });
|
|
333
333
|
* // ONE notification fires here
|
|
334
334
|
*
|
|
335
335
|
* // Direct mutation throws
|
|
336
|
-
* person.name = 'Bob'; // Error: Cannot modify outside Obj.
|
|
336
|
+
* person.name = 'Bob'; // Error: Cannot modify outside Obj.update()
|
|
337
337
|
* ```
|
|
338
338
|
*
|
|
339
|
-
* Note: Only accepts objects. Use `Relation.
|
|
339
|
+
* Note: Only accepts objects. Use `Relation.update` for relations.
|
|
340
340
|
*/
|
|
341
|
-
export const
|
|
341
|
+
export const update = <T extends Unknown>(obj: T, callback: internal.ChangeCallback<T>): void => {
|
|
342
342
|
internal.change(obj, callback);
|
|
343
343
|
};
|
|
344
344
|
|
|
@@ -373,7 +373,7 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
373
373
|
* whether to initialize nested data as an empty object or array.
|
|
374
374
|
*
|
|
375
375
|
* Similar to lodash.set and setDeep from @dxos/util, but schema-aware.
|
|
376
|
-
* Must be called within an `Obj.
|
|
376
|
+
* Must be called within an `Obj.update` callback.
|
|
377
377
|
*
|
|
378
378
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
379
379
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -387,7 +387,7 @@ export const getValue = (obj: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
387
387
|
* ```ts
|
|
388
388
|
* const person = Obj.make(Person, { name: 'John' });
|
|
389
389
|
* // Person schema has: addresses: Schema.Array(Address)
|
|
390
|
-
* Obj.
|
|
390
|
+
* Obj.update(person, (obj) => {
|
|
391
391
|
* Obj.setValue(obj, ['addresses', 0, 'street'], '123 Main St');
|
|
392
392
|
* });
|
|
393
393
|
* // Creates: person.addresses = [{ street: '123 Main St' }]
|
|
@@ -520,7 +520,7 @@ export const Meta = internal.MetaId;
|
|
|
520
520
|
export type ReadonlyMeta = internal.ReadonlyMeta;
|
|
521
521
|
|
|
522
522
|
/**
|
|
523
|
-
* Mutable meta type returned by `Obj.getMeta` inside an `Obj.
|
|
523
|
+
* Mutable meta type returned by `Obj.getMeta` inside an `Obj.update` callback.
|
|
524
524
|
*/
|
|
525
525
|
export type Meta = internal.Meta;
|
|
526
526
|
|
|
@@ -528,7 +528,7 @@ export type Meta = internal.Meta;
|
|
|
528
528
|
// TODO(dmaretskyi): Allow returning undefined.
|
|
529
529
|
/**
|
|
530
530
|
* Get the metadata for an object.
|
|
531
|
-
* Returns mutable meta when passed a mutable object (inside `Obj.
|
|
531
|
+
* Returns mutable meta when passed a mutable object (inside `Obj.update` callback).
|
|
532
532
|
* Returns read-only meta when passed a regular object or snapshot.
|
|
533
533
|
*
|
|
534
534
|
* @example
|
|
@@ -537,7 +537,7 @@ export type Meta = internal.Meta;
|
|
|
537
537
|
* const meta = Obj.getMeta(person); // ReadonlyMeta
|
|
538
538
|
*
|
|
539
539
|
* // Mutable access inside change callback
|
|
540
|
-
* Obj.
|
|
540
|
+
* Obj.update(person, (obj) => {
|
|
541
541
|
* const meta = Obj.getMeta(obj); // ObjectMeta (mutable)
|
|
542
542
|
* meta.tags ??= [];
|
|
543
543
|
* meta.tags.push('important');
|
|
@@ -562,7 +562,7 @@ export const getKeys: {
|
|
|
562
562
|
|
|
563
563
|
/**
|
|
564
564
|
* Delete all keys from the object for the specified source.
|
|
565
|
-
* Must be called within an `Obj.
|
|
565
|
+
* Must be called within an `Obj.update` callback.
|
|
566
566
|
*
|
|
567
567
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
568
568
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -571,7 +571,7 @@ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => in
|
|
|
571
571
|
|
|
572
572
|
/**
|
|
573
573
|
* Add a tag to the object.
|
|
574
|
-
* Must be called within an `Obj.
|
|
574
|
+
* Must be called within an `Obj.update` callback.
|
|
575
575
|
*
|
|
576
576
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
577
577
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -580,7 +580,7 @@ export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.
|
|
|
580
580
|
|
|
581
581
|
/**
|
|
582
582
|
* Remove a tag from the object.
|
|
583
|
-
* Must be called within an `Obj.
|
|
583
|
+
* Must be called within an `Obj.update` callback.
|
|
584
584
|
*
|
|
585
585
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
586
586
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -606,7 +606,7 @@ export const getLabel = (entity: Unknown | Snapshot): string | undefined => inte
|
|
|
606
606
|
|
|
607
607
|
/**
|
|
608
608
|
* Set the label of the object.
|
|
609
|
-
* Must be called within an `Obj.
|
|
609
|
+
* Must be called within an `Obj.update` callback.
|
|
610
610
|
*
|
|
611
611
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
612
612
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -621,7 +621,7 @@ export const getDescription = (entity: Unknown | Snapshot): string | undefined =
|
|
|
621
621
|
|
|
622
622
|
/**
|
|
623
623
|
* Set the description of the object.
|
|
624
|
-
* Must be called within an `Obj.
|
|
624
|
+
* Must be called within an `Obj.update` callback.
|
|
625
625
|
*
|
|
626
626
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
627
627
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -744,7 +744,7 @@ const prepareAssignValue = (value: unknown): unknown =>
|
|
|
744
744
|
* References are compared by target DXN; other values use Effect `Equal.equals` inside a structural region,
|
|
745
745
|
* with recursive comparison for arrays and plain object-shaped property bags (excluding `id`).
|
|
746
746
|
*
|
|
747
|
-
* Must be called within an `Obj.
|
|
747
|
+
* Must be called within an `Obj.update` callback.
|
|
748
748
|
*
|
|
749
749
|
* @returns Whether any property was updated.
|
|
750
750
|
*/
|
package/src/Query.test.ts
CHANGED
|
@@ -523,7 +523,7 @@ describe('query api', () => {
|
|
|
523
523
|
"from": {
|
|
524
524
|
"_tag": "scope",
|
|
525
525
|
"scope": {
|
|
526
|
-
"
|
|
526
|
+
"allFeedsFromSpaces": true,
|
|
527
527
|
},
|
|
528
528
|
},
|
|
529
529
|
"query": {
|
|
@@ -563,17 +563,17 @@ describe('query api', () => {
|
|
|
563
563
|
test('Query.type(...).from(feed) sets queue scope', async () => {
|
|
564
564
|
const spaceId = SpaceId.random();
|
|
565
565
|
const feedId = ObjectId.random();
|
|
566
|
-
const
|
|
566
|
+
const feedDXN = DXN.parse(`dxn:echo:${spaceId}:${feedId}`);
|
|
567
567
|
const feed = (await Obj.fromJSON(
|
|
568
568
|
{
|
|
569
569
|
'@type': 'dxn:type:org.dxos.type.feed:0.1.0',
|
|
570
570
|
id: feedId,
|
|
571
571
|
name: 'test-feed',
|
|
572
572
|
},
|
|
573
|
-
{ dxn:
|
|
573
|
+
{ dxn: feedDXN },
|
|
574
574
|
)) as Feed.Feed;
|
|
575
575
|
|
|
576
|
-
const
|
|
576
|
+
const expectedQueueDXN = new DXN(DXN.kind.QUEUE, ['data', spaceId, feedId]);
|
|
577
577
|
|
|
578
578
|
const query = Query.type(TestSchema.Person).from(feed);
|
|
579
579
|
Schema.validateSync(QueryAST.Query)(query.ast);
|
|
@@ -582,7 +582,7 @@ describe('query api', () => {
|
|
|
582
582
|
from: {
|
|
583
583
|
_tag: 'scope',
|
|
584
584
|
scope: {
|
|
585
|
-
|
|
585
|
+
feeds: [expectedQueueDXN.toString()],
|
|
586
586
|
},
|
|
587
587
|
},
|
|
588
588
|
query: {
|
|
@@ -617,6 +617,22 @@ describe('query api', () => {
|
|
|
617
617
|
);
|
|
618
618
|
});
|
|
619
619
|
|
|
620
|
+
test('Query.pretty surfaces debugLabel from options', () => {
|
|
621
|
+
const query = Query.select(Filter.type(TestSchema.Person)).debugLabel('my-label');
|
|
622
|
+
expect(Query.pretty(query)).toContain('debugLabel');
|
|
623
|
+
expect(Query.pretty(query)).toContain('"my-label"');
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
test('Query.debugLabel merges onto existing options clause', () => {
|
|
627
|
+
const query = Query.select(Filter.type(TestSchema.Person))
|
|
628
|
+
.options({ deleted: 'exclude' })
|
|
629
|
+
.debugLabel('timer-probe');
|
|
630
|
+
const pretty = Query.pretty(query);
|
|
631
|
+
expect(pretty).toContain('deleted');
|
|
632
|
+
expect(pretty).toContain('debugLabel');
|
|
633
|
+
expect(pretty).toContain('"timer-probe"');
|
|
634
|
+
});
|
|
635
|
+
|
|
620
636
|
test('Query.pretty returns human-readable query string', () => {
|
|
621
637
|
const query = Query.select(Filter.type(TestSchema.Person, { name: 'Fred' }));
|
|
622
638
|
const pretty = Query.pretty(query);
|
|
@@ -670,13 +686,13 @@ describe('query api', () => {
|
|
|
670
686
|
|
|
671
687
|
describe('Filter.childOf', () => {
|
|
672
688
|
test('childOf with Ref', () => {
|
|
673
|
-
const
|
|
674
|
-
const parentRef = Ref.fromDXN(
|
|
689
|
+
const parentDXN = DXN.fromSpaceAndObjectId(SpaceId.random(), ObjectId.random());
|
|
690
|
+
const parentRef = Ref.fromDXN(parentDXN);
|
|
675
691
|
const filter = Filter.childOf(parentRef);
|
|
676
692
|
|
|
677
693
|
expect(filter.ast).toMatchObject({
|
|
678
694
|
type: 'child-of',
|
|
679
|
-
parents: [
|
|
695
|
+
parents: [parentDXN.toString()],
|
|
680
696
|
transitive: true,
|
|
681
697
|
});
|
|
682
698
|
Schema.validateSync(QueryAST.Filter)(filter.ast);
|
|
@@ -720,15 +736,15 @@ describe('query api', () => {
|
|
|
720
736
|
});
|
|
721
737
|
|
|
722
738
|
test('childOf in select query', () => {
|
|
723
|
-
const
|
|
724
|
-
const parentRef = Ref.fromDXN(
|
|
739
|
+
const parentDXN = DXN.fromSpaceAndObjectId(SpaceId.random(), ObjectId.random());
|
|
740
|
+
const parentRef = Ref.fromDXN(parentDXN);
|
|
725
741
|
const query = Query.select(Filter.childOf(parentRef));
|
|
726
742
|
|
|
727
743
|
expect(query.ast).toMatchObject({
|
|
728
744
|
type: 'select',
|
|
729
745
|
filter: {
|
|
730
746
|
type: 'child-of',
|
|
731
|
-
parents: [
|
|
747
|
+
parents: [parentDXN.toString()],
|
|
732
748
|
transitive: true,
|
|
733
749
|
},
|
|
734
750
|
});
|
|
@@ -736,8 +752,8 @@ describe('query api', () => {
|
|
|
736
752
|
});
|
|
737
753
|
|
|
738
754
|
test('childOf combined with type filter', () => {
|
|
739
|
-
const
|
|
740
|
-
const parentRef = Ref.fromDXN(
|
|
755
|
+
const parentDXN = DXN.fromSpaceAndObjectId(SpaceId.random(), ObjectId.random());
|
|
756
|
+
const parentRef = Ref.fromDXN(parentDXN);
|
|
741
757
|
const query = Query.select(Filter.and(Filter.type(TestSchema.Person), Filter.childOf(parentRef)));
|
|
742
758
|
|
|
743
759
|
Schema.validateSync(QueryAST.Query)(query.ast);
|
|
@@ -747,7 +763,7 @@ describe('query api', () => {
|
|
|
747
763
|
type: 'and',
|
|
748
764
|
filters: [
|
|
749
765
|
{ type: 'object', typename: 'dxn:type:com.example.type.person:0.1.0' },
|
|
750
|
-
{ type: 'child-of', parents: [
|
|
766
|
+
{ type: 'child-of', parents: [parentDXN.toString()], transitive: true },
|
|
751
767
|
],
|
|
752
768
|
},
|
|
753
769
|
});
|
|
@@ -763,8 +779,8 @@ describe('query api', () => {
|
|
|
763
779
|
|
|
764
780
|
test('childOf with mixed objects and Refs', () => {
|
|
765
781
|
const parent = Obj.make(TestSchema.Person, { name: 'Parent' });
|
|
766
|
-
const
|
|
767
|
-
const parentRef = Ref.fromDXN(
|
|
782
|
+
const refDXN = DXN.fromSpaceAndObjectId(SpaceId.random(), ObjectId.random());
|
|
783
|
+
const parentRef = Ref.fromDXN(refDXN);
|
|
768
784
|
const filter = Filter.childOf([parent, parentRef]);
|
|
769
785
|
|
|
770
786
|
expect(filter.ast).toMatchObject({
|