@dxos/app-graph 0.8.3 → 0.8.4-main.03d5cd7b56

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.
Files changed (73) hide show
  1. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  2. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  3. package/dist/lib/neutral/chunk-WJJ5KEOH.mjs +1477 -0
  4. package/dist/lib/neutral/chunk-WJJ5KEOH.mjs.map +7 -0
  5. package/dist/lib/neutral/index.mjs +40 -0
  6. package/dist/lib/neutral/index.mjs.map +7 -0
  7. package/dist/lib/neutral/meta.json +1 -0
  8. package/dist/lib/neutral/scheduler.mjs +15 -0
  9. package/dist/lib/neutral/scheduler.mjs.map +7 -0
  10. package/dist/lib/neutral/testing/index.mjs +40 -0
  11. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  12. package/dist/types/src/atoms.d.ts +8 -0
  13. package/dist/types/src/atoms.d.ts.map +1 -0
  14. package/dist/types/src/graph-builder.d.ts +117 -60
  15. package/dist/types/src/graph-builder.d.ts.map +1 -1
  16. package/dist/types/src/graph.d.ts +188 -218
  17. package/dist/types/src/graph.d.ts.map +1 -1
  18. package/dist/types/src/index.d.ts +7 -3
  19. package/dist/types/src/index.d.ts.map +1 -1
  20. package/dist/types/src/node-matcher.d.ts +244 -0
  21. package/dist/types/src/node-matcher.d.ts.map +1 -0
  22. package/dist/types/src/node-matcher.test.d.ts +2 -0
  23. package/dist/types/src/node-matcher.test.d.ts.map +1 -0
  24. package/dist/types/src/node.d.ts +50 -5
  25. package/dist/types/src/node.d.ts.map +1 -1
  26. package/dist/types/src/scheduler.browser.d.ts +2 -0
  27. package/dist/types/src/scheduler.browser.d.ts.map +1 -0
  28. package/dist/types/src/scheduler.d.ts +8 -0
  29. package/dist/types/src/scheduler.d.ts.map +1 -0
  30. package/dist/types/src/stories/EchoGraph.stories.d.ts +6 -13
  31. package/dist/types/src/stories/EchoGraph.stories.d.ts.map +1 -1
  32. package/dist/types/src/testing/index.d.ts +2 -0
  33. package/dist/types/src/testing/index.d.ts.map +1 -0
  34. package/dist/types/src/testing/setup-graph-builder.d.ts +31 -0
  35. package/dist/types/src/testing/setup-graph-builder.d.ts.map +1 -0
  36. package/dist/types/src/util.d.ts +40 -0
  37. package/dist/types/src/util.d.ts.map +1 -0
  38. package/dist/types/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +53 -42
  40. package/src/atoms.ts +25 -0
  41. package/src/graph-builder.test.ts +1193 -126
  42. package/src/graph-builder.ts +753 -264
  43. package/src/graph.test.ts +451 -123
  44. package/src/graph.ts +1057 -407
  45. package/src/index.ts +10 -3
  46. package/src/node-matcher.test.ts +301 -0
  47. package/src/node-matcher.ts +314 -0
  48. package/src/node.ts +83 -7
  49. package/src/scheduler.browser.ts +5 -0
  50. package/src/scheduler.ts +17 -0
  51. package/src/stories/EchoGraph.stories.tsx +178 -255
  52. package/src/stories/Tree.tsx +1 -1
  53. package/src/testing/index.ts +5 -0
  54. package/src/testing/setup-graph-builder.ts +41 -0
  55. package/src/util.ts +101 -0
  56. package/dist/lib/browser/index.mjs +0 -778
  57. package/dist/lib/browser/index.mjs.map +0 -7
  58. package/dist/lib/browser/meta.json +0 -1
  59. package/dist/lib/node/index.cjs +0 -816
  60. package/dist/lib/node/index.cjs.map +0 -7
  61. package/dist/lib/node/meta.json +0 -1
  62. package/dist/lib/node-esm/index.mjs +0 -780
  63. package/dist/lib/node-esm/index.mjs.map +0 -7
  64. package/dist/lib/node-esm/meta.json +0 -1
  65. package/dist/types/src/experimental/graph-projections.test.d.ts +0 -25
  66. package/dist/types/src/experimental/graph-projections.test.d.ts.map +0 -1
  67. package/dist/types/src/signals-integration.test.d.ts +0 -2
  68. package/dist/types/src/signals-integration.test.d.ts.map +0 -1
  69. package/dist/types/src/testing.d.ts +0 -5
  70. package/dist/types/src/testing.d.ts.map +0 -1
  71. package/src/experimental/graph-projections.test.ts +0 -56
  72. package/src/signals-integration.test.ts +0 -218
  73. package/src/testing.ts +0 -20
package/src/node.ts CHANGED
@@ -2,7 +2,30 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { type MaybePromise, type MakeOptional } from '@dxos/util';
5
+ import type * as Context from 'effect/Context';
6
+ import type * as Effect from 'effect/Effect';
7
+
8
+ import { type MakeOptional } from '@dxos/util';
9
+
10
+ /**
11
+ * Root node ID.
12
+ */
13
+ export const RootId = 'root';
14
+
15
+ /**
16
+ * Root node type.
17
+ */
18
+ export const RootType = 'org.dxos.type.graphRoot';
19
+
20
+ /**
21
+ * Action node type.
22
+ */
23
+ export const ActionType = 'org.dxos.type.graphAction';
24
+
25
+ /**
26
+ * Action group node type.
27
+ */
28
+ export const ActionGroupType = 'org.dxos.type.graphActionGroup';
6
29
 
