@dxos/app-graph 0.8.4-main.72ec0f3 → 0.8.4-main.7ace549
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.map +1 -1
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs.map +1 -1
- package/dist/lib/node-esm/meta.json +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.map +1 -1
- package/dist/types/src/testing.d.ts +2 -3
- package/dist/types/src/testing.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +19 -19
- package/src/node.ts +1 -1
- package/src/signals-integration.test.ts +9 -5
- package/src/stories/EchoGraph.stories.tsx +14 -22
- package/src/testing.ts +4 -3
- package/dist/types/src/experimental/graph-projections.test.d.ts +0 -25
- package/dist/types/src/experimental/graph-projections.test.d.ts.map +0 -1
- package/src/experimental/graph-projections.test.ts +0 -56
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/app-graph",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.7ace549",
|
|
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",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@preact/signals-core": "^1.12.1",
|
|
29
29
|
"main-thread-scheduling": "^14.1.1",
|
|
30
|
-
"@dxos/async": "0.8.4-main.
|
|
31
|
-
"@dxos/echo": "0.8.4-main.
|
|
32
|
-
"@dxos/
|
|
33
|
-
"@dxos/
|
|
34
|
-
"@dxos/
|
|
35
|
-
"@dxos/live-object": "0.8.4-main.
|
|
36
|
-
"@dxos/
|
|
37
|
-
"@dxos/
|
|
30
|
+
"@dxos/async": "0.8.4-main.7ace549",
|
|
31
|
+
"@dxos/echo": "0.8.4-main.7ace549",
|
|
32
|
+
"@dxos/debug": "0.8.4-main.7ace549",
|
|
33
|
+
"@dxos/echo-signals": "0.8.4-main.7ace549",
|
|
34
|
+
"@dxos/invariant": "0.8.4-main.7ace549",
|
|
35
|
+
"@dxos/live-object": "0.8.4-main.7ace549",
|
|
36
|
+
"@dxos/log": "0.8.4-main.7ace549",
|
|
37
|
+
"@dxos/util": "0.8.4-main.7ace549"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@effect-atom/atom-react": "^0.3.4",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
"react": "~19.2.0",
|
|
46
46
|
"react-dom": "~19.2.0",
|
|
47
47
|
"vite": "7.1.9",
|
|
48
|
-
"@dxos/echo-db": "0.8.4-main.
|
|
49
|
-
"@dxos/random": "0.8.4-main.
|
|
50
|
-
"@dxos/react-client": "0.8.4-main.
|
|
51
|
-
"@dxos/react-ui
|
|
52
|
-
"@dxos/react-ui-
|
|
53
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
54
|
-
"@dxos/
|
|
55
|
-
"@dxos/
|
|
48
|
+
"@dxos/echo-db": "0.8.4-main.7ace549",
|
|
49
|
+
"@dxos/random": "0.8.4-main.7ace549",
|
|
50
|
+
"@dxos/react-client": "0.8.4-main.7ace549",
|
|
51
|
+
"@dxos/react-ui": "0.8.4-main.7ace549",
|
|
52
|
+
"@dxos/react-ui-list": "0.8.4-main.7ace549",
|
|
53
|
+
"@dxos/react-ui-tabs": "0.8.4-main.7ace549",
|
|
54
|
+
"@dxos/react-ui-theme": "0.8.4-main.7ace549",
|
|
55
|
+
"@dxos/storybook-utils": "0.8.4-main.7ace549"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@effect-atom/atom-react": "^0.3.4",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"effect": "3.14.21",
|
|
61
61
|
"react": "^19.0.0",
|
|
62
62
|
"react-dom": "^19.0.0",
|
|
63
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
64
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
63
|
+
"@dxos/react-ui": "0.8.4-main.7ace549",
|
|
64
|
+
"@dxos/react-ui-theme": "0.8.4-main.7ace549"
|
|
65
65
|
},
|
|
66
66
|
"publishConfig": {
|
|
67
67
|
"access": "public"
|
package/src/node.ts
CHANGED
|
@@ -77,7 +77,7 @@ export type InvokeParams = {
|
|
|
77
77
|
caller?: string;
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
export type ActionData = (params?: InvokeParams) => MaybePromise<
|
|
80
|
+
export type ActionData = (params?: InvokeParams) => MaybePromise<any>;
|
|
81
81
|
|
|
82
82
|
export type Action<TProperties extends Record<string, any> = Record<string, any>> = Readonly<
|
|
83
83
|
Omit<Node<ActionData, TProperties>, 'properties'> & {
|
|
@@ -79,8 +79,8 @@ describe('signals integration', () => {
|
|
|
79
79
|
let outerId: string;
|
|
80
80
|
{
|
|
81
81
|
await using db = await peer.createDatabase();
|
|
82
|
-
const inner = db.add({ name: 'inner' });
|
|
83
|
-
const outer = db.add({ inner: Ref.make(inner) });
|
|
82
|
+
const inner = db.add(Obj.make(Type.Expando, { name: 'inner' }));
|
|
83
|
+
const outer = db.add(Obj.make(Type.Expando, { inner: Ref.make(inner) }));
|
|
84
84
|
outerId = outer.id;
|
|
85
85
|
await db.flush();
|
|
86
86
|
}
|
|
@@ -118,8 +118,8 @@ describe('signals integration', () => {
|
|
|
118
118
|
let outerId, innerId: string;
|
|
119
119
|
{
|
|
120
120
|
await using db = await peer.createDatabase();
|
|
121
|
-
const inner = db.add({ name: 'inner' });
|
|
122
|
-
const outer = db.add({ inner: Ref.make(inner) });
|
|
121
|
+
const inner = db.add(Obj.make(Type.Expando, { name: 'inner' }));
|
|
122
|
+
const outer = db.add(Obj.make(Type.Expando, { inner: Ref.make(inner) }));
|
|
123
123
|
innerId = inner.id;
|
|
124
124
|
outerId = outer.id;
|
|
125
125
|
await db.flush();
|
|
@@ -187,7 +187,11 @@ describe('signals integration', () => {
|
|
|
187
187
|
|
|
188
188
|
return Atom.make((get) => {
|
|
189
189
|
const objects = get(atomFromQuery(query));
|
|
190
|
-
return objects.map((object) => ({
|
|
190
|
+
return objects.map((object) => ({
|
|
191
|
+
id: object.id,
|
|
192
|
+
type: EXAMPLE_TYPE,
|
|
193
|
+
data: object.name,
|
|
194
|
+
}));
|
|
191
195
|
});
|
|
192
196
|
},
|
|
193
197
|
}),
|
|
@@ -6,20 +6,11 @@ import { Atom, type Registry, RegistryContext, useAtomValue } from '@effect-atom
|
|
|
6
6
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
7
7
|
import * as Function from 'effect/Function';
|
|
8
8
|
import * as Option from 'effect/Option';
|
|
9
|
+
import type * as Schema from 'effect/Schema';
|
|
9
10
|
import React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
10
11
|
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
Filter,
|
|
14
|
-
type Live,
|
|
15
|
-
Query,
|
|
16
|
-
type QueryResult,
|
|
17
|
-
type Space,
|
|
18
|
-
SpaceState,
|
|
19
|
-
isSpace,
|
|
20
|
-
live,
|
|
21
|
-
} from '@dxos/client/echo';
|
|
22
|
-
import { Obj, Type } from '@dxos/echo';
|
|
12
|
+
import { Filter, type Live, Query, type Space, SpaceState, isSpace, live } from '@dxos/client/echo';
|
|
13
|
+
import { type Database, Obj, Type } from '@dxos/echo';
|
|
23
14
|
import { faker } from '@dxos/random';
|
|
24
15
|
import { type Client, useClient } from '@dxos/react-client';
|
|
25
16
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
@@ -30,7 +21,7 @@ import { getSize, mx } from '@dxos/react-ui-theme';
|
|
|
30
21
|
import { byPosition, isNonNullable, safeParseInt } from '@dxos/util';
|
|
31
22
|
|
|
32
23
|
import { type ExpandableGraph, ROOT_ID } from '../graph';
|
|
33
|
-
import { GraphBuilder, atomFromObservable, createExtension } from '../graph-builder';
|
|
24
|
+
import { GraphBuilder, atomFromObservable, atomFromSignal, createExtension } from '../graph-builder';
|
|
34
25
|
import { type Node } from '../node';
|
|
35
26
|
import { atomFromQuery } from '../testing';
|
|
36
27
|
|
|
@@ -72,7 +63,7 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
|
|
|
72
63
|
id: space.id,
|
|
73
64
|
type: 'dxos.org/type/Space',
|
|
74
65
|
properties: {
|
|
75
|
-
label: get(
|
|
66
|
+
label: get(atomFromSignal(() => space.properties.name)),
|
|
76
67
|
},
|
|
77
68
|
data: space,
|
|
78
69
|
}));
|
|
@@ -85,16 +76,18 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
|
|
|
85
76
|
const objectBuilderExtension = createExtension({
|
|
86
77
|
id: 'object',
|
|
87
78
|
connector: (node) => {
|
|
88
|
-
|
|
79
|
+
// TODO(wittjosiah): Find a simpler way to define this type.
|
|
80
|
+
let result: Database.QueryResult<Schema.Schema.Type<typeof Type.Expando>> | undefined;
|
|
89
81
|
return Atom.make((get) =>
|
|
90
82
|
Function.pipe(
|
|
91
83
|
get(node),
|
|
92
84
|
Option.flatMap((node) => (isSpace(node.data) ? Option.some(node.data) : Option.none())),
|
|
93
85
|
Option.map((space) => {
|
|
94
|
-
if (!
|
|
95
|
-
|
|
86
|
+
if (!result) {
|
|
87
|
+
result = space.db.query(Query.type(Type.Expando, { type: 'test' }));
|
|
96
88
|
}
|
|
97
|
-
|
|
89
|
+
|
|
90
|
+
const objects = get(atomFromQuery(result));
|
|
98
91
|
return objects.map((object) => ({
|
|
99
92
|
id: object.id,
|
|
100
93
|
type: 'dxos.org/type/test',
|
|
@@ -116,7 +109,6 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
|
|
|
116
109
|
});
|
|
117
110
|
graph.expand(ROOT_ID);
|
|
118
111
|
(window as any).graph = graph;
|
|
119
|
-
|
|
120
112
|
return graph;
|
|
121
113
|
};
|
|
122
114
|
|
|
@@ -136,7 +128,7 @@ const getRandomSpace = (client: Client): Space | undefined => {
|
|
|
136
128
|
const getSpaceWithObjects = async (client: Client): Promise<Space | undefined> => {
|
|
137
129
|
const readySpaces = client.spaces.get().filter((space) => space.state.get() === SpaceState.SPACE_READY);
|
|
138
130
|
const spaceQueries = await Promise.all(
|
|
139
|
-
readySpaces.map((space) => space.db.query(Filter.type(Expando, { type: 'test' })).run()),
|
|
131
|
+
readySpaces.map((space) => space.db.query(Filter.type(Type.Expando, { type: 'test' })).run()),
|
|
140
132
|
);
|
|
141
133
|
const spaces = readySpaces.filter((space, index) => spaceQueries[index].objects.length > 0);
|
|
142
134
|
return spaces[Math.floor(Math.random() * spaces.length)];
|
|
@@ -172,7 +164,7 @@ const runAction = async (client: Client, action: Action) => {
|
|
|
172
164
|
case Action.REMOVE_OBJECT: {
|
|
173
165
|
const space = await getSpaceWithObjects(client);
|
|
174
166
|
if (space) {
|
|
175
|
-
const { objects } = await space.db.query(Filter.type(Expando, { type: 'test' })).run();
|
|
167
|
+
const { objects } = await space.db.query(Filter.type(Type.Expando, { type: 'test' })).run();
|
|
176
168
|
space.db.remove(objects[Math.floor(Math.random() * objects.length)]);
|
|
177
169
|
}
|
|
178
170
|
break;
|
|
@@ -181,7 +173,7 @@ const runAction = async (client: Client, action: Action) => {
|
|
|
181
173
|
case Action.RENAME_OBJECT: {
|
|
182
174
|
const space = await getSpaceWithObjects(client);
|
|
183
175
|
if (space) {
|
|
184
|
-
const { objects } = await space.db.query(Filter.type(Expando, { type: 'test' })).run();
|
|
176
|
+
const { objects } = await space.db.query(Filter.type(Type.Expando, { type: 'test' })).run();
|
|
185
177
|
objects[Math.floor(Math.random() * objects.length)].name = faker.commerce.productName();
|
|
186
178
|
}
|
|
187
179
|
break;
|
package/src/testing.ts
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
import { Atom } from '@effect-atom/atom-react';
|
|
6
6
|
|
|
7
|
-
import { type
|
|
8
|
-
import { type QueryResult } from '@dxos/echo-db';
|
|
7
|
+
import { type Database, type Entity } from '@dxos/echo';
|
|
9
8
|
|
|
10
|
-
export const atomFromQuery = <T extends
|
|
9
|
+
export const atomFromQuery = <T extends Entity.Unknown = Entity.Unknown>(
|
|
10
|
+
query: Database.QueryResult<T>,
|
|
11
|
+
): Atom.Atom<T[]> => {
|
|
11
12
|
return Atom.make((get) => {
|
|
12
13
|
const unsubscribe = query.subscribe((result) => {
|
|
13
14
|
get.setSelf(result.objects);
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
type Cb = () => void;
|
|
2
|
-
interface Query {
|
|
3
|
-
id?: string[];
|
|
4
|
-
typename?: string[];
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Lazy query result that can be executed.
|
|
8
|
-
* Does not run without the run function being called.
|
|
9
|
-
*/
|
|
10
|
-
interface QueryResult<T> {
|
|
11
|
-
/**
|
|
12
|
-
* Execute the query and subscribe to the result.
|
|
13
|
-
* @param next Called at least once with the first value (maybe synchronously) and then for every subsequent update.
|
|
14
|
-
* @param error Called on error. `next` is never called after that.
|
|
15
|
-
* @returns Function to dispose the query and unsubscribe.
|
|
16
|
-
*/
|
|
17
|
-
run(onData: (value?: T[]) => void, onError: (err: Error) => void): Cb;
|
|
18
|
-
}
|
|
19
|
-
declare const QueryResult: Readonly<{
|
|
20
|
-
fromPromise: <T>(run: (onDispose: (cb: Cb) => void) => Promise<T[]>) => QueryResult<T>;
|
|
21
|
-
}>;
|
|
22
|
-
interface _Resolver<T> {
|
|
23
|
-
query(query: Query): QueryResult<T>;
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=graph-projections.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"graph-projections.test.d.ts","sourceRoot":"","sources":["../../../../src/experimental/graph-projections.test.ts"],"names":[],"mappings":"AAIA,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC;AAErB,UAAU,KAAK;IACb,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,UAAU,WAAW,CAAC,CAAC;IACrB;;;;;OAKG;IACH,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,EAAE,CAAC;CACvE;AAED,QAAA,MAAM,WAAW;kBACD,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,IAAI,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,KAAG,WAAW,CAAC,CAAC,CAAC;EAyBpF,CAAC;AAEH,UAAU,SAAS,CAAC,CAAC;IACnB,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;CACrC"}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2025 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
type Cb = () => void;
|
|
6
|
-
|
|
7
|
-
interface Query {
|
|
8
|
-
id?: string[];
|
|
9
|
-
typename?: string[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Lazy query result that can be executed.
|
|
14
|
-
* Does not run without the run function being called.
|
|
15
|
-
*/
|
|
16
|
-
interface QueryResult<T> {
|
|
17
|
-
/**
|
|
18
|
-
* Execute the query and subscribe to the result.
|
|
19
|
-
* @param next Called at least once with the first value (maybe synchronously) and then for every subsequent update.
|
|
20
|
-
* @param error Called on error. `next` is never called after that.
|
|
21
|
-
* @returns Function to dispose the query and unsubscribe.
|
|
22
|
-
*/
|
|
23
|
-
run(onData: (value?: T[]) => void, onError: (err: Error) => void): Cb;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const QueryResult = Object.freeze({
|
|
27
|
-
fromPromise: <T>(run: (onDispose: (cb: Cb) => void) => Promise<T[]>): QueryResult<T> => {
|
|
28
|
-
return {
|
|
29
|
-
run: (onData, onError) => {
|
|
30
|
-
const cbs: Cb[] = [];
|
|
31
|
-
let disposed = false;
|
|
32
|
-
const dispose = () => {
|
|
33
|
-
cbs.forEach((cb) => cb());
|
|
34
|
-
disposed = true;
|
|
35
|
-
};
|
|
36
|
-
run((cb) => (disposed ? cb() : cbs.push(cb))).then(
|
|
37
|
-
(data) => {
|
|
38
|
-
if (disposed) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
onData(data);
|
|
42
|
-
},
|
|
43
|
-
(err) => {
|
|
44
|
-
dispose();
|
|
45
|
-
onError(err);
|
|
46
|
-
},
|
|
47
|
-
);
|
|
48
|
-
return dispose;
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
interface _Resolver<T> {
|
|
55
|
-
query(query: Query): QueryResult<T>;
|
|
56
|
-
}
|