@dxos/app-graph 0.8.3 → 0.8.4-main.1da679c
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 +242 -167
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +242 -167
- 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 +15 -4
- package/dist/types/src/graph-builder.d.ts.map +1 -1
- package/dist/types/src/graph.d.ts +6 -2
- package/dist/types/src/graph.d.ts.map +1 -1
- package/dist/types/src/node.d.ts +1 -1
- package/dist/types/src/node.d.ts.map +1 -1
- package/dist/types/src/stories/EchoGraph.stories.d.ts +6 -12
- package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +26 -27
- package/src/graph-builder.test.ts +59 -2
- package/src/graph-builder.ts +65 -21
- package/src/graph.test.ts +1 -1
- package/src/graph.ts +16 -17
- package/src/node.ts +5 -3
- package/src/signals-integration.test.ts +1 -1
- package/src/stories/EchoGraph.stories.tsx +25 -138
- package/dist/lib/node/index.cjs +0 -816
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
|
@@ -5,38 +5,38 @@
|
|
|
5
5
|
import '@dxos-theme';
|
|
6
6
|
|
|
7
7
|
import { type Registry, RegistryContext, Rx, useRxValue } from '@effect-rx/rx-react';
|
|
8
|
-
import {
|
|
8
|
+
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
9
9
|
import { Option, pipe } from 'effect';
|
|
10
10
|
import React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
Expando,
|
|
14
|
+
Filter,
|
|
15
|
+
type Live,
|
|
15
16
|
Query,
|
|
16
17
|
type QueryResult,
|
|
17
18
|
type Space,
|
|
18
19
|
SpaceState,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Filter,
|
|
20
|
+
isSpace,
|
|
21
|
+
live,
|
|
22
22
|
} from '@dxos/client/echo';
|
|
23
23
|
import { Obj, Type } from '@dxos/echo';
|
|
24
24
|
import { faker } from '@dxos/random';
|
|
25
25
|
import { type Client, useClient } from '@dxos/react-client';
|
|
26
26
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
27
|
-
import {
|
|
27
|
+
import { Icon, IconButton, Input, Select } from '@dxos/react-ui';
|
|
28
28
|
import { Path, Tree } from '@dxos/react-ui-list';
|
|
29
|
-
import { Tabs } from '@dxos/react-ui-tabs';
|
|
30
29
|
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
31
30
|
import { withTheme } from '@dxos/storybook-utils';
|
|
32
31
|
import { byPosition, isNonNullable, safeParseInt } from '@dxos/util';
|
|
33
32
|
|
|
34
|
-
import { JsonTree } from './Tree';
|
|
35
33
|
import { type ExpandableGraph, ROOT_ID } from '../graph';
|
|
36
34
|
import { GraphBuilder, createExtension, rxFromObservable, rxFromSignal } from '../graph-builder';
|
|
37
35
|
import { type Node } from '../node';
|
|
38
36
|
import { rxFromQuery } from '../testing';
|
|
39
37
|
|
|
38
|
+
import { JsonTree } from './Tree';
|
|
39
|
+
|
|
40
40
|
const DEFAULT_PERIOD = 500;
|
|
41
41
|
|
|
42
42
|
enum Action {
|
|
@@ -205,7 +205,11 @@ const Controls = ({ children }: PropsWithChildren) => {
|
|
|
205
205
|
return (
|
|
206
206
|
<>
|
|
207
207
|
<div className='flex shrink-0 p-2 space-x-2'>
|
|
208
|
-
<
|
|
208
|
+
<IconButton
|
|
209
|
+
icon={generating ? 'ph--pause--regular' : 'ph--play--regular'}
|
|
210
|
+
label={generating ? 'Pause' : 'Play'}
|
|
211
|
+
onClick={() => setGenerating((generating) => !generating)}
|
|
212
|
+
/>
|
|
209
213
|
<div className='relative' title='mutation period'>
|
|
210
214
|
<Input.Root>
|
|
211
215
|
<Input.TextInput
|
|
@@ -217,11 +221,9 @@ const Controls = ({ children }: PropsWithChildren) => {
|
|
|
217
221
|
onChange={({ target: { value } }) => setActionInterval(value)}
|
|
218
222
|
/>
|
|
219
223
|
</Input.Root>
|
|
220
|
-
<
|
|
224
|
+
<Icon icon='ph--timer--regular' classNames={mx('absolute inline-end-1 block-start-1 mt-[6px]', getSize(3))} />
|
|
221
225
|
</div>
|
|
222
|
-
<
|
|
223
|
-
<Plus />
|
|
224
|
-
</Button>
|
|
226
|
+
<IconButton icon='ph--plus--regular' label='Add' onClick={() => action && runAction(client, action)} />
|
|
225
227
|
<Select.Root value={action?.toString()} onValueChange={(action) => setAction(action as unknown as Action)}>
|
|
226
228
|
<Select.TriggerButton placeholder='Select value' />
|
|
227
229
|
<Select.Portal>
|
|
@@ -245,10 +247,9 @@ const Controls = ({ children }: PropsWithChildren) => {
|
|
|
245
247
|
);
|
|
246
248
|
};
|
|
247
249
|
|
|
248
|
-
|
|
250
|
+
const meta = {
|
|
249
251
|
title: 'sdk/app-graph/EchoGraph',
|
|
250
252
|
decorators: [
|
|
251
|
-
withTheme,
|
|
252
253
|
withClientProvider({
|
|
253
254
|
createIdentity: true,
|
|
254
255
|
onIdentityCreated: async ({ client }) => {
|
|
@@ -256,10 +257,15 @@ export default {
|
|
|
256
257
|
await client.spaces.create();
|
|
257
258
|
},
|
|
258
259
|
}),
|
|
260
|
+
withTheme,
|
|
259
261
|
],
|
|
260
|
-
}
|
|
262
|
+
} satisfies Meta<typeof Registry>;
|
|
263
|
+
|
|
264
|
+
export default meta;
|
|
261
265
|
|
|
262
|
-
|
|
266
|
+
type Story = StoryObj<typeof meta>;
|
|
267
|
+
|
|
268
|
+
export const JsonView: Story = {
|
|
263
269
|
render: () => {
|
|
264
270
|
const client = useClient();
|
|
265
271
|
const registry = useContext(RegistryContext);
|
|
@@ -275,7 +281,7 @@ export const JsonView = {
|
|
|
275
281
|
},
|
|
276
282
|
};
|
|
277
283
|
|
|
278
|
-
export const TreeView = {
|
|
284
|
+
export const TreeView: Story = {
|
|
279
285
|
render: () => {
|
|
280
286
|
const client = useClient();
|
|
281
287
|
const registry = useContext(RegistryContext);
|
|
@@ -372,122 +378,3 @@ export const TreeView = {
|
|
|
372
378
|
);
|
|
373
379
|
},
|
|
374
380
|
};
|
|
375
|
-
|
|
376
|
-
// TODO(wittjosiah): Remove.
|
|
377
|
-
export const TabTreeView = {
|
|
378
|
-
render: () => {
|
|
379
|
-
const client = useClient();
|
|
380
|
-
const registry = useContext(RegistryContext);
|
|
381
|
-
const graph = useMemo(() => createGraph(client, registry), [client, registry]);
|
|
382
|
-
const state = useMemo(() => new Map<string, Live<{ open: boolean; current: boolean }>>(), []);
|
|
383
|
-
|
|
384
|
-
const useItems = useCallback(
|
|
385
|
-
(node?: Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
386
|
-
const connections = useRxValue(graph.connections(node?.id ?? ROOT_ID));
|
|
387
|
-
return options?.sort ? connections.toSorted((a, b) => byPosition(a.properties, b.properties)) : connections;
|
|
388
|
-
},
|
|
389
|
-
[graph],
|
|
390
|
-
);
|
|
391
|
-
|
|
392
|
-
const getProps = useCallback(
|
|
393
|
-
(node: Node, path: string[]) => {
|
|
394
|
-
const children = graph
|
|
395
|
-
.getConnections(node.id, 'outbound')
|
|
396
|
-
.map((n) => {
|
|
397
|
-
// Break cycles.
|
|
398
|
-
const nextPath = [...path, node.id];
|
|
399
|
-
return nextPath.includes(n.id) ? undefined : (n as Node);
|
|
400
|
-
})
|
|
401
|
-
.filter(isNonNullable) as Node[];
|
|
402
|
-
const parentOf =
|
|
403
|
-
children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
|
|
404
|
-
return {
|
|
405
|
-
id: node.id,
|
|
406
|
-
label: node.id,
|
|
407
|
-
icon: node.type === 'dxos.org/type/Space' ? 'ph--planet--regular' : 'ph--placeholder--regular',
|
|
408
|
-
parentOf,
|
|
409
|
-
};
|
|
410
|
-
},
|
|
411
|
-
[graph],
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
const isOpen = useCallback(
|
|
415
|
-
(_path: string[]) => {
|
|
416
|
-
const path = Path.create(..._path);
|
|
417
|
-
const object = state.get(path) ?? live({ open: true, current: false });
|
|
418
|
-
if (!state.has(path)) {
|
|
419
|
-
state.set(path, object);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
return object.open;
|
|
423
|
-
},
|
|
424
|
-
[state],
|
|
425
|
-
);
|
|
426
|
-
|
|
427
|
-
const isCurrent = useCallback(
|
|
428
|
-
(_path: string[]) => {
|
|
429
|
-
const path = Path.create(..._path);
|
|
430
|
-
const object = state.get(path) ?? live({ open: false, current: false });
|
|
431
|
-
if (!state.has(path)) {
|
|
432
|
-
state.set(path, object);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return object.current;
|
|
436
|
-
},
|
|
437
|
-
[state],
|
|
438
|
-
);
|
|
439
|
-
|
|
440
|
-
const onOpenChange = useCallback(
|
|
441
|
-
({ path: _path, open }: { path: string[]; open: boolean }) => {
|
|
442
|
-
const path = Path.create(..._path);
|
|
443
|
-
const object = state.get(path);
|
|
444
|
-
object!.open = open;
|
|
445
|
-
},
|
|
446
|
-
[state],
|
|
447
|
-
);
|
|
448
|
-
|
|
449
|
-
const onSelect = useCallback(
|
|
450
|
-
({ path: _path, current }: { path: string[]; current: boolean }) => {
|
|
451
|
-
const path = Path.create(..._path);
|
|
452
|
-
const object = state.get(path);
|
|
453
|
-
object!.current = current;
|
|
454
|
-
},
|
|
455
|
-
[state],
|
|
456
|
-
);
|
|
457
|
-
|
|
458
|
-
const spaces = useItems(graph.root);
|
|
459
|
-
|
|
460
|
-
return (
|
|
461
|
-
<>
|
|
462
|
-
<Controls />
|
|
463
|
-
<Tabs.Root defaultValue={spaces[0].id}>
|
|
464
|
-
<Tabs.Tablist>
|
|
465
|
-
{spaces.map((space) => {
|
|
466
|
-
return (
|
|
467
|
-
<Tabs.Tab key={space.id} value={space.id}>
|
|
468
|
-
{space.id}
|
|
469
|
-
</Tabs.Tab>
|
|
470
|
-
);
|
|
471
|
-
})}
|
|
472
|
-
</Tabs.Tablist>
|
|
473
|
-
{spaces.map((space) => {
|
|
474
|
-
return (
|
|
475
|
-
<Tabs.Tabpanel key={space.id} value={space.id}>
|
|
476
|
-
<Tree
|
|
477
|
-
id={space.id}
|
|
478
|
-
root={space}
|
|
479
|
-
useItems={useItems}
|
|
480
|
-
getProps={getProps}
|
|
481
|
-
isOpen={isOpen}
|
|
482
|
-
isCurrent={isCurrent}
|
|
483
|
-
onOpenChange={onOpenChange}
|
|
484
|
-
onSelect={onSelect}
|
|
485
|
-
/>
|
|
486
|
-
</Tabs.Tabpanel>
|
|
487
|
-
);
|
|
488
|
-
})}
|
|
489
|
-
</Tabs.Root>
|
|
490
|
-
</>
|
|
491
|
-
);
|
|
492
|
-
},
|
|
493
|
-
};
|