@dxos/app-graph 0.7.5-main.499c70c → 0.7.5-main.5ae2ba8
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/browser/index.mjs +71 -23
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +69 -20
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +71 -23
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/graph-builder.d.ts +19 -3
- package/dist/types/src/graph-builder.d.ts.map +1 -1
- package/dist/types/src/graph.d.ts.map +1 -1
- package/dist/types/src/node.d.ts +2 -2
- package/dist/types/src/node.d.ts.map +1 -1
- package/dist/types/src/stories/EchoGraph.stories.d.ts +2 -3
- package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -16
- package/src/graph-builder.test.ts +36 -0
- package/src/graph-builder.ts +54 -19
- package/src/graph.ts +4 -4
- package/src/node.ts +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MaybePromise } from '@dxos/util';
|
|
1
|
+
import { type Position, type MaybePromise } from '@dxos/util';
|
|
2
2
|
import { Graph, type GraphParams } from './graph';
|
|
3
3
|
import { type ActionData, actionGroupSymbol, type Node, type NodeArg, type Relation } from './node';
|
|
4
4
|
/**
|
|
@@ -37,6 +37,7 @@ type GuardedNodeType<T> = T extends (value: any) => value is infer N ? (N extend
|
|
|
37
37
|
* @param params.id The unique id of the extension.
|
|
38
38
|
* @param params.relation The relation the graph is being expanded from the existing node.
|
|
39
39
|
* @param params.type If provided, all nodes returned are expected to have this type.
|
|
40
|
+
* @param params.disposition Affects the order the extensions are processed in.
|
|
40
41
|
* @param params.filter A filter function to determine if an extension should act on a node.
|
|
41
42
|
* @param params.resolver A function to add nodes to the graph based on just the node id.
|
|
42
43
|
* @param params.connector A function to add nodes to the graph based on a connection to an existing node.
|
|
@@ -47,6 +48,7 @@ export type CreateExtensionOptions<T = any> = {
|
|
|
47
48
|
id: string;
|
|
48
49
|
relation?: Relation;
|
|
49
50
|
type?: string;
|
|
51
|
+
position?: Position;
|
|
50
52
|
filter?: (node: Node) => node is Node<T>;
|
|
51
53
|
resolver?: ResolverExtension;
|
|
52
54
|
connector?: ConnectorExtension<GuardedNodeType<CreateExtensionOptions<T>['filter']>>;
|
|
@@ -75,15 +77,17 @@ export declare const cleanup: (fn: () => void) => void;
|
|
|
75
77
|
* Convert a subscribe/get pair into a signal.
|
|
76
78
|
*/
|
|
77
79
|
export declare const toSignal: <T>(subscribe: (onChange: () => void) => () => void, get: () => T | undefined, key?: string) => T | undefined;
|
|
78
|
-
export type BuilderExtension = {
|
|
80
|
+
export type BuilderExtension = Readonly<{
|
|
79
81
|
id: string;
|
|
82
|
+
position: Position;
|
|
80
83
|
resolver?: ResolverExtension;
|
|
81
84
|
connector?: ConnectorExtension;
|
|
82
85
|
relation?: Relation;
|
|
83
86
|
type?: string;
|
|
84
87
|
filter?: (node: Node) => boolean;
|
|
85
|
-
}
|
|
88
|
+
}>;
|
|
86
89
|
type ExtensionArg = BuilderExtension | BuilderExtension[] | ExtensionArg[];
|
|
90
|
+
export declare const flattenExtensions: (extension: ExtensionArg, acc?: BuilderExtension[]) => BuilderExtension[];
|
|
87
91
|
/**
|
|
88
92
|
* The builder provides an extensible way to compose the construction of the graph.
|
|
89
93
|
*/
|
|
@@ -104,6 +108,18 @@ export declare class GraphBuilder {
|
|
|
104
108
|
*/
|
|
105
109
|
initialize(): Promise<void>;
|
|
106
110
|
get graph(): Graph;
|
|
111
|
+
/**
|
|
112
|
+
* @reactive
|
|
113
|
+
*/
|
|
114
|
+
get extensions(): Readonly<{
|
|
115
|
+
id: string;
|
|
116
|
+
position: Position;
|
|
117
|
+
resolver?: ResolverExtension;
|
|
118
|
+
connector?: ConnectorExtension;
|
|
119
|
+
relation?: Relation;
|
|
120
|
+
type?: string;
|
|
121
|
+
filter?: (node: Node) => boolean;
|
|
122
|
+
}>[];
|
|
107
123
|
/**
|
|
108
124
|
* Register a node builder which will be called in order to construct the graph.
|
|
109
125
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-builder.d.ts","sourceRoot":"","sources":["../../../src/graph-builder.ts"],"names":[],"mappings":"AAUA,OAAO,EAAU,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"graph-builder.d.ts","sourceRoot":"","sources":["../../../src/graph-builder.ts"],"names":[],"mappings":"AAUA,OAAO,EAAc,KAAK,QAAQ,EAAU,KAAK,YAAY,EAAiB,MAAM,YAAY,CAAC;AAEjG,OAAO,EAAkC,KAAK,EAAW,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3F,OAAO,EAAE,KAAK,UAAU,EAAE,iBAAiB,EAAE,KAAK,IAAI,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIpG;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC;AAE7F;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;CAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC;AAEpG;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;IAC/C,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;CACf,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;AAE1E;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;IACpD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;CACf,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,EAAE,GAAG,SAAS,CAAC;AAEjG,KAAK,eAAe,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,KAAK,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC;AAEvH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,GAAG,GAAG,IAAI;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,EAAE,gBAAgB,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjF,YAAY,CAAC,EAAE,qBAAqB,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CAC5F,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,mBAAmB,sBAAsB,CAAC,CAAC,CAAC,KAAG,gBAAgB,EA4B/F,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACtE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAkBF;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,MAAM,MAAM,CAAC,mBAAmB,CASxD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,OAAQ,MAAM,IAAI,KAAG,IAMxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,aACb,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,OAC1C,MAAM,CAAC,GAAG,SAAS,QAClB,MAAM,kBAYb,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAE/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;CAClC,CAAC,CAAC;AAEH,KAAK,YAAY,GAAG,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,YAAY,EAAE,CAAC;AAE3E,eAAO,MAAM,iBAAiB,cAAe,YAAY,QAAO,gBAAgB,EAAE,KAAQ,gBAAgB,EAMzG,CAAC;AAEF;;GAEG;AAIH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgD;IAC5E,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAA0C;IACjF,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAA0C;IAClF,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;IAC5D,OAAO,CAAC,MAAM,CAAQ;gBAEV,MAAM,GAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAM;IAS7D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM;IAS3B;;;;OAIG;IACG,UAAU;IAiBhB,IAAI,KAAK,UAER;IAED;;OAEG;IACH,IAAI,UAAU;YAlFV,MAAM;kBACA,QAAQ;mBACP,iBAAiB;oBAChB,kBAAkB;mBAEnB,QAAQ;eACZ,MAAM;iBACJ,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO;SA6E/B;IAED;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY;IAWnD;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAOzC,OAAO;IAQP;;OAEG;IACG,OAAO,CACX,EAAE,IAAuB,EAAE,QAAqB,EAAE,OAAO,EAAE,EAAE,2BAA2B,EACxF,IAAI,GAAE,MAAM,EAAO;IA0CrB,OAAO,CAAC,cAAc;IA0CtB,OAAO,CAAC,eAAe;YA0ET,aAAa;CAM5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/graph.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/graph.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,YAAY,EAAuB,MAAM,YAAY,CAAC;AAEpE,OAAO,EAAE,KAAK,IAAI,EAAgB,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAmC,MAAM,QAAQ,CAAC;AAMlH,eAAO,MAAM,QAAQ,SAAU,IAAI,KAAG,KAIrC,CAAC;AAEF,eAAO,MAAM,OAAO,SAAS,CAAC;AAC9B,eAAO,MAAM,SAAS,4BAA4B,CAAC;AACnD,eAAO,MAAM,WAAW,8BAA8B,CAAC;AACvD,eAAO,MAAM,iBAAiB,mCAAmC,CAAC;AAElE,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI;IACvF,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAKF,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;IAExD;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IAEZ;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAmE;IACpG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAgC;IAE/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqC;IACtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+B;gBAYhD,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,GAAE,WAAgB;IAoC3F,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAAM;IAK9E;;OAEG;IACH,IAAI,IAAI;;;;;;OAEP;IAED;;OAEG;IACH,MAAM,CAAC,EAAE,EAAY,EAAE,SAAc,EAAE,GAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO;IA2BjF,MAAM;IAwBN;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,UAAO,GAAG,IAAI,GAAG,SAAS;IASxD;;;;;;;OAOG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9D;;OAEG;IACH,KAAK,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAM;;;;;;;IAMhH;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,QAAqB,EAAE,GAAE;QAAE,QAAQ,CAAC,EAAE,QAAQ,CAAA;KAAO;IAIzE;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAO;;;;;;;IAOzD,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAE,QAAqB,EAAE,IAAI,CAAC,EAAE,MAAM;IASvE,OAAO,CAAC,IAAI;IAIZ;;;;;;OAMG;IACH,QAAQ,CACN,EAAE,OAAO,EAAE,IAAgB,EAAE,QAAqB,EAAE,SAAS,EAAE,EAAE,qBAAqB,EACtF,IAAI,GAAE,MAAM,EAAO,GAClB,IAAI;IAgBP;;;;;;OAMG;IACH,iBAAiB,CACf,EAAE,OAAO,EAAE,IAAgB,EAAE,QAAqB,EAAE,SAAS,EAAE,EAAE,qBAAqB,EACtF,WAAW,GAAE,MAAM,EAAO;IAiB5B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAe,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,EAAE,GAAG,SAAS;IAuB/F;;OAEG;IACG,WAAW,CACf,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAC3C,EAAE,OAAe,EAAE,QAAc,EAAE,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAO;IA6BnF,OAAO,CAAC,QAAQ;IAgEhB,OAAO,CAAC,WAAW;IAwCnB,OAAO,CAAC,QAAQ;IA6BhB,OAAO,CAAC,WAAW;IAiCnB;;;;;;;;;OASG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE;IAa9D,OAAO,CAAC,cAAc,CAEpB;IAEF,OAAO,CAAC,SAAS;CAyBlB"}
|
package/dist/types/src/node.d.ts
CHANGED
|
@@ -46,8 +46,8 @@ export type Action<TProperties extends Record<string, any> = Record<string, any>
|
|
|
46
46
|
}>;
|
|
47
47
|
export declare const isAction: (data: unknown) => data is Action;
|
|
48
48
|
export declare const actionGroupSymbol: unique symbol;
|
|
49
|
-
export type ActionGroup = Readonly<Omit<Node<typeof actionGroupSymbol,
|
|
50
|
-
properties: Readonly<
|
|
49
|
+
export type ActionGroup<TProperties extends Record<string, any> = Record<string, any>> = Readonly<Omit<Node<typeof actionGroupSymbol, TProperties>, 'properties'> & {
|
|
50
|
+
properties: Readonly<TProperties>;
|
|
51
51
|
}>;
|
|
52
52
|
export declare const isActionGroup: (data: unknown) => data is ActionGroup;
|
|
53
53
|
export type ActionLike = Action | ActionGroup;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/node.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE;;GAEG;AAGH,MAAM,MAAM,IAAI,CAAC,KAAK,GAAG,GAAG,EAAE,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,QAAQ,CAAC;IACtG;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAElC;;OAEG;IAGH,IAAI,EAAE,KAAK,CAAC;CACb,CAAC,CAAC;AAEH,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CACrF,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EACxC,aAAa,EAAE,IAAI,KAChB,IAAI,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAE9C,eAAO,MAAM,WAAW,SAAU,OAAO,KAAG,IAAI,IAAI,IAGzC,CAAC;AAEZ,MAAM,MAAM,OAAO,CAAC,KAAK,EAAE,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,YAAY,CACtG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,EACxB,MAAM,GAAG,YAAY,GAAG,WAAW,CACpC,GAAG;IACF,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IAE3B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;CAC9B,CAAC;AAMF,MAAM,MAAM,YAAY,GAAG;IACzB,+CAA+C;IAC/C,IAAI,EAAE,IAAI,CAAC;IAEX,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC;AAEtE,MAAM,MAAM,MAAM,CAAC,WAAW,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,QAAQ,CAC1F,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,GAAG;IAClD,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;CACnC,CACF,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,OAAO,KAAG,IAAI,IAAI,MACY,CAAC;AAE9D,eAAO,MAAM,iBAAiB,eAAwB,CAAC;AAEvD,MAAM,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import '@dxos-theme';
|
|
2
|
-
import React from 'react';
|
|
3
2
|
declare const _default: {
|
|
4
3
|
title: string;
|
|
5
|
-
render: () =>
|
|
6
|
-
decorators: import("@storybook/react
|
|
4
|
+
render: () => import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
decorators: import("@storybook/react").Decorator[];
|
|
7
6
|
};
|
|
8
7
|
export default _default;
|
|
9
8
|
export declare const Default: {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EchoGraph.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/EchoGraph.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC
|
|
1
|
+
{"version":3,"file":"EchoGraph.stories.d.ts","sourceRoot":"","sources":["../../../../src/stories/EchoGraph.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,aAAa,CAAC;;;;;;AAuPrB,wBAaE;AAEF,eAAO,MAAM,OAAO,IAAK,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"5.7.
|
|
1
|
+
{"version":"5.7.3"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/app-graph",
|
|
3
|
-
"version": "0.7.5-main.
|
|
3
|
+
"version": "0.7.5-main.5ae2ba8",
|
|
4
4
|
"description": "Constructs knowledge graphs for the purpose of building applications on top of",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": "DXOS.org",
|
|
9
9
|
"sideEffects": true,
|
|
10
|
+
"type": "module",
|
|
10
11
|
"exports": {
|
|
11
12
|
".": {
|
|
12
13
|
"types": "./dist/types/src/index.d.ts",
|
|
@@ -25,14 +26,14 @@
|
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"@preact/signals-core": "^1.6.0",
|
|
27
28
|
"main-thread-scheduling": "^14.1.1",
|
|
28
|
-
"@dxos/async": "0.7.5-main.
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/echo-schema": "0.7.5-main.
|
|
31
|
-
"@dxos/
|
|
32
|
-
"@dxos/invariant": "0.7.5-main.
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/log": "0.7.5-main.
|
|
35
|
-
"@dxos/util": "0.7.5-main.
|
|
29
|
+
"@dxos/async": "0.7.5-main.5ae2ba8",
|
|
30
|
+
"@dxos/debug": "0.7.5-main.5ae2ba8",
|
|
31
|
+
"@dxos/echo-schema": "0.7.5-main.5ae2ba8",
|
|
32
|
+
"@dxos/echo-signals": "0.7.5-main.5ae2ba8",
|
|
33
|
+
"@dxos/invariant": "0.7.5-main.5ae2ba8",
|
|
34
|
+
"@dxos/live-object": "0.7.5-main.5ae2ba8",
|
|
35
|
+
"@dxos/log": "0.7.5-main.5ae2ba8",
|
|
36
|
+
"@dxos/util": "0.7.5-main.5ae2ba8"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
39
|
"@phosphor-icons/react": "^2.1.5",
|
|
@@ -41,18 +42,18 @@
|
|
|
41
42
|
"react": "~18.2.0",
|
|
42
43
|
"react-dom": "~18.2.0",
|
|
43
44
|
"vite": "5.4.7",
|
|
44
|
-
"@dxos/random": "0.7.5-main.
|
|
45
|
-
"@dxos/react-client": "0.7.5-main.
|
|
46
|
-
"@dxos/react-ui
|
|
47
|
-
"@dxos/react-ui": "0.7.5-main.
|
|
48
|
-
"@dxos/storybook-utils": "0.7.5-main.
|
|
45
|
+
"@dxos/random": "0.7.5-main.5ae2ba8",
|
|
46
|
+
"@dxos/react-client": "0.7.5-main.5ae2ba8",
|
|
47
|
+
"@dxos/react-ui": "0.7.5-main.5ae2ba8",
|
|
48
|
+
"@dxos/react-ui-theme": "0.7.5-main.5ae2ba8",
|
|
49
|
+
"@dxos/storybook-utils": "0.7.5-main.5ae2ba8"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
51
52
|
"@phosphor-icons/react": "^2.1.5",
|
|
52
53
|
"react": "~18.2.0",
|
|
53
54
|
"react-dom": "~18.2.0",
|
|
54
|
-
"@dxos/react-ui": "0.7.5-main.
|
|
55
|
-
"@dxos/react-ui-theme": "0.7.5-main.
|
|
55
|
+
"@dxos/react-ui": "0.7.5-main.5ae2ba8",
|
|
56
|
+
"@dxos/react-ui-theme": "0.7.5-main.5ae2ba8"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
import { batch, signal } from '@preact/signals-core';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
|
|
8
|
+
import { updateCounter } from '@dxos/echo-schema/testing';
|
|
9
|
+
|
|
8
10
|
import { ACTION_TYPE, ROOT_ID, ROOT_TYPE } from './graph';
|
|
9
11
|
import { GraphBuilder, createExtension, memoize } from './graph-builder';
|
|
10
12
|
import { type Node } from './node';
|
|
@@ -175,6 +177,40 @@ describe('GraphBuilder', () => {
|
|
|
175
177
|
expect(node.properties.label).to.equal('updated');
|
|
176
178
|
});
|
|
177
179
|
|
|
180
|
+
test('updates with new extensions', async () => {
|
|
181
|
+
const name = signal('default');
|
|
182
|
+
const builder = new GraphBuilder();
|
|
183
|
+
builder.addExtension(
|
|
184
|
+
createExtension({
|
|
185
|
+
id: 'connector',
|
|
186
|
+
connector: () => [{ id: EXAMPLE_ID, type: EXAMPLE_TYPE, data: name, properties: { label: name.value } }],
|
|
187
|
+
}),
|
|
188
|
+
);
|
|
189
|
+
const graph = builder.graph;
|
|
190
|
+
await graph.expand(graph.root);
|
|
191
|
+
|
|
192
|
+
let nodes: Node[] = [];
|
|
193
|
+
using updates = updateCounter(() => {
|
|
194
|
+
nodes = graph.nodes(graph.root);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(updates.count).to.equal(0);
|
|
198
|
+
expect(nodes).has.length(1);
|
|
199
|
+
expect(nodes[0].id).to.equal(EXAMPLE_ID);
|
|
200
|
+
|
|
201
|
+
builder.addExtension(
|
|
202
|
+
createExtension({
|
|
203
|
+
id: 'connector-2',
|
|
204
|
+
connector: () => [{ id: exampleId(2), type: EXAMPLE_TYPE, data: 0 }],
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
expect(updates.count).to.equal(1);
|
|
209
|
+
expect(nodes).has.length(2);
|
|
210
|
+
expect(nodes[0].id).to.equal(EXAMPLE_ID);
|
|
211
|
+
expect(nodes[1].id).to.equal(exampleId(2));
|
|
212
|
+
});
|
|
213
|
+
|
|
178
214
|
test('removes', async () => {
|
|
179
215
|
const nodes = signal([
|
|
180
216
|
{ id: exampleId(1), type: EXAMPLE_TYPE, data: 1 },
|
package/src/graph-builder.ts
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { effect, type Signal, signal } from '@preact/signals-core';
|
|
5
|
+
import { effect, type Signal, signal, untracked } from '@preact/signals-core';
|
|
6
6
|
|
|
7
7
|
import { Trigger, type UnsubscribeCallback } from '@dxos/async';
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { create } from '@dxos/live-object';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
|
-
import { isNode, type MaybePromise,
|
|
11
|
+
import { byPosition, type Position, isNode, type MaybePromise, isNonNullable } from '@dxos/util';
|
|
12
12
|
|
|
13
13
|
import { ACTION_GROUP_TYPE, ACTION_TYPE, Graph, ROOT_ID, type GraphParams } from './graph';
|
|
14
14
|
import { type ActionData, actionGroupSymbol, type Node, type NodeArg, type Relation } from './node';
|
|
15
15
|
|
|
16
|
+
const NODE_RESOLVER_TIMEOUT = 1_000;
|
|
17
|
+
|
|
16
18
|
/**
|
|
17
19
|
* Graph builder extension for adding nodes to the graph based on just the node id.
|
|
18
20
|
* This is useful for creating the first node in a graph or for hydrating cached nodes with data.
|
|
@@ -50,6 +52,7 @@ type GuardedNodeType<T> = T extends (value: any) => value is infer N ? (N extend
|
|
|
50
52
|
* @param params.id The unique id of the extension.
|
|
51
53
|
* @param params.relation The relation the graph is being expanded from the existing node.
|
|
52
54
|
* @param params.type If provided, all nodes returned are expected to have this type.
|
|
55
|
+
* @param params.disposition Affects the order the extensions are processed in.
|
|
53
56
|
* @param params.filter A filter function to determine if an extension should act on a node.
|
|
54
57
|
* @param params.resolver A function to add nodes to the graph based on just the node id.
|
|
55
58
|
* @param params.connector A function to add nodes to the graph based on a connection to an existing node.
|
|
@@ -60,6 +63,7 @@ export type CreateExtensionOptions<T = any> = {
|
|
|
60
63
|
id: string;
|
|
61
64
|
relation?: Relation;
|
|
62
65
|
type?: string;
|
|
66
|
+
position?: Position;
|
|
63
67
|
filter?: (node: Node) => node is Node<T>;
|
|
64
68
|
resolver?: ResolverExtension;
|
|
65
69
|
connector?: ConnectorExtension<GuardedNodeType<CreateExtensionOptions<T>['filter']>>;
|
|
@@ -71,15 +75,16 @@ export type CreateExtensionOptions<T = any> = {
|
|
|
71
75
|
* Create a graph builder extension.
|
|
72
76
|
*/
|
|
73
77
|
export const createExtension = <T = any>(extension: CreateExtensionOptions<T>): BuilderExtension[] => {
|
|
74
|
-
const { id, resolver, connector, actions, actionGroups, ...rest } = extension;
|
|
78
|
+
const { id, position = 'static', resolver, connector, actions, actionGroups, ...rest } = extension;
|
|
75
79
|
const getId = (key: string) => `${id}/${key}`;
|
|
76
80
|
return [
|
|
77
|
-
resolver ? { id: getId('resolver'), resolver } : undefined,
|
|
78
|
-
connector ? { ...rest, id: getId('connector'), connector } : undefined,
|
|
81
|
+
resolver ? { id: getId('resolver'), position, resolver } : undefined,
|
|
82
|
+
connector ? { ...rest, id: getId('connector'), position, connector } : undefined,
|
|
79
83
|
actionGroups
|
|
80
84
|
? ({
|
|
81
85
|
...rest,
|
|
82
86
|
id: getId('actionGroups'),
|
|
87
|
+
position,
|
|
83
88
|
type: ACTION_GROUP_TYPE,
|
|
84
89
|
relation: 'outbound',
|
|
85
90
|
connector: ({ node }) =>
|
|
@@ -90,12 +95,13 @@ export const createExtension = <T = any>(extension: CreateExtensionOptions<T>):
|
|
|
90
95
|
? ({
|
|
91
96
|
...rest,
|
|
92
97
|
id: getId('actions'),
|
|
98
|
+
position,
|
|
93
99
|
type: ACTION_TYPE,
|
|
94
100
|
relation: 'outbound',
|
|
95
101
|
connector: ({ node }) => actions({ node })?.map((arg) => ({ ...arg, type: ACTION_TYPE })),
|
|
96
102
|
} satisfies BuilderExtension)
|
|
97
103
|
: undefined,
|
|
98
|
-
].filter(
|
|
104
|
+
].filter(isNonNullable);
|
|
99
105
|
};
|
|
100
106
|
|
|
101
107
|
export type GraphBuilderTraverseOptions = {
|
|
@@ -166,18 +172,27 @@ export const toSignal = <T>(
|
|
|
166
172
|
return thisSignal.value;
|
|
167
173
|
};
|
|
168
174
|
|
|
169
|
-
export type BuilderExtension = {
|
|
175
|
+
export type BuilderExtension = Readonly<{
|
|
170
176
|
id: string;
|
|
177
|
+
position: Position;
|
|
171
178
|
resolver?: ResolverExtension;
|
|
172
179
|
connector?: ConnectorExtension;
|
|
173
180
|
// Only for connector.
|
|
174
181
|
relation?: Relation;
|
|
175
182
|
type?: string;
|
|
176
183
|
filter?: (node: Node) => boolean;
|
|
177
|
-
}
|
|
184
|
+
}>;
|
|
178
185
|
|
|
179
186
|
type ExtensionArg = BuilderExtension | BuilderExtension[] | ExtensionArg[];
|
|
180
187
|
|
|
188
|
+
export const flattenExtensions = (extension: ExtensionArg, acc: BuilderExtension[] = []): BuilderExtension[] => {
|
|
189
|
+
if (Array.isArray(extension)) {
|
|
190
|
+
return [...acc, ...extension.flatMap((ext) => flattenExtensions(ext, acc))];
|
|
191
|
+
} else {
|
|
192
|
+
return [...acc, extension];
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
181
196
|
/**
|
|
182
197
|
* The builder provides an extensible way to compose the construction of the graph.
|
|
183
198
|
*/
|
|
@@ -221,24 +236,40 @@ export class GraphBuilder {
|
|
|
221
236
|
.filter((id) => id !== ROOT_ID)
|
|
222
237
|
.forEach((id) => (this._initialized[id] = new Trigger()));
|
|
223
238
|
Object.keys(this._graph._nodes).forEach((id) => this._onInitialNode(id));
|
|
224
|
-
await Promise.all(
|
|
239
|
+
await Promise.all(
|
|
240
|
+
Object.entries(this._initialized).map(async ([id, trigger]) => {
|
|
241
|
+
try {
|
|
242
|
+
await trigger.wait({ timeout: NODE_RESOLVER_TIMEOUT });
|
|
243
|
+
} catch {
|
|
244
|
+
log.error('node resolver timeout', { id });
|
|
245
|
+
this.graph._removeNodes([id]);
|
|
246
|
+
}
|
|
247
|
+
}),
|
|
248
|
+
);
|
|
225
249
|
}
|
|
226
250
|
|
|
227
251
|
get graph() {
|
|
228
252
|
return this._graph;
|
|
229
253
|
}
|
|
230
254
|
|
|
255
|
+
/**
|
|
256
|
+
* @reactive
|
|
257
|
+
*/
|
|
258
|
+
get extensions() {
|
|
259
|
+
return Object.values(this._extensions);
|
|
260
|
+
}
|
|
261
|
+
|
|
231
262
|
/**
|
|
232
263
|
* Register a node builder which will be called in order to construct the graph.
|
|
233
264
|
*/
|
|
234
265
|
addExtension(extension: ExtensionArg): GraphBuilder {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
266
|
+
const extensions = flattenExtensions(extension);
|
|
267
|
+
untracked(() => {
|
|
268
|
+
extensions.forEach((extension) => {
|
|
269
|
+
this._dispatcher.state[extension.id] = [];
|
|
270
|
+
this._extensions[extension.id] = extension;
|
|
271
|
+
});
|
|
272
|
+
});
|
|
242
273
|
return this;
|
|
243
274
|
}
|
|
244
275
|
|
|
@@ -246,7 +277,9 @@ export class GraphBuilder {
|
|
|
246
277
|
* Remove a node builder from the graph builder.
|
|
247
278
|
*/
|
|
248
279
|
removeExtension(id: string): GraphBuilder {
|
|
249
|
-
|
|
280
|
+
untracked(() => {
|
|
281
|
+
delete this._extensions[id];
|
|
282
|
+
});
|
|
250
283
|
return this;
|
|
251
284
|
}
|
|
252
285
|
|
|
@@ -310,7 +343,8 @@ export class GraphBuilder {
|
|
|
310
343
|
this._resolverSubscriptions.set(
|
|
311
344
|
nodeId,
|
|
312
345
|
effect(() => {
|
|
313
|
-
|
|
346
|
+
const extensions = Object.values(this._extensions).toSorted(byPosition);
|
|
347
|
+
for (const { id, resolver } of extensions) {
|
|
314
348
|
if (!resolver) {
|
|
315
349
|
continue;
|
|
316
350
|
}
|
|
@@ -367,7 +401,8 @@ export class GraphBuilder {
|
|
|
367
401
|
|
|
368
402
|
// TODO(wittjosiah): Consider allowing extensions to collaborate on the same node by merging their results.
|
|
369
403
|
const nodes: NodeArg<any>[] = [];
|
|
370
|
-
|
|
404
|
+
const extensions = Object.values(this._extensions).toSorted(byPosition);
|
|
405
|
+
for (const { id, connector, filter, type, relation = 'outbound' } of extensions) {
|
|
371
406
|
if (
|
|
372
407
|
!connector ||
|
|
373
408
|
relation !== nodesRelation ||
|
package/src/graph.ts
CHANGED
|
@@ -8,12 +8,12 @@ import { asyncTimeout, Trigger } from '@dxos/async';
|
|
|
8
8
|
import { invariant } from '@dxos/invariant';
|
|
9
9
|
import { type ReactiveObject, create } from '@dxos/live-object';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
|
-
import { type MakeOptional,
|
|
11
|
+
import { type MakeOptional, isNonNullable, pick } from '@dxos/util';
|
|
12
12
|
|
|
13
13
|
import { type Node, type NodeArg, type NodeFilter, type Relation, actionGroupSymbol, isActionLike } from './node';
|
|
14
14
|
|
|
15
15
|
const graphSymbol = Symbol('graph');
|
|
16
|
-
type DeepWriteable<T> = { -readonly [K in keyof T]: DeepWriteable<T[K]> };
|
|
16
|
+
type DeepWriteable<T> = { -readonly [K in keyof T]: T[K] extends object ? DeepWriteable<T[K]> : T[K] };
|
|
17
17
|
type NodeInternal = DeepWriteable<Node> & { [graphSymbol]: Graph };
|
|
18
18
|
|
|
19
19
|
export const getGraph = (node: Node): Graph => {
|
|
@@ -162,7 +162,7 @@ export class Graph {
|
|
|
162
162
|
const nextSeen = [...seen, node.id];
|
|
163
163
|
return nextSeen.includes(n.id) ? undefined : toJSON(n, nextSeen);
|
|
164
164
|
})
|
|
165
|
-
.filter(
|
|
165
|
+
.filter(isNonNullable);
|
|
166
166
|
}
|
|
167
167
|
return obj;
|
|
168
168
|
};
|
|
@@ -599,7 +599,7 @@ export class Graph {
|
|
|
599
599
|
} else {
|
|
600
600
|
return edges[relation]
|
|
601
601
|
.map((id) => this._nodes[id])
|
|
602
|
-
.filter(
|
|
602
|
+
.filter(isNonNullable)
|
|
603
603
|
.filter((n) => !type || n.type === type);
|
|
604
604
|
}
|
|
605
605
|
}
|
package/src/node.ts
CHANGED
|
@@ -87,9 +87,9 @@ export const isAction = (data: unknown): data is Action =>
|
|
|
87
87
|
|
|
88
88
|
export const actionGroupSymbol = Symbol('ActionGroup');
|
|
89
89
|
|
|
90
|
-
export type ActionGroup = Readonly<
|
|
91
|
-
Omit<Node<typeof actionGroupSymbol,
|
|
92
|
-
properties: Readonly<
|
|
90
|
+
export type ActionGroup<TProperties extends Record<string, any> = Record<string, any>> = Readonly<
|
|
91
|
+
Omit<Node<typeof actionGroupSymbol, TProperties>, 'properties'> & {
|
|
92
|
+
properties: Readonly<TProperties>;
|
|
93
93
|
}
|
|
94
94
|
>;
|
|
95
95
|
|