@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/src/Query.ts
CHANGED
|
@@ -207,6 +207,11 @@ export interface Query<T> {
|
|
|
207
207
|
* Add options to a query.
|
|
208
208
|
*/
|
|
209
209
|
'options'(options: QueryAST.QueryOptions): Query<T>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Attach a diagnostic label for logs and tooling (execution semantics unchanged).
|
|
213
|
+
*/
|
|
214
|
+
'debugLabel'(label: string): Query<T>;
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
export type Any = Query<any>;
|
|
@@ -354,7 +359,7 @@ class QueryClass implements Any {
|
|
|
354
359
|
from: {
|
|
355
360
|
_tag: 'scope',
|
|
356
361
|
scope: {
|
|
357
|
-
...(options?.includeFeeds ? {
|
|
362
|
+
...(options?.includeFeeds ? { allFeedsFromSpaces: true } : {}),
|
|
358
363
|
},
|
|
359
364
|
},
|
|
360
365
|
});
|
|
@@ -379,7 +384,7 @@ class QueryClass implements Any {
|
|
|
379
384
|
_tag: 'scope',
|
|
380
385
|
scope: {
|
|
381
386
|
spaceIds: databases.map((db) => db.spaceId),
|
|
382
|
-
...(options?.includeFeeds ? {
|
|
387
|
+
...(options?.includeFeeds ? { allFeedsFromSpaces: true } : {}),
|
|
383
388
|
},
|
|
384
389
|
},
|
|
385
390
|
});
|
|
@@ -405,10 +410,15 @@ class QueryClass implements Any {
|
|
|
405
410
|
}
|
|
406
411
|
}
|
|
407
412
|
|
|
408
|
-
const
|
|
409
|
-
const
|
|
413
|
+
const feedItems = items as Feed.Feed[];
|
|
414
|
+
const feedDXNs = feedItems.map((feed) => {
|
|
410
415
|
const dxn = Feed.getQueueDxn(feed);
|
|
411
|
-
|
|
416
|
+
if (!dxn) {
|
|
417
|
+
throw new TypeError(
|
|
418
|
+
`Query.from() expects persisted Feed objects with a queue DXN; got feed without a space (id=${Obj.getDXN(feed).toString()}).`,
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
return dxn.toString();
|
|
412
422
|
});
|
|
413
423
|
return new QueryClass({
|
|
414
424
|
type: 'from',
|
|
@@ -416,7 +426,7 @@ class QueryClass implements Any {
|
|
|
416
426
|
from: {
|
|
417
427
|
_tag: 'scope',
|
|
418
428
|
scope: {
|
|
419
|
-
|
|
429
|
+
feeds: feedDXNs,
|
|
420
430
|
},
|
|
421
431
|
},
|
|
422
432
|
});
|
|
@@ -429,6 +439,21 @@ class QueryClass implements Any {
|
|
|
429
439
|
options,
|
|
430
440
|
});
|
|
431
441
|
}
|
|
442
|
+
|
|
443
|
+
debugLabel(label: string): Any {
|
|
444
|
+
if (this.ast.type === 'options') {
|
|
445
|
+
return new QueryClass({
|
|
446
|
+
type: 'options',
|
|
447
|
+
query: this.ast.query,
|
|
448
|
+
options: { ...this.ast.options, debugLabel: label },
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
return new QueryClass({
|
|
452
|
+
type: 'options',
|
|
453
|
+
query: this.ast,
|
|
454
|
+
options: { debugLabel: label },
|
|
455
|
+
});
|
|
456
|
+
}
|
|
432
457
|
}
|
|
433
458
|
|
|
434
459
|
export const is = (value: unknown): value is Any => {
|
|
@@ -531,7 +556,7 @@ export const from = (
|
|
|
531
556
|
return wrapper.from(source as any, options);
|
|
532
557
|
};
|
|
533
558
|
|
|
534
|
-
const SCOPE_KEYS = new Set(['spaceIds', '
|
|
559
|
+
const SCOPE_KEYS = new Set(['spaceIds', 'feeds', 'allFeedsFromSpaces']);
|
|
535
560
|
|
|
536
561
|
/** Detect a raw Scope object (plain object with only Scope-valid keys). */
|
|
537
562
|
const _isScope = (value: unknown): value is QueryAST.Scope => {
|
package/src/Ref.ts
CHANGED
|
@@ -85,6 +85,8 @@ export const make = refInternal.Ref.make;
|
|
|
85
85
|
// TODO(dmaretskyi): Consider just allowing `make` to accept DXN.
|
|
86
86
|
export const fromDXN = refInternal.Ref.fromDXN;
|
|
87
87
|
|
|
88
|
+
export const hasObjectId = refInternal.Ref.hasObjectId;
|
|
89
|
+
|
|
88
90
|
// TODO(wittjosiah): Factor out?
|
|
89
91
|
export const isRefType = (ast: SchemaAST.AST): boolean => {
|
|
90
92
|
return SchemaAST.getAnnotation<JsonSchema.JsonSchema>(ast, SchemaAST.JSONSchemaAnnotationId).pipe(
|
package/src/Relation.ts
CHANGED
|
@@ -264,7 +264,7 @@ export const getTarget = <T extends Unknown | Snapshot>(relation: T): TargetOf<T
|
|
|
264
264
|
|
|
265
265
|
/**
|
|
266
266
|
* Makes all properties mutable recursively.
|
|
267
|
-
* Used to provide a mutable view of a relation within `Relation.
|
|
267
|
+
* Used to provide a mutable view of a relation within `Relation.update`.
|
|
268
268
|
*/
|
|
269
269
|
export type Mutable<T> = internal.Mutable<T>;
|
|
270
270
|
|
|
@@ -272,10 +272,10 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
272
272
|
* Perform mutations on an echo relation within a controlled context.
|
|
273
273
|
*
|
|
274
274
|
* All mutations within the callback are batched and trigger a single notification
|
|
275
|
-
* when the callback completes. Direct mutations outside of `Relation.
|
|
275
|
+
* when the callback completes. Direct mutations outside of `Relation.update` will throw
|
|
276
276
|
* an error for echo relations.
|
|
277
277
|
*
|
|
278
|
-
* @param relation - The echo relation to mutate. Use `Obj.
|
|
278
|
+
* @param relation - The echo relation to mutate. Use `Obj.update` for objects.
|
|
279
279
|
* @param callback - The callback that performs mutations on the relation.
|
|
280
280
|
*
|
|
281
281
|
* @example
|
|
@@ -286,15 +286,15 @@ export type Mutable<T> = internal.Mutable<T>;
|
|
|
286
286
|
* role: 'Engineer',
|
|
287
287
|
* });
|
|
288
288
|
*
|
|
289
|
-
* // Mutate within Relation.
|
|
290
|
-
* Relation.
|
|
289
|
+
* // Mutate within Relation.update
|
|
290
|
+
* Relation.update(worksFor, (obj) => {
|
|
291
291
|
* obj.role = 'Senior Engineer';
|
|
292
292
|
* });
|
|
293
293
|
* ```
|
|
294
294
|
*
|
|
295
|
-
* Note: Only accepts relations. Use `Obj.
|
|
295
|
+
* Note: Only accepts relations. Use `Obj.update` for objects.
|
|
296
296
|
*/
|
|
297
|
-
export const
|
|
297
|
+
export const update = <T extends Unknown>(relation: T, callback: internal.ChangeCallback<T>): void => {
|
|
298
298
|
internal.change(relation, callback);
|
|
299
299
|
};
|
|
300
300
|
|
|
@@ -337,7 +337,7 @@ export const getValue = (rel: Unknown | Snapshot, path: readonly (string | numbe
|
|
|
337
337
|
|
|
338
338
|
/**
|
|
339
339
|
* Set a deeply nested property on a relation.
|
|
340
|
-
* Must be called within a `Relation.
|
|
340
|
+
* Must be called within a `Relation.update` callback.
|
|
341
341
|
*
|
|
342
342
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
343
343
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -399,13 +399,13 @@ export const Meta = internal.MetaId;
|
|
|
399
399
|
export type ReadonlyMeta = internal.ReadonlyMeta;
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
|
-
* Mutable meta type returned by `Relation.getMeta` inside a `Relation.
|
|
402
|
+
* Mutable meta type returned by `Relation.getMeta` inside a `Relation.update` callback.
|
|
403
403
|
*/
|
|
404
404
|
export type Meta = internal.Meta;
|
|
405
405
|
|
|
406
406
|
/**
|
|
407
407
|
* Get the metadata for a relation.
|
|
408
|
-
* Returns mutable meta when passed a mutable relation (inside `Relation.
|
|
408
|
+
* Returns mutable meta when passed a mutable relation (inside `Relation.update` callback).
|
|
409
409
|
* Returns read-only meta when passed a regular relation or snapshot.
|
|
410
410
|
*/
|
|
411
411
|
// TODO(wittjosiah): When passed a Snapshot, should return a snapshot of meta, not the live meta proxy.
|
|
@@ -423,7 +423,7 @@ export const getKeys = (entity: Unknown | Snapshot, source: string): ForeignKey[
|
|
|
423
423
|
|
|
424
424
|
/**
|
|
425
425
|
* Delete all keys from the relation for the specified source.
|
|
426
|
-
* Must be called within a `Relation.
|
|
426
|
+
* Must be called within a `Relation.update` callback.
|
|
427
427
|
*
|
|
428
428
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
429
429
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -432,7 +432,7 @@ export const deleteKeys = (entity: Mutable<Unknown>, source: string): void => in
|
|
|
432
432
|
|
|
433
433
|
/**
|
|
434
434
|
* Add a tag to the relation.
|
|
435
|
-
* Must be called within a `Relation.
|
|
435
|
+
* Must be called within a `Relation.update` callback.
|
|
436
436
|
*
|
|
437
437
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
438
438
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -441,7 +441,7 @@ export const addTag = (entity: Mutable<Unknown>, tag: string): void => internal.
|
|
|
441
441
|
|
|
442
442
|
/**
|
|
443
443
|
* Remove a tag from the relation.
|
|
444
|
-
* Must be called within a `Relation.
|
|
444
|
+
* Must be called within a `Relation.update` callback.
|
|
445
445
|
*
|
|
446
446
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
447
447
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -466,7 +466,7 @@ export const getLabel = (entity: Unknown | Snapshot): string | undefined => inte
|
|
|
466
466
|
|
|
467
467
|
/**
|
|
468
468
|
* Set the label of the relation.
|
|
469
|
-
* Must be called within a `Relation.
|
|
469
|
+
* Must be called within a `Relation.update` callback.
|
|
470
470
|
*
|
|
471
471
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
472
472
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -481,7 +481,7 @@ export const getDescription = (entity: Unknown | Snapshot): string | undefined =
|
|
|
481
481
|
|
|
482
482
|
/**
|
|
483
483
|
* Set the description of the relation.
|
|
484
|
-
* Must be called within a `Relation.
|
|
484
|
+
* Must be called within a `Relation.update` callback.
|
|
485
485
|
*
|
|
486
486
|
* NOTE: TypeScript's structural typing allows readonly objects to be passed to `Mutable<T>`
|
|
487
487
|
* parameters, so there is no compile-time error. Enforcement is runtime-only.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import * as Obj from './Obj';
|
|
8
|
+
import { TestSchema } from './testing';
|
|
9
|
+
import type * as Type from './Type';
|
|
10
|
+
|
|
11
|
+
describe('Exemplars', () => {
|
|
12
|
+
test('factory', ({ expect }) => {
|
|
13
|
+
const factory = <S extends Type.AnyObj>(schema: S) => {
|
|
14
|
+
return (props: Obj.MakeProps<S>) => Obj.make(schema, props);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const makePerson = factory(TestSchema.Person);
|
|
18
|
+
const person = makePerson({ name: 'John Doe' });
|
|
19
|
+
expect(person.name).toBe('John Doe');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -481,7 +481,7 @@ export const makeUserAnnotation = <T>(props: MakeAnnoationsProps<T>): Annotation
|
|
|
481
481
|
|
|
482
482
|
const getFromAst = (ast: SchemaAST.AST) =>
|
|
483
483
|
SchemaAST.getAnnotation<PropertyMetaAnnotation>(PropertyMetaAnnotationId)(ast).pipe(
|
|
484
|
-
Option.
|
|
484
|
+
Option.flatMap((meta) => Option.fromNullable(meta[props.id])),
|
|
485
485
|
Option.map(Schema.decodeUnknownSync(props.schema)),
|
|
486
486
|
);
|
|
487
487
|
|
|
@@ -532,6 +532,19 @@ export const IconAnnotation = makeUserAnnotation<IconAnnotation>({
|
|
|
532
532
|
schema: IconAnnotationSchema,
|
|
533
533
|
});
|
|
534
534
|
|
|
535
|
+
/**
|
|
536
|
+
* Indicates that this entity's icon should be resolved from a property whose value is a `Ref`
|
|
537
|
+
* to another entity. Consumers (e.g. graph node builders) resolve the ref target and use that
|
|
538
|
+
* target's schema `IconAnnotation` in place of the static one declared on this schema.
|
|
539
|
+
*
|
|
540
|
+
* Useful for wrapper schemas that delegate their visual identity to a referenced sub-entity
|
|
541
|
+
* (e.g. a generic `Game` whose icon should come from its `variant` ref's typed state).
|
|
542
|
+
*/
|
|
543
|
+
export const IconFromRefAnnotation = makeUserAnnotation<string>({
|
|
544
|
+
id: 'org.dxos.annotation.icon.from-ref',
|
|
545
|
+
schema: Schema.String,
|
|
546
|
+
});
|
|
547
|
+
|
|
535
548
|
/**
|
|
536
549
|
* Get the label of an entity.
|
|
537
550
|
* Accepts both reactive entities and snapshots.
|
|
@@ -545,7 +558,7 @@ export const getLabel = (entity: AnyProperties): string | undefined => {
|
|
|
545
558
|
|
|
546
559
|
/**
|
|
547
560
|
* Set the label of an entity.
|
|
548
|
-
* Must be called within an Obj.
|
|
561
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
549
562
|
*/
|
|
550
563
|
export const setLabel = (entity: Mutable<AnyProperties>, label: string) => {
|
|
551
564
|
const schema = getSchema(entity);
|
|
@@ -567,7 +580,7 @@ export const getDescription = (entity: AnyProperties): string | undefined => {
|
|
|
567
580
|
|
|
568
581
|
/**
|
|
569
582
|
* Set the description of an entity.
|
|
570
|
-
* Must be called within an Obj.
|
|
583
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
571
584
|
*/
|
|
572
585
|
export const setDescription = (entity: Mutable<AnyProperties>, description: string) => {
|
|
573
586
|
const schema = getSchema(entity);
|
package/src/internal/Obj/ids.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { DXN, ObjectId, QueueSubspaceTags, SpaceId } from '@dxos/keys';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* @deprecated Use `db.
|
|
8
|
+
* @deprecated Use `Feed.make(...)` + `db.add(feed)` then `Feed.getQueueDxn(feed)`.
|
|
9
9
|
*/
|
|
10
10
|
// TODO(burdon): Move to @dxos/keys.
|
|
11
11
|
export const createQueueDXN = (spaceId = SpaceId.random(), queueId = ObjectId.random()) =>
|
|
@@ -20,7 +20,7 @@ import { objectFromJSON, objectToJSON } from './json-serializer';
|
|
|
20
20
|
describe('Object JSON serializer', () => {
|
|
21
21
|
test('should serialize and deserialize object', async () => {
|
|
22
22
|
const contact = makeObject(TestSchema.Person, { name: 'Alice' });
|
|
23
|
-
Obj.
|
|
23
|
+
Obj.update(contact, (contact) => {
|
|
24
24
|
getMetaChecked(contact).keys.push({ id: '12345', source: 'example.com' });
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -116,15 +116,15 @@ export const objectFromJSON = async (
|
|
|
116
116
|
const isRelation =
|
|
117
117
|
typeof jsonData[ATTR_RELATION_SOURCE] === 'string' || typeof jsonData[ATTR_RELATION_TARGET] === 'string';
|
|
118
118
|
if (isRelation) {
|
|
119
|
-
const
|
|
120
|
-
const
|
|
119
|
+
const sourceDXN: DXN = DXN.parse(jsonData[ATTR_RELATION_SOURCE] ?? raise(new TypeError('Missing relation source')));
|
|
120
|
+
const targetDXN: DXN = DXN.parse(jsonData[ATTR_RELATION_TARGET] ?? raise(new TypeError('Missing relation target')));
|
|
121
121
|
|
|
122
|
-
const source = (await refResolver?.resolve(
|
|
123
|
-
const target = (await refResolver?.resolve(
|
|
122
|
+
const source = (await refResolver?.resolve(sourceDXN)) as AnyEntity | undefined;
|
|
123
|
+
const target = (await refResolver?.resolve(targetDXN)) as AnyEntity | undefined;
|
|
124
124
|
|
|
125
125
|
defineHiddenProperty(obj, KindId, EntityKind.Relation);
|
|
126
|
-
defineHiddenProperty(obj, RelationSourceDXNId,
|
|
127
|
-
defineHiddenProperty(obj, RelationTargetDXNId,
|
|
126
|
+
defineHiddenProperty(obj, RelationSourceDXNId, sourceDXN);
|
|
127
|
+
defineHiddenProperty(obj, RelationTargetDXNId, targetDXN);
|
|
128
128
|
defineHiddenProperty(obj, RelationSourceId, source);
|
|
129
129
|
defineHiddenProperty(obj, RelationTargetId, target);
|
|
130
130
|
} else {
|
|
@@ -142,8 +142,8 @@ export const objectFromJSON = async (
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
if (jsonData[ATTR_PARENT]) {
|
|
145
|
-
const
|
|
146
|
-
const resolvedParent = (await refResolver?.resolve(
|
|
145
|
+
const parentDXN = DXN.parse(jsonData[ATTR_PARENT]);
|
|
146
|
+
const resolvedParent = (await refResolver?.resolve(parentDXN)) as Obj.Unknown | undefined;
|
|
147
147
|
defineHiddenProperty(obj, ParentId, resolvedParent);
|
|
148
148
|
} else if (parent) {
|
|
149
149
|
defineHiddenProperty(obj, ParentId, parent);
|
|
@@ -184,7 +184,7 @@ const stripInternalJsonKeys = (jsonData: unknown) => {
|
|
|
184
184
|
[ATTR_TYPE]: _type,
|
|
185
185
|
[ATTR_META]: _meta,
|
|
186
186
|
[ATTR_DELETED]: _deleted,
|
|
187
|
-
[ATTR_SELF_DXN]:
|
|
187
|
+
[ATTR_SELF_DXN]: _selfDXN,
|
|
188
188
|
[ATTR_RELATION_SOURCE]: _relationSource,
|
|
189
189
|
[ATTR_RELATION_TARGET]: _relationTarget,
|
|
190
190
|
...props
|
|
@@ -17,7 +17,7 @@ describe('Obj.setValue', () => {
|
|
|
17
17
|
email: 'john@example.com',
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
Obj.
|
|
20
|
+
Obj.update(person, (person) => Obj.setValue(person, ['address', 'city'], 'NYC'));
|
|
21
21
|
|
|
22
22
|
expect(person.address).toBeDefined();
|
|
23
23
|
expect(person.address?.city).toBe('NYC');
|
|
@@ -30,7 +30,7 @@ describe('Obj.setValue', () => {
|
|
|
30
30
|
email: 'john@example.com',
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
Obj.
|
|
33
|
+
Obj.update(person, (person) => Obj.setValue(person, ['fields', 0, 'label'], 'Phone'));
|
|
34
34
|
|
|
35
35
|
expect(Array.isArray(person.fields)).toBe(true);
|
|
36
36
|
expect(person.fields?.[0].label).toBe('Phone');
|
|
@@ -45,7 +45,7 @@ describe('Obj.setValue', () => {
|
|
|
45
45
|
email: 'john@example.com',
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
Obj.
|
|
48
|
+
Obj.update(person, (person) => Obj.setValue(person, ['address', 'coordinates', 'lat'], 40.7128));
|
|
49
49
|
|
|
50
50
|
expect(person.address).toBeDefined();
|
|
51
51
|
expect(person.address?.coordinates).toBeDefined();
|
|
@@ -69,7 +69,7 @@ describe('Obj.setValue', () => {
|
|
|
69
69
|
|
|
70
70
|
const container = Obj.make(Container, { name: 'box' });
|
|
71
71
|
|
|
72
|
-
Obj.
|
|
72
|
+
Obj.update(container, (container) => {
|
|
73
73
|
Obj.setValue(container, ['items', 0, 'value'], 10);
|
|
74
74
|
Obj.setValue(container, ['items', 1, 'value'], 20);
|
|
75
75
|
Obj.setValue(container, ['items', 2, 'value'], 30);
|
|
@@ -88,7 +88,7 @@ describe('Obj.setValue', () => {
|
|
|
88
88
|
email: 'john@example.com',
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
Obj.
|
|
91
|
+
Obj.update(person, (person) => Obj.setValue(person, ['age'], 25));
|
|
92
92
|
|
|
93
93
|
expect(person.age).toBe(25);
|
|
94
94
|
});
|
|
@@ -100,7 +100,7 @@ describe('Obj.setValue', () => {
|
|
|
100
100
|
email: 'john@example.com',
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
Obj.
|
|
103
|
+
Obj.update(person, (person) => Obj.setValue(person, ['address', 'city'], 'NYC'));
|
|
104
104
|
|
|
105
105
|
expect(person.address).toBeDefined();
|
|
106
106
|
expect(person.address?.city).toBe('NYC');
|
|
@@ -114,7 +114,7 @@ describe('Obj.setValue', () => {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
let result: any;
|
|
117
|
-
Obj.
|
|
117
|
+
Obj.update(person, (person) => {
|
|
118
118
|
result = Obj.setValue(person, ['age'], 30);
|
|
119
119
|
});
|
|
120
120
|
|
|
@@ -129,7 +129,7 @@ describe('Obj.setValue', () => {
|
|
|
129
129
|
age: 25,
|
|
130
130
|
});
|
|
131
131
|
|
|
132
|
-
Obj.
|
|
132
|
+
Obj.update(person, (person) => Obj.setValue(person, ['age'], 30));
|
|
133
133
|
|
|
134
134
|
expect(person.age).toBe(30);
|
|
135
135
|
});
|
|
@@ -142,7 +142,7 @@ describe('Obj.setValue', () => {
|
|
|
142
142
|
address: { city: 'Boston', state: 'MA', coordinates: {} },
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
Obj.
|
|
145
|
+
Obj.update(person, (person) => Obj.setValue(person, ['address', 'city'], 'NYC'));
|
|
146
146
|
|
|
147
147
|
expect(person.address?.city).toBe('NYC');
|
|
148
148
|
expect(person.address?.state).toBe('MA');
|
|
@@ -160,7 +160,7 @@ describe('Obj.setValue', () => {
|
|
|
160
160
|
|
|
161
161
|
const matrix = Obj.make(Matrix, {});
|
|
162
162
|
|
|
163
|
-
Obj.
|
|
163
|
+
Obj.update(matrix, (matrix) => {
|
|
164
164
|
Obj.setValue(matrix, ['values', 0, 0], 1);
|
|
165
165
|
Obj.setValue(matrix, ['values', 0, 1], 2);
|
|
166
166
|
Obj.setValue(matrix, ['values', 1, 0], 3);
|
|
@@ -180,7 +180,7 @@ describe('Obj.setValue', () => {
|
|
|
180
180
|
email: 'john@example.com',
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
Obj.
|
|
183
|
+
Obj.update(person, (person) => {
|
|
184
184
|
expect(() => Obj.setValue(person, [], 'value')).toThrow('Path must not be empty');
|
|
185
185
|
});
|
|
186
186
|
});
|
|
@@ -192,7 +192,7 @@ describe('Obj.setValue', () => {
|
|
|
192
192
|
email: 'john@example.com',
|
|
193
193
|
});
|
|
194
194
|
|
|
195
|
-
Obj.
|
|
195
|
+
Obj.update(person, (person) => Obj.setValue(person, ['age'], 30));
|
|
196
196
|
|
|
197
197
|
expect(person.age).toBe(30);
|
|
198
198
|
});
|
|
@@ -215,7 +215,7 @@ describe('Obj.setValue', () => {
|
|
|
215
215
|
const container = Obj.make(Container, { name: 'box' });
|
|
216
216
|
|
|
217
217
|
// Using string '0' for array index.
|
|
218
|
-
Obj.
|
|
218
|
+
Obj.update(container, (container) => Obj.setValue(container, ['items', '0', 'value'], 42));
|
|
219
219
|
|
|
220
220
|
expect(container.items?.[0].value).toBe(42);
|
|
221
221
|
});
|
|
@@ -243,7 +243,7 @@ describe('Obj.setValue', () => {
|
|
|
243
243
|
|
|
244
244
|
// This should work: setting a nested property on an array element.
|
|
245
245
|
// The required 'id' field should be initialized with a default value.
|
|
246
|
-
Obj.
|
|
246
|
+
Obj.update(todoList, (todoList) => Obj.setValue(todoList, ['tasks', 0, 'title'], 'Buy groceries'));
|
|
247
247
|
|
|
248
248
|
expect(todoList.tasks?.[0].id).toBe(''); // Default value for required String
|
|
249
249
|
expect(todoList.tasks?.[0].title).toBe('Buy groceries');
|
|
@@ -270,7 +270,7 @@ describe('Obj.setValue', () => {
|
|
|
270
270
|
|
|
271
271
|
const container = Obj.make(Container, { name: 'box' });
|
|
272
272
|
|
|
273
|
-
Obj.
|
|
273
|
+
Obj.update(container, (container) => Obj.setValue(container, ['items', 0, 'label'], 'First Item'));
|
|
274
274
|
|
|
275
275
|
// All required primitive fields should have default values.
|
|
276
276
|
expect(container.items?.[0].id).toBe('');
|
|
@@ -21,7 +21,7 @@ import { getSchema } from '../common/types';
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Set a deeply nested property on an object.
|
|
24
|
-
* Must be called within an Obj.
|
|
24
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
25
25
|
*/
|
|
26
26
|
export const setValue = (obj: Mutable<any>, path: readonly (string | number)[], value: any): void => {
|
|
27
27
|
invariant(path.length > 0, 'Path must not be empty');
|
package/src/internal/Query.ts
CHANGED
|
@@ -109,6 +109,9 @@ export const prettyQuery = (query: QueryAST.Query): string => {
|
|
|
109
109
|
if (opts.deleted !== undefined) {
|
|
110
110
|
parts.push(`deleted: ${JSON.stringify(opts.deleted)}`);
|
|
111
111
|
}
|
|
112
|
+
if (opts.debugLabel !== undefined) {
|
|
113
|
+
parts.push(`debugLabel: ${JSON.stringify(opts.debugLabel)}`);
|
|
114
|
+
}
|
|
112
115
|
return `${prettyQuery(query.query)}.options({ ${parts.join(', ')} })`;
|
|
113
116
|
}
|
|
114
117
|
case 'from': {
|
|
@@ -118,11 +121,11 @@ export const prettyQuery = (query: QueryAST.Query): string => {
|
|
|
118
121
|
if (scope.spaceIds !== undefined) {
|
|
119
122
|
parts.push(`spaceIds: [${scope.spaceIds.map((s) => JSON.stringify(s)).join(', ')}]`);
|
|
120
123
|
}
|
|
121
|
-
if (scope.
|
|
122
|
-
parts.push(`
|
|
124
|
+
if (scope.feeds !== undefined) {
|
|
125
|
+
parts.push(`feeds: [${scope.feeds.map(String).join(', ')}]`);
|
|
123
126
|
}
|
|
124
|
-
if (scope.
|
|
125
|
-
parts.push(`
|
|
127
|
+
if (scope.allFeedsFromSpaces !== undefined) {
|
|
128
|
+
parts.push(`allFeedsFromSpaces: ${scope.allFeedsFromSpaces}`);
|
|
126
129
|
}
|
|
127
130
|
return `${prettyQuery(query.query)}.from({ ${parts.join(', ')} })`;
|
|
128
131
|
}
|
|
@@ -372,7 +372,7 @@ export class EchoSchema<A = any, I = any> extends EchoSchemaConstructor() implem
|
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
/**
|
|
375
|
-
* Wrapper for Obj.
|
|
375
|
+
* Wrapper for Obj.update that handles the change context for the persistent schema.
|
|
376
376
|
*/
|
|
377
377
|
private _change(callback: (schema: PersistentSchema) => void): void {
|
|
378
378
|
const changeFn = (this._persistentSchema as any)[ChangeId];
|
|
@@ -99,4 +99,4 @@
|
|
|
99
99
|
- [ ] ReactiveObject should specify id property? Reconcile AnyProperties, ReactiveObject, HasId, WithId, etc.
|
|
100
100
|
- [ ] Can we us S.is(MyType) to detect objects with our types system? (Branding?)
|
|
101
101
|
- [ ] Type.Expando doesn't work with AtomQuery result type (have to use Obj.Any instead).
|
|
102
|
-
- [ ] Obj.Any doesn't work with Obj.
|
|
102
|
+
- [ ] Obj.Any doesn't work with Obj.update callback types (have to use `any` for the mutable parameter).
|
|
@@ -48,7 +48,7 @@ export const getKeys = (entity: AnyProperties, source: string): ForeignKey[] =>
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Delete all keys from the entity for the specified source.
|
|
51
|
-
* Must be called within an Obj.
|
|
51
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
52
52
|
*/
|
|
53
53
|
export const deleteKeys = (entity: Mutable<AnyProperties>, source: string) => {
|
|
54
54
|
const meta = getMetaChecked(entity);
|
|
@@ -62,7 +62,7 @@ export const deleteKeys = (entity: Mutable<AnyProperties>, source: string) => {
|
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Add a tag to the entity.
|
|
65
|
-
* Must be called within an Obj.
|
|
65
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
66
66
|
*/
|
|
67
67
|
export const addTag = (entity: Mutable<AnyProperties>, tag: string) => {
|
|
68
68
|
const meta = getMetaChecked(entity);
|
|
@@ -72,7 +72,7 @@ export const addTag = (entity: Mutable<AnyProperties>, tag: string) => {
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Remove a tag from the entity.
|
|
75
|
-
* Must be called within an Obj.
|
|
75
|
+
* Must be called within an Obj.update or Relation.update callback.
|
|
76
76
|
*/
|
|
77
77
|
export const removeTag = (entity: Mutable<AnyProperties>, tag: string) => {
|
|
78
78
|
const meta = getMetaChecked(entity);
|
|
@@ -35,7 +35,7 @@ const pendingOwnerNotifications = new Set<object>();
|
|
|
35
35
|
/**
|
|
36
36
|
* Enter a change context for the given key.
|
|
37
37
|
* While in a change context, mutations are allowed on the associated object.
|
|
38
|
-
* Nested Obj.
|
|
38
|
+
* Nested Obj.update calls are not supported.
|
|
39
39
|
*
|
|
40
40
|
* @param key - The key to enter the change context for (target object or ObjectCore).
|
|
41
41
|
* @returns A cleanup function that exits the change context.
|