@dxos/app-graph 0.8.4-main.84f28bd → 0.8.4-main.937b3ca
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 +1131 -612
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +1130 -612
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/atoms.d.ts +8 -0
- package/dist/types/src/atoms.d.ts.map +1 -0
- package/dist/types/src/graph-builder.d.ts +113 -60
- package/dist/types/src/graph-builder.d.ts.map +1 -1
- package/dist/types/src/graph.d.ts +183 -209
- package/dist/types/src/graph.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +6 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/node-matcher.d.ts +218 -0
- package/dist/types/src/node-matcher.d.ts.map +1 -0
- package/dist/types/src/node-matcher.test.d.ts +2 -0
- package/dist/types/src/node-matcher.test.d.ts.map +1 -0
- package/dist/types/src/node.d.ts +32 -3
- package/dist/types/src/node.d.ts.map +1 -1
- package/dist/types/src/stories/EchoGraph.stories.d.ts +8 -10
- package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +37 -37
- package/src/atoms.ts +25 -0
- package/src/graph-builder.test.ts +571 -97
- package/src/graph-builder.ts +600 -258
- package/src/graph.test.ts +300 -107
- package/src/graph.ts +971 -400
- package/src/index.ts +9 -3
- package/src/node-matcher.test.ts +301 -0
- package/src/node-matcher.ts +284 -0
- package/src/node.ts +40 -5
- package/src/stories/EchoGraph.stories.tsx +126 -114
- package/src/stories/Tree.tsx +2 -2
- 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/dist/types/src/signals-integration.test.d.ts +0 -2
- package/dist/types/src/signals-integration.test.d.ts.map +0 -1
- package/dist/types/src/testing.d.ts +0 -5
- package/dist/types/src/testing.d.ts.map +0 -1
- package/src/experimental/graph-projections.test.ts +0 -56
- package/src/signals-integration.test.ts +0 -218
- package/src/testing.ts +0 -20
|
@@ -2,40 +2,31 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import '@
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { type
|
|
10
|
-
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
isSpace,
|
|
16
|
-
Query,
|
|
17
|
-
type QueryResult,
|
|
18
|
-
type Space,
|
|
19
|
-
SpaceState,
|
|
20
|
-
Expando,
|
|
21
|
-
type Live,
|
|
22
|
-
Filter,
|
|
23
|
-
} from '@dxos/client/echo';
|
|
24
|
-
import { Obj, Type } from '@dxos/echo';
|
|
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';
|
|
9
|
+
import React, { type PropsWithChildren, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
10
|
+
|
|
11
|
+
import { Filter, type Space, SpaceState, isSpace } from '@dxos/client/echo';
|
|
12
|
+
import { Obj, Query } from '@dxos/echo';
|
|
13
|
+
import { TestSchema } from '@dxos/echo/testing';
|
|
14
|
+
import { AtomObj, AtomQuery } from '@dxos/echo-atom';
|
|
25
15
|
import { faker } from '@dxos/random';
|
|
26
16
|
import { type Client, useClient } from '@dxos/react-client';
|
|
27
17
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
28
|
-
import {
|
|
18
|
+
import { Icon, IconButton, Input, Select } from '@dxos/react-ui';
|
|
19
|
+
import { withTheme } from '@dxos/react-ui/testing';
|
|
29
20
|
import { Path, Tree } from '@dxos/react-ui-list';
|
|
30
|
-
import { getSize, mx } from '@dxos/
|
|
31
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
21
|
+
import { getSize, mx } from '@dxos/ui-theme';
|
|
32
22
|
import { byPosition, isNonNullable, safeParseInt } from '@dxos/util';
|
|
33
23
|
|
|
24
|
+
import * as CreateAtom from '../atoms';
|
|
25
|
+
import * as Graph from '../graph';
|
|
26
|
+
import * as GraphBuilder from '../graph-builder';
|
|
27
|
+
import * as Node from '../node';
|
|
28
|
+
|
|
34
29
|
import { JsonTree } from './Tree';
|
|
35
|
-
import { type ExpandableGraph, ROOT_ID } from '../graph';
|
|
36
|
-
import { GraphBuilder, createExtension, rxFromObservable, rxFromSignal } from '../graph-builder';
|
|
37
|
-
import { type Node } from '../node';
|
|
38
|
-
import { rxFromQuery } from '../testing';
|
|
39
30
|
|
|
40
31
|
const DEFAULT_PERIOD = 500;
|
|
41
32
|
|
|
@@ -57,43 +48,44 @@ const actionWeights = {
|
|
|
57
48
|
[Action.RENAME_OBJECT]: 4,
|
|
58
49
|
};
|
|
59
50
|
|
|
60
|
-
const createGraph = (client: Client, registry: Registry.Registry): ExpandableGraph => {
|
|
61
|
-
const spaceBuilderExtension =
|
|
51
|
+
const createGraph = (client: Client, registry: Registry.Registry): Graph.ExpandableGraph => {
|
|
52
|
+
const spaceBuilderExtension = GraphBuilder.createExtensionRaw({
|
|
62
53
|
id: 'space',
|
|
63
54
|
connector: (node) =>
|
|
64
|
-
|
|
65
|
-
pipe(
|
|
55
|
+
Atom.make((get) =>
|
|
56
|
+
Function.pipe(
|
|
66
57
|
get(node),
|
|
67
|
-
Option.flatMap((node) => (node.id ===
|
|
58
|
+
Option.flatMap((node) => (node.id === Node.RootId ? Option.some(node) : Option.none())),
|
|
68
59
|
Option.map(() => {
|
|
69
|
-
const spaces = get(
|
|
60
|
+
const spaces = get(CreateAtom.fromObservable(client.spaces)) ?? [];
|
|
70
61
|
return spaces
|
|
71
|
-
.filter((space) => get(
|
|
72
|
-
.map((space) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
62
|
+
.filter((space: any) => get(CreateAtom.fromObservable(space.state)) === SpaceState.SPACE_READY)
|
|
63
|
+
.map((space) => {
|
|
64
|
+
const propertiesSnapshot = get(AtomObj.make(space.properties));
|
|
65
|
+
return {
|
|
66
|
+
id: space.id,
|
|
67
|
+
type: 'dxos.org/type/Space',
|
|
68
|
+
properties: {
|
|
69
|
+
label: propertiesSnapshot.name,
|
|
70
|
+
},
|
|
71
|
+
data: space,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
78
74
|
}),
|
|
79
75
|
Option.getOrElse(() => []),
|
|
80
76
|
),
|
|
81
77
|
),
|
|
82
78
|
});
|
|
83
79
|
|
|
84
|
-
const objectBuilderExtension =
|
|
80
|
+
const objectBuilderExtension = GraphBuilder.createExtensionRaw({
|
|
85
81
|
id: 'object',
|
|
86
82
|
connector: (node) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
pipe(
|
|
83
|
+
return Atom.make((get) =>
|
|
84
|
+
Function.pipe(
|
|
90
85
|
get(node),
|
|
91
86
|
Option.flatMap((node) => (isSpace(node.data) ? Option.some(node.data) : Option.none())),
|
|
92
87
|
Option.map((space) => {
|
|
93
|
-
|
|
94
|
-
query = space.db.query(Query.type(Expando, { type: 'test' }));
|
|
95
|
-
}
|
|
96
|
-
const objects = get(rxFromQuery(query));
|
|
88
|
+
const objects = get(AtomQuery.make(space.db, Query.type(TestSchema.Expando, { type: 'test' })));
|
|
97
89
|
return objects.map((object) => ({
|
|
98
90
|
id: object.id,
|
|
99
91
|
type: 'dxos.org/type/test',
|
|
@@ -107,15 +99,15 @@ const createGraph = (client: Client, registry: Registry.Registry): ExpandableGra
|
|
|
107
99
|
},
|
|
108
100
|
});
|
|
109
101
|
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
102
|
+
const builder = GraphBuilder.make({ registry });
|
|
103
|
+
GraphBuilder.addExtension(builder, spaceBuilderExtension);
|
|
104
|
+
GraphBuilder.addExtension(builder, objectBuilderExtension);
|
|
105
|
+
const graph = builder.graph;
|
|
113
106
|
graph.onNodeChanged.on(({ id }) => {
|
|
114
|
-
|
|
107
|
+
Graph.expand(graph, id);
|
|
115
108
|
});
|
|
116
|
-
|
|
109
|
+
Graph.expand(graph, Node.RootId);
|
|
117
110
|
(window as any).graph = graph;
|
|
118
|
-
|
|
119
111
|
return graph;
|
|
120
112
|
};
|
|
121
113
|
|
|
@@ -135,9 +127,9 @@ const getRandomSpace = (client: Client): Space | undefined => {
|
|
|
135
127
|
const getSpaceWithObjects = async (client: Client): Promise<Space | undefined> => {
|
|
136
128
|
const readySpaces = client.spaces.get().filter((space) => space.state.get() === SpaceState.SPACE_READY);
|
|
137
129
|
const spaceQueries = await Promise.all(
|
|
138
|
-
readySpaces.map((space) => space.db.query(Filter.type(Expando, { type: 'test' })).run()),
|
|
130
|
+
readySpaces.map((space) => space.db.query(Filter.type(TestSchema.Expando, { type: 'test' })).run()),
|
|
139
131
|
);
|
|
140
|
-
const spaces = readySpaces.filter((space, index) => spaceQueries[index].
|
|
132
|
+
const spaces = readySpaces.filter((space, index) => spaceQueries[index].length > 0);
|
|
141
133
|
return spaces[Math.floor(Math.random() * spaces.length)];
|
|
142
134
|
};
|
|
143
135
|
|
|
@@ -154,19 +146,26 @@ const runAction = async (client: Client, action: Action) => {
|
|
|
154
146
|
case Action.RENAME_SPACE: {
|
|
155
147
|
const space = getRandomSpace(client);
|
|
156
148
|
if (space) {
|
|
157
|
-
space.properties
|
|
149
|
+
Obj.change(space.properties, (p) => {
|
|
150
|
+
p.name = faker.commerce.productName();
|
|
151
|
+
});
|
|
158
152
|
}
|
|
159
153
|
break;
|
|
160
154
|
}
|
|
161
155
|
|
|
162
156
|
case Action.ADD_OBJECT:
|
|
163
|
-
getRandomSpace(client)?.db.add(
|
|
157
|
+
getRandomSpace(client)?.db.add(
|
|
158
|
+
Obj.make(TestSchema.Expando, {
|
|
159
|
+
type: 'test',
|
|
160
|
+
name: faker.commerce.productName(),
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
164
163
|
break;
|
|
165
164
|
|
|
166
165
|
case Action.REMOVE_OBJECT: {
|
|
167
166
|
const space = await getSpaceWithObjects(client);
|
|
168
167
|
if (space) {
|
|
169
|
-
const
|
|
168
|
+
const objects = await space.db.query(Filter.type(TestSchema.Expando, { type: 'test' })).run();
|
|
170
169
|
space.db.remove(objects[Math.floor(Math.random() * objects.length)]);
|
|
171
170
|
}
|
|
172
171
|
break;
|
|
@@ -175,8 +174,11 @@ const runAction = async (client: Client, action: Action) => {
|
|
|
175
174
|
case Action.RENAME_OBJECT: {
|
|
176
175
|
const space = await getSpaceWithObjects(client);
|
|
177
176
|
if (space) {
|
|
178
|
-
const
|
|
179
|
-
objects[Math.floor(Math.random() * objects.length)]
|
|
177
|
+
const objects = await space.db.query(Filter.type(TestSchema.Expando, { type: 'test' })).run();
|
|
178
|
+
const object = objects[Math.floor(Math.random() * objects.length)];
|
|
179
|
+
Obj.change(object, (o) => {
|
|
180
|
+
o.name = faker.commerce.productName();
|
|
181
|
+
});
|
|
180
182
|
}
|
|
181
183
|
break;
|
|
182
184
|
}
|
|
@@ -205,23 +207,25 @@ const Controls = ({ children }: PropsWithChildren) => {
|
|
|
205
207
|
return (
|
|
206
208
|
<>
|
|
207
209
|
<div className='flex shrink-0 p-2 space-x-2'>
|
|
208
|
-
<
|
|
210
|
+
<IconButton
|
|
211
|
+
icon={generating ? 'ph--pause--regular' : 'ph--play--regular'}
|
|
212
|
+
label={generating ? 'Pause' : 'Play'}
|
|
213
|
+
onClick={() => setGenerating((generating) => !generating)}
|
|
214
|
+
/>
|
|
209
215
|
<div className='relative' title='mutation period'>
|
|
210
216
|
<Input.Root>
|
|
211
217
|
<Input.TextInput
|
|
212
218
|
autoComplete='off'
|
|
213
219
|
size={5}
|
|
214
|
-
classNames='
|
|
220
|
+
classNames='is-[100px] text-right pie-[22px]'
|
|
215
221
|
placeholder='Interval'
|
|
216
222
|
value={actionInterval}
|
|
217
223
|
onChange={({ target: { value } }) => setActionInterval(value)}
|
|
218
224
|
/>
|
|
219
225
|
</Input.Root>
|
|
220
|
-
<
|
|
226
|
+
<Icon icon='ph--timer--regular' classNames={mx('absolute inline-end-1 block-start-1 mt-[6px]', getSize(3))} />
|
|
221
227
|
</div>
|
|
222
|
-
<
|
|
223
|
-
<Plus />
|
|
224
|
-
</Button>
|
|
228
|
+
<IconButton icon='ph--plus--regular' label='Add' onClick={() => action && runAction(client, action)} />
|
|
225
229
|
<Select.Root value={action?.toString()} onValueChange={(action) => setAction(action as unknown as Action)}>
|
|
226
230
|
<Select.TriggerButton placeholder='Select value' />
|
|
227
231
|
<Select.Portal>
|
|
@@ -245,28 +249,30 @@ const Controls = ({ children }: PropsWithChildren) => {
|
|
|
245
249
|
);
|
|
246
250
|
};
|
|
247
251
|
|
|
248
|
-
const meta
|
|
252
|
+
const meta = {
|
|
249
253
|
title: 'sdk/app-graph/EchoGraph',
|
|
250
254
|
decorators: [
|
|
255
|
+
withTheme,
|
|
251
256
|
withClientProvider({
|
|
252
257
|
createIdentity: true,
|
|
253
|
-
|
|
258
|
+
onCreateIdentity: async ({ client }) => {
|
|
254
259
|
await client.spaces.create();
|
|
255
260
|
await client.spaces.create();
|
|
256
261
|
},
|
|
257
262
|
}),
|
|
258
|
-
withTheme,
|
|
259
263
|
],
|
|
260
|
-
};
|
|
264
|
+
} satisfies Meta;
|
|
261
265
|
|
|
262
266
|
export default meta;
|
|
263
267
|
|
|
264
|
-
|
|
268
|
+
type Story = StoryObj<typeof meta>;
|
|
269
|
+
|
|
270
|
+
export const JsonView: Story = {
|
|
265
271
|
render: () => {
|
|
266
272
|
const client = useClient();
|
|
267
273
|
const registry = useContext(RegistryContext);
|
|
268
274
|
const graph = useMemo(() => createGraph(client, registry), [client, registry]);
|
|
269
|
-
const data =
|
|
275
|
+
const data = useAtomValue(graph.json());
|
|
270
276
|
|
|
271
277
|
return (
|
|
272
278
|
<>
|
|
@@ -277,31 +283,42 @@ export const JsonView = {
|
|
|
277
283
|
},
|
|
278
284
|
};
|
|
279
285
|
|
|
280
|
-
export const TreeView = {
|
|
286
|
+
export const TreeView: Story = {
|
|
281
287
|
render: () => {
|
|
282
288
|
const client = useClient();
|
|
283
289
|
const registry = useContext(RegistryContext);
|
|
284
290
|
const graph = useMemo(() => createGraph(client, registry), [client, registry]);
|
|
285
|
-
const
|
|
291
|
+
const stateRef = useRef(new Map<string, Atom.Writable<{ open: boolean; current: boolean }>>());
|
|
292
|
+
|
|
293
|
+
const getOrCreateState = useMemo(
|
|
294
|
+
() => (path: string) => {
|
|
295
|
+
let atom = stateRef.current.get(path);
|
|
296
|
+
if (!atom) {
|
|
297
|
+
atom = Atom.make({ open: true, current: false }).pipe(Atom.keepAlive);
|
|
298
|
+
stateRef.current.set(path, atom);
|
|
299
|
+
}
|
|
300
|
+
return atom;
|
|
301
|
+
},
|
|
302
|
+
[],
|
|
303
|
+
);
|
|
286
304
|
|
|
287
305
|
const useItems = useCallback(
|
|
288
|
-
(node?: Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
289
|
-
const connections =
|
|
306
|
+
(node?: Node.Node, options?: { disposition?: string; sort?: boolean }) => {
|
|
307
|
+
const connections = useAtomValue(graph.connections(node?.id ?? Node.RootId));
|
|
290
308
|
return options?.sort ? connections.toSorted((a, b) => byPosition(a.properties, b.properties)) : connections;
|
|
291
309
|
},
|
|
292
310
|
[graph],
|
|
293
311
|
);
|
|
294
312
|
|
|
295
313
|
const getProps = useCallback(
|
|
296
|
-
(node: Node, path: string[]) => {
|
|
297
|
-
const children = graph
|
|
298
|
-
.getConnections(node.id, 'outbound')
|
|
314
|
+
(node: Node.Node, path: string[]) => {
|
|
315
|
+
const children = Graph.getConnections(graph, node.id, 'outbound')
|
|
299
316
|
.map((n) => {
|
|
300
317
|
// Break cycles.
|
|
301
318
|
const nextPath = [...path, node.id];
|
|
302
|
-
return nextPath.includes(n.id) ? undefined : (n as Node);
|
|
319
|
+
return nextPath.includes(n.id) ? undefined : (n as Node.Node);
|
|
303
320
|
})
|
|
304
|
-
.filter(isNonNullable) as Node[];
|
|
321
|
+
.filter(isNonNullable) as Node.Node[];
|
|
305
322
|
const parentOf =
|
|
306
323
|
children.length > 0 ? children.map(({ id }) => id) : node.properties.role === 'branch' ? [] : undefined;
|
|
307
324
|
return {
|
|
@@ -314,59 +331,54 @@ export const TreeView = {
|
|
|
314
331
|
[graph],
|
|
315
332
|
);
|
|
316
333
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}
|
|
334
|
+
// Hook that subscribes to item state via Atom.
|
|
335
|
+
const useItemState = (_path: string[]) => {
|
|
336
|
+
const path = useMemo(() => Path.create(..._path), [_path.join('~')]);
|
|
337
|
+
const atom = getOrCreateState(path);
|
|
338
|
+
return useAtomValue(atom);
|
|
339
|
+
};
|
|
324
340
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
);
|
|
341
|
+
const useIsOpen = (_path: string[]) => {
|
|
342
|
+
return useItemState(_path).open;
|
|
343
|
+
};
|
|
329
344
|
|
|
330
|
-
const
|
|
331
|
-
(_path
|
|
332
|
-
|
|
333
|
-
const object = state.get(path) ?? live({ open: false, current: false });
|
|
334
|
-
if (!state.has(path)) {
|
|
335
|
-
state.set(path, object);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return object.current;
|
|
339
|
-
},
|
|
340
|
-
[state],
|
|
341
|
-
);
|
|
345
|
+
const useIsCurrent = (_path: string[]) => {
|
|
346
|
+
return useItemState(_path).current;
|
|
347
|
+
};
|
|
342
348
|
|
|
343
349
|
const onOpenChange = useCallback(
|
|
344
350
|
({ path: _path, open }: { path: string[]; open: boolean }) => {
|
|
345
351
|
const path = Path.create(..._path);
|
|
346
|
-
const
|
|
347
|
-
|
|
352
|
+
const atom = stateRef.current.get(path);
|
|
353
|
+
if (atom) {
|
|
354
|
+
const prev = registry.get(atom);
|
|
355
|
+
registry.set(atom, { ...prev, open });
|
|
356
|
+
}
|
|
348
357
|
},
|
|
349
|
-
[
|
|
358
|
+
[registry],
|
|
350
359
|
);
|
|
351
360
|
|
|
352
361
|
const onSelect = useCallback(
|
|
353
362
|
({ path: _path, current }: { path: string[]; current: boolean }) => {
|
|
354
363
|
const path = Path.create(..._path);
|
|
355
|
-
const
|
|
356
|
-
|
|
364
|
+
const atom = stateRef.current.get(path);
|
|
365
|
+
if (atom) {
|
|
366
|
+
const prev = registry.get(atom);
|
|
367
|
+
registry.set(atom, { ...prev, current });
|
|
368
|
+
}
|
|
357
369
|
},
|
|
358
|
-
[
|
|
370
|
+
[registry],
|
|
359
371
|
);
|
|
360
372
|
|
|
361
373
|
return (
|
|
362
374
|
<>
|
|
363
375
|
<Controls />
|
|
364
376
|
<Tree
|
|
365
|
-
id={
|
|
377
|
+
id={Node.RootId}
|
|
366
378
|
useItems={useItems}
|
|
367
379
|
getProps={getProps}
|
|
368
|
-
|
|
369
|
-
|
|
380
|
+
useIsOpen={useIsOpen}
|
|
381
|
+
useIsCurrent={useIsCurrent}
|
|
370
382
|
onOpenChange={onOpenChange}
|
|
371
383
|
onSelect={onSelect}
|
|
372
384
|
/>
|
package/src/stories/Tree.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import React, { type FC, type HTMLAttributes, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { mx } from '@dxos/
|
|
7
|
+
import { mx } from '@dxos/ui-theme';
|
|
8
8
|
|
|
9
9
|
// TODO(burdon): Copied form devtools.
|
|
10
10
|
|
|
@@ -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
|
|
75
|
+
<div className={mx('flex pli-2 border border-l-0 font-mono truncate', className)} {...props}>
|
|
76
76
|
{children}
|
|
77
77
|
</div>
|
|
78
78
|
);
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signals-integration.test.d.ts","sourceRoot":"","sources":["../../../src/signals-integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { Rx } from '@effect-rx/rx-react';
|
|
2
|
-
import { type QueryResult } from '@dxos/echo-db';
|
|
3
|
-
import { type AnyEchoObject } from '@dxos/echo-schema';
|
|
4
|
-
export declare const rxFromQuery: <T extends AnyEchoObject>(query: QueryResult<T>) => Rx.Rx<T[]>;
|
|
5
|
-
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/testing.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAEzC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,aAAa,EAAE,OAAO,WAAW,CAAC,CAAC,CAAC,KAAG,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAUrF,CAAC"}
|
|
@@ -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
|
-
}
|