@dxos/app-graph 0.8.4-main.fd6878d → 0.8.4-main.fffef41

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.
@@ -2,11 +2,10 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
7
- import { type Registry, RegistryContext, Rx, useRxValue } from '@effect-rx/rx-react';
8
- import { type Meta } from '@storybook/react-vite';
9
- import { Option, pipe } from 'effect';
5
+ import { Atom, type Registry, RegistryContext, useAtomValue } from '@effect-atom/atom-react';
6
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
+ import * as Function from 'effect/Function';
8
+ import * as Option from 'effect/Option';
10
9
  import React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';
11
10
 
12
11
  import {
@@ -25,15 +24,15 @@ import { faker } from '@dxos/random';
25
24
  import { type Client, useClient } from '@dxos/react-client';
26
25
  import { withClientProvider } from '@dxos/react-client/testing';
27
26
  import { Icon, IconButton, Input, Select } from '@dxos/react-ui';
27
+ import { withTheme } from '@dxos/react-ui/testing';
28
28
  import { Path, Tree } from '@dxos/react-ui-list';
29
29
  import { getSize, mx } from '@dxos/react-ui-theme';
30
- import { withTheme } from '@dxos/storybook-utils';
31
30
  import { byPosition, isNonNullable, safeParseInt } from '@dxos/util';
32
31
 
33
32
  import { type ExpandableGraph, ROOT_ID } from '../graph';
34
- import { GraphBuilder, createExtension, rxFromObservable, rxFromSignal } from '../graph-builder';
33
+ import { GraphBuilder, atomFromObservable, createExtension } from '../graph-builder';
35
34
  import { type Node } from '../node';
36
- import { rxFromQuery } from '../testing';
35
+ import { atomFromQuery } from '../testing';
37
36
 
38
37
  import { JsonTree } from './Tree';
39
38
 
@@ -61,18 +60,20 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
61
60
  const spaceBuilderExtension = createExtension({
62
61
  id: 'space',
63
62
  connector: (node) =>
64
- Rx.make((get) =>
65
- pipe(
63
+ Atom.make((get) =>
64
+ Function.pipe(
66
65
  get(node),
67
66
  Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
68
67
  Option.map(() => {
69
- const spaces = get(rxFromObservable(client.spaces)) ?? [];
68
+ const spaces = get(atomFromObservable(client.spaces)) ?? [];
70
69
  return spaces
71
- .filter((space) => get(rxFromObservable(space.state)) === SpaceState.SPACE_READY)
70
+ .filter((space) => get(atomFromObservable(space.state)) === SpaceState.SPACE_READY)
72
71
  .map((space) => ({
73
72
  id: space.id,
74
73
  type: 'dxos.org/type/Space',
75
- properties: { label: get(rxFromSignal(() => space.properties.name)) },
74
+ properties: {
75
+ label: get(atomFromObservable(space.properties.name)),
76
+ },
76
77
  data: space,
77
78
  }));
78
79
  }),
@@ -85,15 +86,15 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
85
86
  id: 'object',
86
87
  connector: (node) => {
87
88
  let query: QueryResult<Live<Expando>> | undefined;
88
- return Rx.make((get) =>
89
- pipe(
89
+ return Atom.make((get) =>
90
+ Function.pipe(
90
91
  get(node),
91
92
  Option.flatMap((node) => (isSpace(node.data) ? Option.some(node.data) : Option.none())),
92
93
  Option.map((space) => {
93
94
  if (!query) {
94
95
  query = space.db.query(Query.type(Expando, { type: 'test' }));
95
96
  }
96
- const objects = get(rxFromQuery(query));
97
+ const objects = get(atomFromQuery(query));
97
98
  return objects.map((object) => ({
98
99
  id: object.id,
99
100
  type: 'dxos.org/type/test',
@@ -160,7 +161,12 @@ const runAction = async (client: Client, action: Action) => {
160
161
  }
161
162
 
162
163
  case Action.ADD_OBJECT:
163
- getRandomSpace(client)?.db.add(Obj.make(Type.Expando, { type: 'test', name: faker.commerce.productName() }));
164
+ getRandomSpace(client)?.db.add(
165
+ Obj.make(Type.Expando, {
166
+ type: 'test',
167
+ name: faker.commerce.productName(),
168
+ }),
169
+ );
164
170
  break;
165
171
 
166
172
  case Action.REMOVE_OBJECT: {
@@ -215,7 +221,7 @@ const Controls = ({ children }: PropsWithChildren) => {
215
221
  <Input.TextInput
216
222
  autoComplete='off'
217
223
  size={5}
218
- classNames='w-[100px] text-right pie-[22px]'
224
+ classNames='is-[100px] text-right pie-[22px]'
219
225
  placeholder='Interval'
220
226
  value={actionInterval}
221
227
  onChange={({ target: { value } }) => setActionInterval(value)}
@@ -247,28 +253,30 @@ const Controls = ({ children }: PropsWithChildren) => {
247
253
  );
248
254
  };
249
255
 
250
- const meta: Meta = {
256
+ const meta = {
251
257
  title: 'sdk/app-graph/EchoGraph',
252
258
  decorators: [
259
+ withTheme,
253
260
  withClientProvider({
254
261
  createIdentity: true,
255
- onIdentityCreated: async ({ client }) => {
262
+ onCreateIdentity: async ({ client }) => {
256
263
  await client.spaces.create();
257
264
  await client.spaces.create();
258
265
  },
259
266
  }),
260
- withTheme,
261
267
  ],
262
- };
268
+ } satisfies Meta;
263
269
 
264
270
  export default meta;
265
271
 
266
- export const JsonView = {
272
+ type Story = StoryObj<typeof meta>;
273
+
274
+ export const JsonView: Story = {
267
275
  render: () => {
268
276
  const client = useClient();
269
277
  const registry = useContext(RegistryContext);
270
278
  const graph = useMemo(() => createGraph(client, registry), [client, registry]);
271
- const data = useRxValue(graph.json());
279
+ const data = useAtomValue(graph.json());
272
280
 
273
281
  return (
274
282
  <>
@@ -279,7 +287,7 @@ export const JsonView = {
279
287
  },
280
288
  };
281
289
 
282
- export const TreeView = {
290
+ export const TreeView: Story = {
283
291
  render: () => {
284
292
  const client = useClient();
285
293
  const registry = useContext(RegistryContext);
@@ -288,7 +296,7 @@ export const TreeView = {
288
296
 
289
297
  const useItems = useCallback(
290
298
  (node?: Node, options?: { disposition?: string; sort?: boolean }) => {
291
- const connections = useRxValue(graph.connections(node?.id ?? ROOT_ID));
299
+ const connections = useAtomValue(graph.connections(node?.id ?? ROOT_ID));
292
300
  return options?.sort ? connections.toSorted((a, b) => byPosition(a.properties, b.properties)) : connections;
293
301
  },
294
302
  [graph],
@@ -72,7 +72,7 @@ const Scalar: FC<{ value: any }> = ({ value }) => {
72
72
 
73
73
  const Box: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...props }) => {
74
74
  return (
75
- <div className={mx('flex px-2 border border-l-0 font-mono truncate', className)} {...props}>
75
+ <div className={mx('flex pli-2 border border-l-0 font-mono truncate', className)} {...props}>
76
76
  {children}
77
77
  </div>
78
78
  );
package/src/testing.ts CHANGED
@@ -2,13 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Rx } from '@effect-rx/rx-react';
5
+ import { Atom } from '@effect-atom/atom-react';
6
6
 
7
+ import { type AnyEchoObject } from '@dxos/echo/internal';
7
8
  import { type QueryResult } from '@dxos/echo-db';
8
- import { type AnyEchoObject } from '@dxos/echo-schema';
9
9
 
10
- export const rxFromQuery = <T extends AnyEchoObject>(query: QueryResult<T>): Rx.Rx<T[]> => {
11
- return Rx.make((get) => {
10
+ export const atomFromQuery = <T extends AnyEchoObject>(query: QueryResult<T>): Atom.Atom<T[]> => {
11
+ return Atom.make((get) => {
12
12
  const unsubscribe = query.subscribe((result) => {
13
13
  get.setSelf(result.objects);
14
14
  });