@dxos/app-graph 0.7.1 → 0.7.2-staging.6d26b2a
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 +34 -20
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +33 -19
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +34 -20
- 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 +1 -1
- package/dist/types/src/graph-builder.d.ts.map +1 -1
- package/dist/types/src/graph.d.ts +5 -1
- package/dist/types/src/graph.d.ts.map +1 -1
- package/dist/types/src/node.d.ts +7 -1
- package/dist/types/src/node.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/graph-builder.ts +6 -2
- package/src/graph.ts +32 -20
- package/src/node.ts +8 -1
- package/src/stories/EchoGraph.stories.tsx +2 -2
package/src/graph.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { asyncTimeout, Trigger } from '@dxos/async';
|
|
|
8
8
|
import { type ReactiveObject, create } from '@dxos/echo-schema';
|
|
9
9
|
import { invariant } from '@dxos/invariant';
|
|
10
10
|
import { log } from '@dxos/log';
|
|
11
|
-
import { nonNullable } from '@dxos/util';
|
|
11
|
+
import { type MakeOptional, nonNullable, pick } from '@dxos/util';
|
|
12
12
|
|
|
13
13
|
import { type Relation, type Node, type NodeArg, type NodeFilter, isActionLike, actionGroupSymbol } from './node';
|
|
14
14
|
|
|
@@ -66,8 +66,7 @@ export type GraphTraversalOptions = {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
export type GraphParams = {
|
|
69
|
-
|
|
70
|
-
nodes?: Omit<Node, 'data'>[];
|
|
69
|
+
nodes?: MakeOptional<Node, 'data' | 'cacheable'>[];
|
|
71
70
|
edges?: Record<string, string[]>;
|
|
72
71
|
onInitialNode?: Graph['_onInitialNode'];
|
|
73
72
|
onInitialNodes?: Graph['_onInitialNodes'];
|
|
@@ -96,15 +95,26 @@ export class Graph {
|
|
|
96
95
|
readonly _edges: Record<string, ReactiveObject<{ inbound: string[]; outbound: string[] }>> = {};
|
|
97
96
|
|
|
98
97
|
constructor({ nodes, edges, onInitialNode, onInitialNodes, onRemoveNode }: GraphParams = {}) {
|
|
99
|
-
this.
|
|
98
|
+
this._onInitialNode = onInitialNode;
|
|
99
|
+
this._onInitialNodes = onInitialNodes;
|
|
100
|
+
this._onRemoveNode = onRemoveNode;
|
|
101
|
+
|
|
102
|
+
this._nodes[ROOT_ID] = this._constructNode({
|
|
103
|
+
id: ROOT_ID,
|
|
104
|
+
type: ROOT_TYPE,
|
|
105
|
+
cacheable: [],
|
|
106
|
+
properties: {},
|
|
107
|
+
data: null,
|
|
108
|
+
});
|
|
100
109
|
if (nodes) {
|
|
101
110
|
nodes.forEach((node) => {
|
|
111
|
+
const cacheable = Object.keys(node.properties ?? {});
|
|
102
112
|
if (node.type === ACTION_TYPE) {
|
|
103
|
-
this._addNode({
|
|
113
|
+
this._addNode({ cacheable, data: () => log.warn('Pickled action invocation'), ...node });
|
|
104
114
|
} else if (node.type === ACTION_GROUP_TYPE) {
|
|
105
|
-
this._addNode({
|
|
115
|
+
this._addNode({ cacheable, data: actionGroupSymbol, ...node });
|
|
106
116
|
} else {
|
|
107
|
-
this._addNode(node);
|
|
117
|
+
this._addNode({ cacheable, ...node });
|
|
108
118
|
}
|
|
109
119
|
});
|
|
110
120
|
}
|
|
@@ -118,10 +128,6 @@ export class Graph {
|
|
|
118
128
|
this._sortEdges(source, 'outbound', edges);
|
|
119
129
|
});
|
|
120
130
|
}
|
|
121
|
-
|
|
122
|
-
this._onInitialNode = onInitialNode;
|
|
123
|
-
this._onInitialNodes = onInitialNodes;
|
|
124
|
-
this._onRemoveNode = onRemoveNode;
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
static from(pickle: string, options: Omit<GraphParams, 'nodes' | 'edges'> = {}) {
|
|
@@ -167,17 +173,23 @@ export class Graph {
|
|
|
167
173
|
}
|
|
168
174
|
|
|
169
175
|
pickle() {
|
|
170
|
-
const nodes = Object.values(this._nodes)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
const nodes = Object.values(this._nodes)
|
|
177
|
+
.filter((node) => !!node.cacheable)
|
|
178
|
+
.map((node) => {
|
|
179
|
+
return {
|
|
180
|
+
id: node.id,
|
|
181
|
+
type: node.type,
|
|
182
|
+
properties: pick(node.properties, node.cacheable!),
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const cacheable = new Set(nodes.map((node) => node.id));
|
|
177
187
|
|
|
178
188
|
const edges = Object.fromEntries(
|
|
179
189
|
Object.entries(this._edges)
|
|
180
|
-
.
|
|
190
|
+
.filter(([id]) => cacheable.has(id))
|
|
191
|
+
.map(([id, { outbound }]): [string, string[]] => [id, outbound.filter((nodeId) => cacheable.has(nodeId))])
|
|
192
|
+
// TODO(wittjosiah): Why sort?
|
|
181
193
|
.toSorted(([a], [b]) => a.localeCompare(b)),
|
|
182
194
|
);
|
|
183
195
|
|
|
@@ -440,7 +452,7 @@ export class Graph {
|
|
|
440
452
|
|
|
441
453
|
private _removeNode(id: string, edges = false) {
|
|
442
454
|
untracked(() => {
|
|
443
|
-
const node = this.findNode(id);
|
|
455
|
+
const node = this.findNode(id, false);
|
|
444
456
|
if (!node) {
|
|
445
457
|
return;
|
|
446
458
|
}
|
package/src/node.ts
CHANGED
|
@@ -20,6 +20,13 @@ export type Node<TData = any, TProperties extends Record<string, any> = Record<s
|
|
|
20
20
|
*/
|
|
21
21
|
type: string;
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Keys in of the properties which should be cached.
|
|
25
|
+
* If defined, the node will be included in the cache.
|
|
26
|
+
* If undefined, the node will not be included in the cache.
|
|
27
|
+
*/
|
|
28
|
+
cacheable?: string[];
|
|
29
|
+
|
|
23
30
|
/**
|
|
24
31
|
* Properties of the node relevant to displaying the node.
|
|
25
32
|
*/
|
|
@@ -47,7 +54,7 @@ export const isGraphNode = (data: unknown): data is Node =>
|
|
|
47
54
|
|
|
48
55
|
export type NodeArg<TData, TProperties extends Record<string, any> = Record<string, any>> = MakeOptional<
|
|
49
56
|
Node<TData, TProperties>,
|
|
50
|
-
'data' | 'properties'
|
|
57
|
+
'data' | 'properties' | 'cacheable'
|
|
51
58
|
> & {
|
|
52
59
|
/** Will automatically add nodes with an edge from this node to each. */
|
|
53
60
|
nodes?: NodeArg<unknown>[];
|
|
@@ -10,7 +10,7 @@ import React, { useEffect, useState } from 'react';
|
|
|
10
10
|
import {
|
|
11
11
|
create,
|
|
12
12
|
type Echo,
|
|
13
|
-
type
|
|
13
|
+
type ReactiveEchoObject,
|
|
14
14
|
type FilterSource,
|
|
15
15
|
type Space,
|
|
16
16
|
SpaceState,
|
|
@@ -54,7 +54,7 @@ const actionWeights = {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
// TODO(wittjosiah): Factor out.
|
|
57
|
-
const memoizeQuery = <T extends
|
|
57
|
+
const memoizeQuery = <T extends ReactiveEchoObject<any>>(
|
|
58
58
|
spaceOrEcho?: Space | Echo,
|
|
59
59
|
filter?: FilterSource<T>,
|
|
60
60
|
options?: QueryOptions,
|