@dxos/echo 0.9.0 → 0.9.1-staging.ee54ba693a
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 +30 -8
- package/dist/lib/neutral/Database.mjs +7 -3
- package/dist/lib/neutral/Entity.mjs +15 -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 +19 -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-QQIYS74I.mjs → chunk-3KTE2Y7Q.mjs} +20 -20
- package/dist/lib/neutral/chunk-3KTE2Y7Q.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-R5W6DXR4.mjs → chunk-3TN2VMI4.mjs} +72 -36
- package/dist/lib/neutral/chunk-3TN2VMI4.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-5SMDBFVB.mjs → chunk-42L4HJ3Z.mjs} +11 -15
- package/dist/lib/neutral/chunk-42L4HJ3Z.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-7PI7C4EF.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-SBVFRTST.mjs → chunk-BEFR7LEA.mjs} +20 -10
- package/dist/lib/neutral/chunk-BEFR7LEA.mjs.map +7 -0
- 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-UUP46KUQ.mjs → chunk-C57XMMBY.mjs} +21 -20
- package/dist/lib/neutral/chunk-C57XMMBY.mjs.map +7 -0
- package/dist/lib/neutral/chunk-C62JYFAD.mjs +183 -0
- package/dist/lib/neutral/chunk-C62JYFAD.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-MZ7K3MLL.mjs → chunk-FSGX2R62.mjs} +3 -3
- package/dist/lib/neutral/chunk-FSGX2R62.mjs.map +7 -0
- package/dist/lib/neutral/{chunk-TYGKCRMK.mjs → chunk-HBXT3GSB.mjs} +37 -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-WTQJHC75.mjs → chunk-L3E5IXAE.mjs} +225 -45
- 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-6YDI3J37.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-RIVWNMSF.mjs → chunk-U53LSQQA.mjs} +3 -3
- package/dist/lib/neutral/{chunk-RIVWNMSF.mjs.map → chunk-U53LSQQA.mjs.map} +1 -1
- package/dist/lib/neutral/{chunk-IGK6FN65.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-LWXVKPPW.mjs → chunk-UZHCQ6NI.mjs} +13 -11
- package/dist/lib/neutral/{chunk-LWXVKPPW.mjs.map → chunk-UZHCQ6NI.mjs.map} +3 -3
- package/dist/lib/neutral/{chunk-5SUJPHAE.mjs → chunk-WKIT2YY5.mjs} +2 -2
- package/dist/lib/neutral/{chunk-T6E37YIP.mjs → chunk-XB6ISRAO.mjs} +38 -18
- 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-ZGNNFYHS.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 +111 -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 +38 -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/Entity.d.ts +2 -0
- package/dist/types/src/Entity.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 +59 -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 +33 -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 +10 -6
- 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 +38 -21
- 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 +50 -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 +12 -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/index.d.ts +1 -0
- package/dist/types/src/internal/Ref/index.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/ref.d.ts +79 -8
- package/dist/types/src/internal/Ref/ref.d.ts.map +1 -1
- package/dist/types/src/internal/Ref/strong-deps.d.ts +35 -0
- package/dist/types/src/internal/Ref/strong-deps.d.ts.map +1 -0
- 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 +58 -4
- package/src/Collection.ts +10 -12
- package/src/Database.ts +55 -21
- package/src/Entity.ts +3 -1
- package/src/Err.ts +22 -0
- package/src/Feed.ts +117 -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 +38 -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 +14 -6
- package/src/Registry.ts +1 -1
- package/src/Relation.ts +1 -1
- package/src/Tag.ts +13 -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 +85 -33
- package/src/View.ts +22 -30
- package/src/index.ts +1 -1
- package/src/internal/Annotation/annotations.ts +71 -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 +62 -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 +4 -4
- 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/index.ts +1 -0
- package/src/internal/Ref/ref.test.ts +8 -8
- package/src/internal/Ref/ref.ts +122 -39
- package/src/internal/Ref/strong-deps.ts +107 -0
- 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-3PBP4V4O.mjs +0 -101
- package/dist/lib/neutral/chunk-3PBP4V4O.mjs.map +0 -7
- package/dist/lib/neutral/chunk-4ZUHOTCG.mjs +0 -184
- package/dist/lib/neutral/chunk-4ZUHOTCG.mjs.map +0 -7
- package/dist/lib/neutral/chunk-5SMDBFVB.mjs.map +0 -7
- package/dist/lib/neutral/chunk-6YDI3J37.mjs.map +0 -7
- package/dist/lib/neutral/chunk-7FPIAJIV.mjs +0 -2279
- package/dist/lib/neutral/chunk-7FPIAJIV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-BBFJWWAV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-EVK6XBXO.mjs.map +0 -7
- package/dist/lib/neutral/chunk-MZ7K3MLL.mjs.map +0 -7
- package/dist/lib/neutral/chunk-O6BH7EPN.mjs.map +0 -7
- package/dist/lib/neutral/chunk-QQIYS74I.mjs.map +0 -7
- package/dist/lib/neutral/chunk-R5W6DXR4.mjs.map +0 -7
- package/dist/lib/neutral/chunk-SBVFRTST.mjs.map +0 -7
- package/dist/lib/neutral/chunk-T6E37YIP.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TFEWTY5A.mjs.map +0 -7
- package/dist/lib/neutral/chunk-TYGKCRMK.mjs.map +0 -7
- package/dist/lib/neutral/chunk-UUP46KUQ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WTQJHC75.mjs.map +0 -7
- package/dist/lib/neutral/chunk-WU3GIANS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-ZGNNFYHS.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-7PI7C4EF.mjs.map → chunk-4A2NWKRJ.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-IGK6FN65.mjs.map → chunk-UGFFV2FR.mjs.map} +0 -0
- /package/dist/lib/neutral/{chunk-5SUJPHAE.mjs.map → chunk-WKIT2YY5.mjs.map} +0 -0
package/src/index.ts
CHANGED
|
@@ -8,7 +8,6 @@ export { DXN, EID, URI } from '@dxos/keys';
|
|
|
8
8
|
export * as Annotation from './Annotation';
|
|
9
9
|
export * as Database from './Database';
|
|
10
10
|
export * as Entity from './Entity';
|
|
11
|
-
// TODO(burdon): Rename to Error (less problematic than Obj/Object).
|
|
12
11
|
export * as Err from './Err';
|
|
13
12
|
export * as Feed from './Feed';
|
|
14
13
|
export * as Filter from './Filter';
|
|
@@ -27,6 +26,7 @@ export * as Registry from './Registry';
|
|
|
27
26
|
export * as Relation from './Relation';
|
|
28
27
|
export * as Scope from './Scope';
|
|
29
28
|
export * as Tag from './Tag';
|
|
29
|
+
export * as Text from './Text';
|
|
30
30
|
export * as Type from './Type';
|
|
31
31
|
export * as Collection from './Collection';
|
|
32
32
|
export * as View from './View';
|
|
@@ -395,8 +395,11 @@ export const setDescriptionWithSchema = <S extends Schema.Schema.Any>(
|
|
|
395
395
|
object: Schema.Schema.Type<S>,
|
|
396
396
|
description: string,
|
|
397
397
|
) => {
|
|
398
|
-
const
|
|
399
|
-
|
|
398
|
+
const accessorOpt = DescriptionAnnotation.get(schema);
|
|
399
|
+
if (Option.isNone(accessorOpt)) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
object[accessorOpt.value] = description;
|
|
400
403
|
};
|
|
401
404
|
|
|
402
405
|
/**
|
|
@@ -413,6 +416,57 @@ export const FormInputAnnotation = createAnnotationHelper<boolean>(FormInputAnno
|
|
|
413
416
|
export const FormInlineAnnotationId = Symbol.for('@dxos/schema/annotation/FormInline');
|
|
414
417
|
export const FormInlineAnnotation = createAnnotationHelper<boolean>(FormInlineAnnotationId);
|
|
415
418
|
|
|
419
|
+
/**
|
|
420
|
+
* When set on a `Ref` (or array-of-`Ref`) property, the form OWNS the referenced target(s): "add" creates a
|
|
421
|
+
* new object of the annotation's typename (instead of opening the existing-object picker) and each target is
|
|
422
|
+
* rendered inline — its own fields — like {@link FormInlineAnnotation}. The target typename is carried here
|
|
423
|
+
* (rather than inferred from the element type) so the field can stay `Ref.Ref(Obj.Unknown)` and avoid pulling
|
|
424
|
+
* the target's type (e.g. query-AST-laden `Trigger`) into the schema's emitted declaration.
|
|
425
|
+
*/
|
|
426
|
+
export const FormCreateAnnotationId = Symbol.for('@dxos/schema/annotation/FormCreate');
|
|
427
|
+
export const FormCreateAnnotation = createAnnotationHelper<string>(FormCreateAnnotationId);
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* When set on an array property, the form renders it as an ordered,
|
|
431
|
+
* drag-to-reorder list (drag handles per row). Element order is meaningful and
|
|
432
|
+
* user-controllable; reordering rewrites the array.
|
|
433
|
+
*/
|
|
434
|
+
export const FormOrderedAnnotationId = Symbol.for('@dxos/schema/annotation/FormOrdered');
|
|
435
|
+
export const FormOrderedAnnotation = createAnnotationHelper<boolean>(FormOrderedAnnotationId);
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Annotation carrying one or more named layout DSL templates that control how a
|
|
439
|
+
* form arranges a schema's fields (consumed by `@dxos/react-ui-form`'s
|
|
440
|
+
* `Form.Layout` / `Form.FieldSet`). Callers select a variant by name; the
|
|
441
|
+
* implicit name is `DEFAULT_LAYOUT_NAME` (`'default'`).
|
|
442
|
+
*
|
|
443
|
+
* Templates use a minimal XML grammar. Example:
|
|
444
|
+
*
|
|
445
|
+
* FormLayoutAnnotation.set({
|
|
446
|
+
* default: `
|
|
447
|
+
* <grid cols="2">
|
|
448
|
+
* <field name="origin"/>
|
|
449
|
+
* <field name="destination"/>
|
|
450
|
+
* <field name="provider" span="2"/>
|
|
451
|
+
* </grid>
|
|
452
|
+
* `,
|
|
453
|
+
* card: `
|
|
454
|
+
* <grid cols="1">
|
|
455
|
+
* <field name="provider"/>
|
|
456
|
+
* <field name="number"/>
|
|
457
|
+
* </grid>
|
|
458
|
+
* `,
|
|
459
|
+
* })
|
|
460
|
+
*/
|
|
461
|
+
export const FormLayoutAnnotationId = Symbol.for('@dxos/react-ui-form/annotation/Layout');
|
|
462
|
+
|
|
463
|
+
export type FormLayoutMap = Record<string, string>;
|
|
464
|
+
|
|
465
|
+
export const FormLayoutAnnotation = createAnnotationHelper<FormLayoutMap>(FormLayoutAnnotationId);
|
|
466
|
+
|
|
467
|
+
/** Name used when no explicit form-layout variant is requested. */
|
|
468
|
+
export const DEFAULT_LAYOUT_NAME = 'default';
|
|
469
|
+
|
|
416
470
|
/**
|
|
417
471
|
* Default field to be used on referenced schema to lookup the value.
|
|
418
472
|
*/
|
|
@@ -557,6 +611,21 @@ export const setLabel = (entity: Mutable<AnyProperties>, label: string) => {
|
|
|
557
611
|
}
|
|
558
612
|
};
|
|
559
613
|
|
|
614
|
+
/**
|
|
615
|
+
* Returns the primary label property key for an entity.
|
|
616
|
+
* Reads the first accessor from {@link LabelAnnotation}, defaulting to 'name'.
|
|
617
|
+
*/
|
|
618
|
+
export const getLabelProperty = (entity: AnyProperties): string => {
|
|
619
|
+
const schema = getSchema(entity);
|
|
620
|
+
if (schema == null) {
|
|
621
|
+
return 'name';
|
|
622
|
+
}
|
|
623
|
+
return LabelAnnotation.get(schema).pipe(
|
|
624
|
+
Option.flatMap((fields) => Option.fromNullable(fields[0])),
|
|
625
|
+
Option.getOrElse(() => 'name'),
|
|
626
|
+
);
|
|
627
|
+
};
|
|
628
|
+
|
|
560
629
|
/**
|
|
561
630
|
* Get the description of an entity.
|
|
562
631
|
* Accepts both reactive entities and snapshots.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import * as Atom from '@effect-atom/atom/Atom';
|
|
6
|
+
import * as Data from 'effect/Data';
|
|
7
|
+
import * as Option from 'effect/Option';
|
|
8
|
+
|
|
9
|
+
import { assertArgument } from '@dxos/invariant';
|
|
10
|
+
|
|
11
|
+
import type * as Annotation from '../../Annotation';
|
|
12
|
+
import type * as Entity from '../../Entity';
|
|
13
|
+
import { snapshotForComparison } from '../common/atom-snapshot';
|
|
14
|
+
import { subscribe } from '../common/proxy/reactive';
|
|
15
|
+
import { isEntity } from '../Entity';
|
|
16
|
+
import { get as getAnnotation } from './entity-dictionary';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Atom family for an annotation value on an entity instance.
|
|
20
|
+
* Mirrors the object-property atom family: re-emits a fresh reference whenever the entity changes
|
|
21
|
+
* (so an in-place array mutation is observed) and dedupes primitive values via `!==`.
|
|
22
|
+
*/
|
|
23
|
+
const annotationFamily = Atom.family((target: Entity.Unknown) =>
|
|
24
|
+
Atom.family(<T>(annotation: Annotation.Annotation<T>): Atom.Atom<Option.Option<T>> => {
|
|
25
|
+
const read = (): Option.Option<T> => Option.map(getAnnotation(target, annotation), snapshotForComparison);
|
|
26
|
+
|
|
27
|
+
return Atom.make<Option.Option<T>>((get) => {
|
|
28
|
+
let previous = read();
|
|
29
|
+
|
|
30
|
+
const unsubscribe = subscribe(target, () => {
|
|
31
|
+
const next = read();
|
|
32
|
+
if (!sameOption(previous, next)) {
|
|
33
|
+
previous = next;
|
|
34
|
+
get.setSelf(next);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
get.addFinalizer(() => unsubscribe());
|
|
38
|
+
|
|
39
|
+
return previous;
|
|
40
|
+
}).pipe(Atom.keepAlive);
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Atom family for a single key of a record-valued annotation on an entity instance.
|
|
46
|
+
* Keyed by a value-equal `Data.tuple([target, annotation, key])` so nested families are avoided.
|
|
47
|
+
*/
|
|
48
|
+
const annotationPropertyFamily = Atom.family(
|
|
49
|
+
([target, annotation, key]: readonly [
|
|
50
|
+
Entity.Unknown,
|
|
51
|
+
Annotation.Annotation<Record<string, any>>,
|
|
52
|
+
string,
|
|
53
|
+
]): Atom.Atom<any> => {
|
|
54
|
+
const read = (): unknown =>
|
|
55
|
+
getAnnotation(target, annotation).pipe(
|
|
56
|
+
Option.map((value) => snapshotForComparison(value[key])),
|
|
57
|
+
Option.getOrUndefined,
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return Atom.make<unknown>((get) => {
|
|
61
|
+
let previous = read();
|
|
62
|
+
|
|
63
|
+
const unsubscribe = subscribe(target, () => {
|
|
64
|
+
const next = read();
|
|
65
|
+
if (next !== previous) {
|
|
66
|
+
previous = next;
|
|
67
|
+
get.setSelf(next);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
get.addFinalizer(() => unsubscribe());
|
|
71
|
+
|
|
72
|
+
return previous;
|
|
73
|
+
}).pipe(Atom.keepAlive);
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
/** Equal when both empty, or both present with the same (snapshotted) value. */
|
|
78
|
+
const sameOption = <T>(a: Option.Option<T>, b: Option.Option<T>): boolean =>
|
|
79
|
+
Option.isNone(a) || Option.isNone(b) ? Option.isNone(a) && Option.isNone(b) : a.value === b.value;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Reactive atom for an annotation value on an entity instance. Emits a shallow snapshot (a fresh
|
|
83
|
+
* reference for objects/arrays) so dependent atoms recompute on change. Mirrors {@link makeProperty}.
|
|
84
|
+
*/
|
|
85
|
+
export const makeAtom = <T>(
|
|
86
|
+
target: Entity.Unknown,
|
|
87
|
+
annotation: Annotation.Annotation<T>,
|
|
88
|
+
): Atom.Atom<Option.Option<T>> => {
|
|
89
|
+
assertArgument(isEntity(target), 'target', 'Must be a reactive ECHO entity');
|
|
90
|
+
return annotationFamily(target)(annotation);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Reactive atom for a single key of a record-valued annotation on an entity instance.
|
|
95
|
+
*/
|
|
96
|
+
export const makeProperty = <V>(
|
|
97
|
+
target: Entity.Unknown,
|
|
98
|
+
annotation: Annotation.Annotation<Record<string, V>>,
|
|
99
|
+
key: string,
|
|
100
|
+
): Atom.Atom<V | undefined> => {
|
|
101
|
+
assertArgument(isEntity(target), 'target', 'Must be a reactive ECHO entity');
|
|
102
|
+
// The flattened family key is a single concrete tuple type, so the generic `V` is erased at the
|
|
103
|
+
// family boundary and recovered here; no typed alternative exists for a per-call-generic family.
|
|
104
|
+
return annotationPropertyFamily(
|
|
105
|
+
Data.tuple(target, annotation as Annotation.Annotation<Record<string, any>>, key),
|
|
106
|
+
) as Atom.Atom<V | undefined>;
|
|
107
|
+
};
|
|
@@ -3,72 +3,75 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import * as Option from 'effect/Option';
|
|
6
|
-
|
|
7
|
-
import { deepMapValues } from '@dxos/util';
|
|
6
|
+
import * as Schema from 'effect/Schema';
|
|
8
7
|
|
|
9
8
|
import type * as Annotation from '../../Annotation';
|
|
10
9
|
import type * as Entity from '../../Entity';
|
|
11
10
|
import { getMetaChecked } from '../common/api/meta';
|
|
12
|
-
import { type Mutable } from '../common/proxy/reactive';
|
|
13
|
-
import { getDatabase } from '../Entity/api';
|
|
11
|
+
import { type Mutable, change } from '../common/proxy/reactive';
|
|
14
12
|
import { isEntity, isSnapshot } from '../Entity/guard';
|
|
15
|
-
import {
|
|
16
|
-
import { getDictionary, setDictionary } from './dictionary';
|
|
13
|
+
import { getDictionary } from './dictionary';
|
|
17
14
|
|
|
18
15
|
/**
|
|
19
16
|
* Get the value of an annotation from an entity instance or snapshot.
|
|
17
|
+
*
|
|
18
|
+
* The value is read-only (schema types are readonly by default). To mutate it, use {@link update}
|
|
19
|
+
* (which reads it as mutable inside a change transaction); the reactive proxy rejects mutation of the
|
|
20
|
+
* live value outside an `Obj.update`. Snapshots return a decoded detached copy.
|
|
20
21
|
*/
|
|
21
22
|
export const get = <T>(
|
|
22
23
|
target: Entity.Unknown | Entity.Snapshot,
|
|
23
24
|
annotation: Annotation.Annotation<T>,
|
|
24
25
|
): Option.Option<T> => {
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
if (isSnapshot(target)) {
|
|
27
|
+
return getDictionary(getMetaChecked(target).annotations, annotation);
|
|
28
|
+
}
|
|
29
|
+
if (isEntity(target)) {
|
|
30
|
+
const annotations = getMetaChecked(target).annotations;
|
|
31
|
+
// The dictionary slot is typed `unknown`; at runtime it holds the annotation's live value
|
|
32
|
+
// (the proxy codecs nested refs in both directions), so the read coerces to the declared type.
|
|
33
|
+
return annotation.key in annotations ? Option.some(annotations[annotation.key] as T) : Option.none();
|
|
30
34
|
}
|
|
35
|
+
throw new TypeError('Target is not an annotation target.');
|
|
31
36
|
};
|
|
32
37
|
|
|
33
38
|
/**
|
|
34
39
|
* Set the value of an annotation on an entity instance.
|
|
35
40
|
* Must be called with a mutable entity — i.e. inside an `Obj.update` callback.
|
|
41
|
+
*
|
|
42
|
+
* The value is assigned directly to the reactive meta dictionary; the proxy encodes nested Refs and
|
|
43
|
+
* links their unsaved targets on write (matching ordinary property assignment), so no manual
|
|
44
|
+
* encode/persist step is needed.
|
|
36
45
|
*/
|
|
37
46
|
export const set = <T>(target: Mutable<Entity.Unknown>, annotation: Annotation.Annotation<T>, value: T): void => {
|
|
38
47
|
if (isEntity(target)) {
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// `database.add`. `setDictionary` pre-encodes the value (`Schema.encodeSync`),
|
|
44
|
-
// so the live Ref never reaches the proxy's link handling and would otherwise
|
|
45
|
-
// be stored as a dangling reference.
|
|
46
|
-
persistRefTargets(target, value);
|
|
47
|
-
setDictionary(meta.annotations, annotation, value);
|
|
48
|
+
// The dictionary slot is untyped, so the proxy can't validate against the annotation schema;
|
|
49
|
+
// validate here (without encoding — the proxy encodes nested refs and links targets on assignment).
|
|
50
|
+
Schema.validateSync(annotation.schema)(value);
|
|
51
|
+
getMetaChecked(target).annotations[annotation.key] = value;
|
|
48
52
|
} else {
|
|
49
53
|
throw new TypeError('Target is not an annotation target.');
|
|
50
54
|
}
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* already lives in a database (the host's or a foreign one) are left untouched.
|
|
58
|
+
* Mutate an existing annotation value in place via a callback, wrapping the mutation in a change
|
|
59
|
+
* transaction (like `Obj.update`). Use when only an annotation needs to change. No-op when absent.
|
|
57
60
|
*/
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
export const update = <T>(
|
|
62
|
+
target: Entity.Unknown,
|
|
63
|
+
annotation: Annotation.Annotation<T>,
|
|
64
|
+
mutator: (value: Mutable<T>) => void,
|
|
65
|
+
): void => {
|
|
66
|
+
change(target, (mutable) => {
|
|
67
|
+
const current = get(mutable, annotation);
|
|
68
|
+
if (Option.isSome(current)) {
|
|
69
|
+
// `get` returns the value read-only; inside this change transaction the live value is mutable.
|
|
70
|
+
const value = current.value as Mutable<T>;
|
|
71
|
+
mutator(value);
|
|
72
|
+
// Validate against the annotation's own schema — the dictionary slot is untyped, so the proxy
|
|
73
|
+
// can't. Schema validation checks ref structure only (not targets), so it is cycle-safe.
|
|
74
|
+
Schema.validateSync(annotation.schema)(value);
|
|
71
75
|
}
|
|
72
|
-
return recurse(current);
|
|
73
76
|
});
|
|
74
77
|
};
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { invariant } from '@dxos/invariant';
|
|
6
|
-
import { DXN, EID,
|
|
6
|
+
import { DXN, EID, type SpaceId, URI } from '@dxos/keys';
|
|
7
7
|
import { assumeType } from '@dxos/util';
|
|
8
8
|
|
|
9
9
|
import type { AnyEntity } from '../common/types';
|
|
@@ -9,7 +9,8 @@ import { KindId, SnapshotKindId } from '../common/types';
|
|
|
9
9
|
* Returns true if the value is an ECHO entity instance (object or relation).
|
|
10
10
|
*/
|
|
11
11
|
export const isEntity = (value: unknown): value is Entity.Unknown => {
|
|
12
|
-
|
|
12
|
+
// (some) type entities are functions since they are class declarations.
|
|
13
|
+
if (value == null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
15
16
|
return (value as any)[KindId] !== undefined;
|
|
@@ -11,13 +11,13 @@ import { assumeType } from '@dxos/util';
|
|
|
11
11
|
|
|
12
12
|
import type * as Database from '../../Database';
|
|
13
13
|
import {
|
|
14
|
-
type ATTR_PARENT,
|
|
15
|
-
type ATTR_TYPE,
|
|
16
14
|
ATTR_DELETED,
|
|
15
|
+
type ATTR_PARENT,
|
|
17
16
|
ATTR_RELATION_SOURCE,
|
|
18
17
|
ATTR_RELATION_TARGET,
|
|
19
18
|
ATTR_SELF_URI,
|
|
20
19
|
ATTR_SELF_URI_LEGACY,
|
|
20
|
+
type ATTR_TYPE,
|
|
21
21
|
EntityKind,
|
|
22
22
|
KindId,
|
|
23
23
|
ObjectDatabaseId,
|
|
@@ -6,8 +6,9 @@ import * as Schema from 'effect/Schema';
|
|
|
6
6
|
import * as SchemaAST from 'effect/SchemaAST';
|
|
7
7
|
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
|
-
import { DXN } from '@dxos/keys';
|
|
9
|
+
import { DXN, type EntityId } from '@dxos/keys';
|
|
10
10
|
|
|
11
|
+
import type * as Type from '../../Type';
|
|
11
12
|
import { type TypeAnnotation, TypeAnnotationId } from '../Annotation/annotations';
|
|
12
13
|
import { makeTypeJsonSchemaAnnotation } from '../Annotation/util';
|
|
13
14
|
import { EntityKind } from '../common/types';
|
|
@@ -71,3 +72,15 @@ export const EchoObjectSchema: {
|
|
|
71
72
|
);
|
|
72
73
|
};
|
|
73
74
|
};
|
|
75
|
+
|
|
76
|
+
export const makeObjectType = <Self, _Schema extends Schema.Schema.Any>(
|
|
77
|
+
dxn: DXN.DXN,
|
|
78
|
+
schema: _Schema,
|
|
79
|
+
options?: { id?: EntityId },
|
|
80
|
+
): Type.ObjClass<Self, Schema.Schema.Type<_Schema>, {}> => {
|
|
81
|
+
const type = EchoObjectSchema(dxn, options)(schema);
|
|
82
|
+
const constructor = function ObjectType() {};
|
|
83
|
+
Object.setPrototypeOf(constructor, type);
|
|
84
|
+
// Boundary cast: constructor/prototype wiring cannot be expressed in TypeScript's type system.
|
|
85
|
+
return constructor as unknown as Type.ObjClass<Self, Schema.Schema.Type<_Schema>, {}>;
|
|
86
|
+
};
|
|
@@ -186,3 +186,22 @@ export const getDXNForRelationSchemaRef = (schema: Schema.Schema.Any): DXN.DXN =
|
|
|
186
186
|
|
|
187
187
|
return DXN.make(typename);
|
|
188
188
|
};
|
|
189
|
+
|
|
190
|
+
export const makeRelationType = (options: {
|
|
191
|
+
dxn: DXN.DXN;
|
|
192
|
+
source: RelationEndpoint;
|
|
193
|
+
target: RelationEndpoint;
|
|
194
|
+
schema: Schema.Schema.Any;
|
|
195
|
+
id?: EntityId;
|
|
196
|
+
}): Type.RelationClass<unknown, unknown, unknown, unknown, {}> => {
|
|
197
|
+
const type = EchoRelationSchema({
|
|
198
|
+
dxn: options.dxn,
|
|
199
|
+
source: options.source,
|
|
200
|
+
target: options.target,
|
|
201
|
+
id: options.id,
|
|
202
|
+
})(options.schema);
|
|
203
|
+
const constructor = function RelationType() {};
|
|
204
|
+
Object.setPrototypeOf(constructor, type);
|
|
205
|
+
// Boundary cast: constructor/prototype wiring cannot be expressed in TypeScript's type system.
|
|
206
|
+
return constructor as unknown as Type.RelationClass<unknown, unknown, unknown, unknown, {}>;
|
|
207
|
+
};
|
|
@@ -23,7 +23,9 @@ export const getTypeURIFromSpecifier = (input: Schema.Schema.All | AnyEntity | U
|
|
|
23
23
|
if (Schema.isSchema(input)) {
|
|
24
24
|
return getSchemaURI(input) ?? raise(new TypeError('Schema has no URI'));
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
// Type entities are normally proxy objects, but class-declared types from
|
|
27
|
+
// `Type.makeObject` are functions whose prototype chain reaches the entity, so accept functions too.
|
|
28
|
+
if (input !== null && (typeof input === 'object' || typeof input === 'function') && KindId in input) {
|
|
27
29
|
// `Type.Type` entity. Both in-memory and persisted forms expose the schema
|
|
28
30
|
// they declare via `StaticTypeSchemaSlot`, whose URI is exactly what
|
|
29
31
|
// `Obj.make` stamps on `system.type` — a static declaration carries
|