7
30
  /**
8
31
  * Represents a node in the graph.
@@ -46,7 +69,19 @@ export type NodeFilter<TData = any, TProperties extends Record<string, any> = Re
46
69
  connectedNode: Node,
47
70
  ) => node is Node<TData, TProperties>;
48
71
 
49
- export type Relation = 'outbound' | 'inbound';
72
+ export type RelationDirection = 'outbound' | 'inbound';
73
+
74
+ export type Relation = Readonly<{
75
+ kind: string;
76
+ direction: RelationDirection;
77
+ }>;
78
+
79
+ export type RelationInput = Relation | string;
80
+
81
+ export const relation = (kind: string, direction: RelationDirection = 'outbound'): Relation => ({ kind, direction });
82
+ // TODO(wittjosiah): Consider moving these helpers out of the core API.
83
+ export const childRelation = (direction: RelationDirection = 'outbound'): Relation => relation('child', direction);
84
+ export const actionRelation = (direction: RelationDirection = 'outbound'): Relation => relation('action', direction);
50
85
 
51
86
  export const isGraphNode = (data: unknown): data is Node =>
52
87
  data && typeof data === 'object' && 'id' in data && 'properties' in data && data.properties
@@ -61,30 +96,45 @@ export type NodeArg<TData, TProperties extends Record<string, any> = Record<stri
61
96
  nodes?: NodeArg<unknown>[];
62
97
 
63
98
  /** Will automatically add specified edges. */
64
- edges?: [string, Relation][];
99
+ edges?: [string, RelationInput][];
65
100
  };
66
101
 
67
102
  //
68
103
  // Actions
69
104
  //
70
105
 
71
- export type InvokeParams = {
106
+ export type InvokeProps = {
72
107
  /** Node the invoked action is connected to. */
73
108
  parent?: Node;
74
109
 
110
+ /** Path from root to the node in the current tree context. */
111
+ path?: string[];
112
+
75
113
  caller?: string;
76
114
  };
77
115
 
78
- export type ActionData = (params?: InvokeParams) => MaybePromise<void>;
116
+ /**
117
+ * Action data is an Effect-returning function.
118
+ * The Effect is provided with captured context at execution time.
119
+ */
120
+ export type ActionData<R = never> = (params?: InvokeProps) => Effect.Effect<any, Error, R>;
121
+
122
+ /**
123
+ * Context captured at extension creation time.
124
+ * Automatically provided to action Effects at execution.
125
+ */
126
+ export type ActionContext = Context.Context<any>;
79
127
 
80
128
  export type Action<TProperties extends Record<string, any> = Record<string, any>> = Readonly<
81
129
  Omit<Node<ActionData, TProperties>, 'properties'> & {
82
130
  properties: Readonly<TProperties>;
131
+ /** Captured context from extension creation. Provided automatically at action execution. */
132
+ _actionContext?: ActionContext;
83
133
  }
84
134
  >;
85
135
 
86
136
  export const isAction = (data: unknown): data is Action =>
87
- isGraphNode(data) ? typeof data.data === 'function' : false;
137
+ isGraphNode(data) ? typeof data.data === 'function' && data.type === ActionType : false;
88
138
 
89
139
  export const actionGroupSymbol = Symbol('ActionGroup');
90
140
 
@@ -95,8 +145,34 @@ export type ActionGroup<TProperties extends Record<string, any> = Record<string,
95
145
  >;
96
146
 
97
147
  export const isActionGroup = (data: unknown): data is ActionGroup =>
98
- isGraphNode(data) ? data.data === actionGroupSymbol : false;
148
+ isGraphNode(data) ? data.data === actionGroupSymbol && data.type === ActionGroupType : false;
99
149
 
100
150
  export type ActionLike = Action | ActionGroup;
101
151
 
102
152
  export const isActionLike = (data: unknown): data is Action | ActionGroup => isAction(data) || isActionGroup(data);
153
+
154
+ //
155
+ // Node Factories
156
+ //
157
+
158
+ /** Typed factory for constructing a NodeArg. Provides auto-complete and type validation. */
159
+ export const make = <TData = any, TProperties extends Record<string, any> = Record<string, any>>(
160
+ arg: NodeArg<TData, TProperties>,
161
+ ): NodeArg<TData, TProperties> => arg;
162
+
163
+ /** Create an action node. Automatically sets `type: ActionType`. */
164
+ export const makeAction = <R = never>(
165
+ arg: Omit<NodeArg<ActionData<R>>, 'type' | 'nodes' | 'edges'>,
166
+ ): NodeArg<ActionData<R>> => ({
167
+ ...arg,
168
+ type: ActionType,
169
+ });
170
+
171
+ /** Create an action group node. Automatically sets `type` and `data`. */
172
+ export const makeActionGroup = (
173
+ arg: Omit<NodeArg<typeof actionGroupSymbol>, 'type' | 'data' | 'nodes' | 'edges'>,
174
+ ): NodeArg<typeof actionGroupSymbol> => ({
175
+ ...arg,
176
+ type: ActionGroupType,
177
+ data: actionGroupSymbol,
178
+ });
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export { scheduleTask, yieldOrContinue } from 'main-thread-scheduling';
@@ -0,0 +1,17 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ // CF Workers / Node fallback: there is no main thread to yield to.
6
+ // scheduleTask runs the callback on the next microtask; yieldOrContinue is a microtask hop.
7
+
8
+ type ScheduleOptions = { strategy?: 'smooth' | 'interactive' | 'idle'; signal?: AbortSignal };
9
+
10
+ export const scheduleTask = async <T>(callback: () => T | Promise<T>, _options?: ScheduleOptions): Promise<T> => {
11
+ await Promise.resolve();
12
+ return callback();
13
+ };
14
+
15
+ export const yieldOrContinue = async (_priority: 'smooth' | 'interactive' | 'idle'): Promise<void> => {
16
+ await Promise.resolve();
17
+ };