@dxos/plugin-explorer 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.13.0

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 (174) hide show
  1. package/PLUGIN.mdl +63 -10
  2. package/dist/lib/ForceGraph.mjs +2 -0
  3. package/dist/lib/Graph.mjs +4 -5
  4. package/dist/lib/Graph.mjs.map +1 -1
  5. package/dist/lib/capabilities.browser.mjs +21 -0
  6. package/dist/lib/capabilities.browser.mjs.map +1 -0
  7. package/dist/lib/capabilities.mjs +1 -3
  8. package/dist/lib/capabilities.mjs.map +1 -1
  9. package/dist/lib/capabilities.node.mjs.map +1 -1
  10. package/dist/lib/capabilities.tauri.mjs +21 -0
  11. package/dist/lib/capabilities.tauri.mjs.map +1 -0
  12. package/dist/lib/capabilities.workerd.mjs.map +1 -1
  13. package/dist/lib/chunk-ExplorerArticle.mjs +27 -30
  14. package/dist/lib/chunk-ExplorerArticle.mjs.map +1 -1
  15. package/dist/lib/chunk-Graph.mjs +161 -0
  16. package/dist/lib/chunk-Graph.mjs.map +1 -0
  17. package/dist/lib/chunk-NeighborhoodCompanion.mjs +26 -22
  18. package/dist/lib/chunk-NeighborhoodCompanion.mjs.map +1 -1
  19. package/dist/lib/chunk-PLUGIN.mjs +6 -0
  20. package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
  21. package/dist/lib/chunk-app-graph-builder.mjs +2 -1
  22. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -1
  23. package/dist/lib/chunk-create-object.mjs +1 -1
  24. package/dist/lib/chunk-react-surface.mjs +2 -2
  25. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  26. package/dist/lib/chunk-rolldown-runtime.mjs +15 -1
  27. package/dist/lib/{chunk-types.mjs → chunk-tree.mjs} +29 -26
  28. package/dist/lib/chunk-tree.mjs.map +1 -0
  29. package/dist/lib/components.mjs +15 -164
  30. package/dist/lib/components.mjs.map +1 -1
  31. package/dist/lib/containers.mjs.map +1 -1
  32. package/dist/lib/hooks.mjs +2 -2
  33. package/dist/lib/hooks.mjs.map +1 -1
  34. package/dist/lib/index.mjs +3 -2
  35. package/dist/lib/meta.mjs.map +1 -1
  36. package/dist/lib/ns/ForceGraph.mjs +11 -0
  37. package/dist/lib/ns/ForceGraph.mjs.map +1 -0
  38. package/dist/lib/ns/Hooks.mjs +10 -0
  39. package/dist/lib/ns/Hooks.mjs.map +1 -0
  40. package/dist/lib/testing.mjs +9 -9
  41. package/dist/lib/testing.mjs.map +1 -1
  42. package/dist/lib/translations.mjs +2 -2
  43. package/dist/lib/translations.mjs.map +1 -1
  44. package/dist/types/src/ForceGraph.d.ts +3 -0
  45. package/dist/types/src/ForceGraph.d.ts.map +1 -0
  46. package/dist/types/src/Hooks.d.ts +2 -0
  47. package/dist/types/src/Hooks.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/gen/browser.d.ts +7 -0
  49. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
  50. package/dist/types/src/capabilities/gen/node.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/gen/tauri.d.ts +7 -0
  52. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
  53. package/dist/types/src/capabilities/gen/workerd.d.ts.map +1 -1
  54. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  55. package/dist/types/src/components/Chart/Chart.d.ts +1 -1
  56. package/dist/types/src/components/Chart/Chart.d.ts.map +1 -1
  57. package/dist/types/src/components/Chart/Chart.stories.d.ts +1 -1
  58. package/dist/types/src/components/Chart/Chart.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/Chart/index.d.ts +1 -1
  60. package/dist/types/src/components/Chart/index.d.ts.map +1 -1
  61. package/dist/types/src/components/Globe/Globe.d.ts +1 -1
  62. package/dist/types/src/components/Globe/Globe.d.ts.map +1 -1
  63. package/dist/types/src/components/Globe/Globe.stories.d.ts +1 -1
  64. package/dist/types/src/components/Globe/Globe.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Globe/index.d.ts +1 -1
  66. package/dist/types/src/components/Globe/index.d.ts.map +1 -1
  67. package/dist/types/src/components/Graph/CanvasForceGraph.stories.d.ts +1 -1
  68. package/dist/types/src/components/Graph/ForceGraph.d.ts +2 -2
  69. package/dist/types/src/components/Graph/ForceGraph.d.ts.map +1 -1
  70. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts +1 -1
  71. package/dist/types/src/components/Graph/ForceGraph.stories.d.ts.map +1 -1
  72. package/dist/types/src/components/Graph/index.d.ts +2 -2
  73. package/dist/types/src/components/Graph/index.d.ts.map +1 -1
  74. package/dist/types/src/components/Lattice/index.d.ts +1 -1
  75. package/dist/types/src/components/Lattice/index.d.ts.map +1 -1
  76. package/dist/types/src/components/Tree/index.d.ts +1 -1
  77. package/dist/types/src/components/Tree/index.d.ts.map +1 -1
  78. package/dist/types/src/components/Tree/types/index.d.ts +2 -2
  79. package/dist/types/src/components/Tree/types/index.d.ts.map +1 -1
  80. package/dist/types/src/components/Tree/types/tree.d.ts.map +1 -1
  81. package/dist/types/src/components/Tree/types/types.d.ts +1 -1
  82. package/dist/types/src/components/Tree/types/types.d.ts.map +1 -1
  83. package/dist/types/src/components/Visualization/Visualization.d.ts +1 -1
  84. package/dist/types/src/components/Visualization/Visualization.d.ts.map +1 -1
  85. package/dist/types/src/components/Visualization/Visualization.stories.d.ts +1 -1
  86. package/dist/types/src/components/Visualization/Visualization.stories.d.ts.map +1 -1
  87. package/dist/types/src/components/Visualization/index.d.ts +2 -2
  88. package/dist/types/src/components/Visualization/index.d.ts.map +1 -1
  89. package/dist/types/src/components/index.d.ts +6 -6
  90. package/dist/types/src/components/index.d.ts.map +1 -1
  91. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.d.ts +1 -1
  92. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.d.ts.map +1 -1
  93. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.stories.d.ts +1 -1
  94. package/dist/types/src/containers/ExplorerArticle/ExplorerArticle.stories.d.ts.map +1 -1
  95. package/dist/types/src/containers/ExplorerArticle/index.d.ts +1 -1
  96. package/dist/types/src/containers/ExplorerArticle/index.d.ts.map +1 -1
  97. package/dist/types/src/containers/NeighborhoodCompanion/NeighborhoodCompanion.d.ts.map +1 -1
  98. package/dist/types/src/containers/NeighborhoodCompanion/index.d.ts +1 -1
  99. package/dist/types/src/containers/NeighborhoodCompanion/index.d.ts.map +1 -1
  100. package/dist/types/src/containers/index.d.ts.map +1 -1
  101. package/dist/types/src/hooks/index.d.ts +2 -2
  102. package/dist/types/src/hooks/index.d.ts.map +1 -1
  103. package/dist/types/src/index.d.ts +3 -2
  104. package/dist/types/src/index.d.ts.map +1 -1
  105. package/dist/types/src/testing/generator.d.ts +1 -1
  106. package/dist/types/src/testing/generator.d.ts.map +1 -1
  107. package/dist/types/src/testing/index.d.ts +3 -3
  108. package/dist/types/src/testing/index.d.ts.map +1 -1
  109. package/dist/types/src/testing/relations.d.ts +3 -4
  110. package/dist/types/src/testing/relations.d.ts.map +1 -1
  111. package/dist/types/src/translations.d.ts +2 -3
  112. package/dist/types/src/translations.d.ts.map +1 -1
  113. package/dist/types/src/types/Graph.d.ts.map +1 -1
  114. package/dist/types/src/types/index.d.ts +3 -3
  115. package/dist/types/src/types/index.d.ts.map +1 -1
  116. package/dist/types/src/util/index.d.ts +2 -2
  117. package/dist/types/src/util/index.d.ts.map +1 -1
  118. package/dist/types/tsconfig.tsbuildinfo +1 -1
  119. package/package.json +58 -57
  120. package/src/ForceGraph.ts +8 -0
  121. package/src/Hooks.ts +7 -0
  122. package/src/capabilities/app-graph-builder.ts +2 -1
  123. package/src/capabilities/gen/browser.ts +32 -0
  124. package/src/capabilities/gen/node.ts +3 -3
  125. package/src/capabilities/gen/tauri.ts +32 -0
  126. package/src/capabilities/gen/workerd.ts +3 -3
  127. package/src/capabilities/index.ts +4 -4
  128. package/src/capabilities/react-surface.ts +2 -2
  129. package/src/components/Chart/Chart.stories.tsx +1 -1
  130. package/src/components/Chart/Chart.tsx +1 -1
  131. package/src/components/Chart/index.ts +1 -1
  132. package/src/components/Globe/Globe.stories.tsx +1 -1
  133. package/src/components/Globe/Globe.tsx +1 -1
  134. package/src/components/Globe/index.ts +1 -1
  135. package/src/components/Graph/CanvasForceGraph.stories.tsx +3 -3
  136. package/src/components/Graph/CanvasForceGraph.tsx +5 -5
  137. package/src/components/Graph/ForceGraph.stories.tsx +8 -9
  138. package/src/components/Graph/ForceGraph.tsx +7 -7
  139. package/src/components/Graph/index.ts +2 -2
  140. package/src/components/Lattice/Lattice.stories.tsx +4 -4
  141. package/src/components/Lattice/Lattice.tsx +2 -2
  142. package/src/components/Lattice/index.ts +1 -1
  143. package/src/components/Tree/EdgeBundling.stories.tsx +6 -6
  144. package/src/components/Tree/Tree.stories.tsx +3 -3
  145. package/src/components/Tree/index.ts +1 -1
  146. package/src/components/Tree/types/index.ts +2 -2
  147. package/src/components/Tree/types/tree.test.ts +4 -4
  148. package/src/components/Tree/types/tree.ts +27 -24
  149. package/src/components/Tree/types/types.ts +1 -1
  150. package/src/components/Visualization/Visualization.stories.tsx +3 -3
  151. package/src/components/Visualization/Visualization.tsx +8 -9
  152. package/src/components/Visualization/index.ts +2 -2
  153. package/src/components/Visualization/variants.ts +1 -1
  154. package/src/components/index.ts +6 -6
  155. package/src/containers/ExplorerArticle/ExplorerArticle.stories.tsx +3 -3
  156. package/src/containers/ExplorerArticle/ExplorerArticle.tsx +17 -16
  157. package/src/containers/ExplorerArticle/index.ts +1 -1
  158. package/src/containers/NeighborhoodCompanion/NeighborhoodCompanion.tsx +19 -19
  159. package/src/containers/NeighborhoodCompanion/index.ts +1 -1
  160. package/src/containers/index.ts +2 -2
  161. package/src/hooks/index.ts +2 -2
  162. package/src/hooks/useGraphModel.ts +2 -2
  163. package/src/hooks/useNeighborhoodModel.ts +1 -1
  164. package/src/index.ts +3 -2
  165. package/src/meta.ts +1 -1
  166. package/src/plugin.test.ts +2 -2
  167. package/src/testing/generator.ts +3 -3
  168. package/src/testing/index.ts +3 -3
  169. package/src/testing/relations.ts +7 -8
  170. package/src/translations.ts +4 -4
  171. package/src/types/Graph.ts +4 -4
  172. package/src/types/index.ts +3 -3
  173. package/src/util/index.ts +2 -2
  174. package/dist/lib/chunk-types.mjs.map +0 -1
package/PLUGIN.mdl CHANGED
@@ -18,9 +18,10 @@ Each extension is defined in the Appendix or resolved via its URI.
18
18
  |-------------|--------------------------------|
19
19
  | `type` | `org.dxos.mdl.type@1.0` |
20
20
  | `feat` | `org.dxos.mdl.feat@1.0` |
21
- | `test` | `org.dxos.mdl.test@1.0` |
21
+ | `scenario` | `org.dxos.mdl.scenario@1.0` |
22
22
  | `component` | `org.dxos.mdl.component@1.0` |
23
23
  | `op` | `org.dxos.mdl.op@1.0` |
24
+ | `test` | `org.dxos.mdl.test@1.0` |
24
25
 
25
26
  ## Types
26
27
 
@@ -204,7 +205,7 @@ feat F-4: Node Interaction
204
205
  ## Acceptance
205
206
 
206
207
  ```mdl
207
- test T-1: Graph creation
208
+ scenario T-1: Graph creation
208
209
  given: user opens the object creation dialog and selects Graph
209
210
  when: a typename is selected and the form submitted
210
211
  then:
@@ -214,7 +215,7 @@ test T-1: Graph creation
214
215
  ```
215
216
 
216
217
  ```mdl
217
- test T-2: Article mounts model
218
+ scenario T-2: Article mounts model
218
219
  given: a Graph with a populated query
219
220
  when: ExplorerArticle is rendered with role === article
220
221
  then:
@@ -224,7 +225,7 @@ test T-2: Article mounts model
224
225
  ```
225
226
 
226
227
  ```mdl
227
- test T-3: Variant switch preserves positions
228
+ scenario T-3: Variant switch preserves positions
228
229
  given: force variant is active with nodes positioned
229
230
  when: user switches to cluster variant
230
231
  then:
@@ -234,7 +235,7 @@ test T-3: Variant switch preserves positions
234
235
  ```
235
236
 
236
237
  ```mdl
237
- test T-4: Query filter updates graph
238
+ scenario T-4: Query filter updates graph
238
239
  given: ExplorerArticle is open with all objects visible
239
240
  when: user types a typename filter in QueryEditor
240
241
  then:
@@ -244,7 +245,7 @@ test T-4: Query filter updates graph
244
245
  ```
245
246
 
246
247
  ```mdl
247
- test T-5: Node hover preview
248
+ scenario T-5: Node hover preview
248
249
  given: force-directed graph with at least one ECHO object node
249
250
  when: pointer enters that node
250
251
  then:
@@ -253,7 +254,7 @@ test T-5: Node hover preview
253
254
  ```
254
255
 
255
256
  ```mdl
256
- test T-6: Lattice sort order
257
+ scenario T-6: Lattice sort order
257
258
  given: database contains objects of two typenames A and B
258
259
  when: lattice variant is active
259
260
  then:
@@ -262,7 +263,7 @@ test T-6: Lattice sort order
262
263
  ```
263
264
 
264
265
  ```mdl
265
- test T-7: Model closed on unmount
266
+ scenario T-7: Model closed on unmount
266
267
  given: ExplorerArticle is mounted and SpaceGraphModel is open
267
268
  when: component unmounts
268
269
  then:
@@ -272,6 +273,58 @@ test T-7: Model closed on unmount
272
273
 
273
274
  ---
274
275
 
276
+ ## QA
277
+
278
+ Executable tests. Each step carries a human instruction (`do`) and, where the step maps to an
279
+ invocable operation, an agent binding (`invoke`). Report failures by test and step number.
280
+
281
+ plugin-explorer is not in `getDefaults` or the dev-only default set (see
282
+ `packages/apps/composer-app/src/plugin-defs.tsx`) — it is OFF by default. Neither `createGraph` nor
283
+ `buildFilter` is a registered runtime `Operation` (no `DXN.make` key exists in
284
+ `src/`) — creation goes through the generic `CreateObjectEntry` capability
285
+ (`src/capabilities/create-object.ts`), a UI-driven path with no operation key to invoke, and the
286
+ query editor calls `buildFilter` as a plain in-process function. Both steps are human-only.
287
+
288
+ ```mdl
289
+ test QA-1: Create a Graph and switch layout variants
290
+ desc: The core explorer round-trip — create a Graph object, watch it render, switch between layout variants.
291
+ actors: human
292
+ covers: [F-1.1, F-1.2, F-1.3, F-3.1, T-1, T-2, T-3]
293
+ status: unverified
294
+ given:
295
+ - an identity exists
296
+ - space: a space is open, containing at least one object of some typename to visualize
297
+ - no Graph named "QA Graph" exists — ABORT rather than reusing one this test did not create
298
+ steps:
299
+ - name: Create the Graph
300
+ do: In the navtree, click + on the space and choose Explorer > Graph. Name it "QA Graph" and pick a typename to seed the view.
301
+ expect: a Graph object named "QA Graph" is created and opens as an article, rendering an SVG force-directed graph of matching objects
302
+ note: |
303
+ NO `invoke` — `createGraph` has no runtime operation key; the navtree action calls the
304
+ `CreateObjectEntry` capability directly (see above).
305
+ - name: Switch to the cluster variant
306
+ do: Click the "cluster" tab in the variant toolbar.
307
+ expect: the projector swaps to radial cluster layout; nodes tween from their force positions rather than jumping; no pan/zoom wrapper is present
308
+ - name: Switch to the lattice variant
309
+ do: Click the "lattice" tab.
310
+ expect: nodes render as small rounded rectangles, grouped by typename then sorted alphabetically by label
311
+ - name: Hover a node
312
+ do: Move the pointer over any node with an underlying ECHO object.
313
+ expect: an anchor-card preview appears showing the object's label
314
+ after:
315
+ - name: Delete the Graph
316
+ do: Right-click "QA Graph" in the navtree and choose Delete.
317
+ expect: the row leaves the navtree and its plank closes
318
+ note: |
319
+ NO `invoke` here either — the test never captured a live reference to the Graph (its
320
+ creation had no `invoke`/`capture`), so a runner must resolve it by querying
321
+ `space.db.query(dxos.Filter.everything())` for the object named "QA Graph" and call
322
+ `org.dxos.operation.space.removeObjects` with that reference, rather than the test
323
+ guessing an id it was never given.
324
+ ```
325
+
326
+ ---
327
+
275
328
  ## Appendix: Extension Definitions
276
329
 
277
330
  Extension block types used in this document are defined below using
@@ -299,8 +352,8 @@ ext feat
299
352
  ```
300
353
 
301
354
  ```mdl
302
- ext test
303
- uri: org.dxos.mdl.test@1.0
355
+ ext scenario
356
+ uri: org.dxos.mdl.scenario@1.0
304
357
  desc: An acceptance scenario expressed as given / when / then steps.
305
358
  fields:
306
359
  given?: Step | Step[]
@@ -0,0 +1,2 @@
1
+ import { n as CanvasForceGraph, t as ForceGraph } from "./chunk-Graph.mjs";
2
+ export { CanvasForceGraph, ForceGraph };
@@ -2,7 +2,6 @@ import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
2
2
  import { Annotation, DXN, Filter, Obj, Query, QueryAST, Ref, Type, View } from "@dxos/echo";
3
3
  import * as Schema from "effect/Schema";
4
4
  import { ViewAnnotation } from "@dxos/schema";
5
- import { FormInputAnnotation, LabelAnnotation } from "@dxos/echo/Annotation";
6
5
  //#region src/types/Graph.ts
7
6
  var Graph_exports = /* @__PURE__ */ __exportAll({
8
7
  Graph: () => Graph,
@@ -10,15 +9,15 @@ var Graph_exports = /* @__PURE__ */ __exportAll({
10
9
  });
11
10
  var Graph = class extends Type.makeObject(DXN.make("org.dxos.type.graph", "0.1.0"))(Schema.Struct({
12
11
  name: Schema.optional(Schema.String),
13
- view: Ref.Ref(View.View).pipe(FormInputAnnotation.set(false), Schema.optional),
12
+ view: Ref.Ref(View.View).pipe(Annotation.FormInputAnnotation.set(false), Schema.optional),
14
13
  query: Schema.Struct({
15
14
  raw: Schema.optional(Schema.String),
16
15
  ast: QueryAST.Query
17
- }).pipe(FormInputAnnotation.set(false))
18
- }).pipe(LabelAnnotation.set(["name"]), ViewAnnotation.set(["view"]), Annotation.IconAnnotation.set({
16
+ }).pipe(Annotation.FormInputAnnotation.set(false))
17
+ }).pipe(Annotation.LabelAnnotation.set(["name"]), ViewAnnotation.set(["view"]), Annotation.IconAnnotation.set({
19
18
  icon: "ph--graph--regular",
20
19
  hue: "green"
21
- }))) {};
20
+ }), Annotation.UserType.set())) {};
22
21
  /**
23
22
  * Make a graph as a view of a data set.
24
23
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Graph.mjs","names":[],"sources":["../../src/types/Graph.ts"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, DXN, Filter, Obj, Query, QueryAST, Ref, Type, View } from '@dxos/echo';\nimport { FormInputAnnotation, LabelAnnotation } from '@dxos/echo/Annotation';\nimport { ViewAnnotation } from '@dxos/schema';\n\nexport class Graph extends Type.makeObject<Graph>(DXN.make('org.dxos.type.graph', '0.1.0'))(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n view: Ref.Ref(View.View).pipe(FormInputAnnotation.set(false), Schema.optional),\n query: Schema.Struct({\n raw: Schema.optional(Schema.String),\n ast: QueryAST.Query,\n }).pipe(FormInputAnnotation.set(false)),\n }).pipe(\n LabelAnnotation.set(['name']),\n ViewAnnotation.set(['view']),\n Annotation.IconAnnotation.set({ icon: 'ph--graph--regular', hue: 'green' }),\n ),\n) {}\n\ntype MakeProps = Omit<Partial<Obj.MakeProps<typeof Graph>>, 'view'> & {\n view?: View.View;\n};\n\n/**\n * Make a graph as a view of a data set.\n */\nexport const make = ({\n name,\n query = { raw: '', ast: Query.select(Filter.nothing()).ast },\n view,\n}: MakeProps = {}): Graph => {\n return Obj.make(Graph, { name, view: view && Ref.make(view), query });\n};\n"],"mappings":";;;;;;;;;;AAUA,IAAa,QAAb,cAA2B,KAAK,WAAkB,IAAI,KAAK,uBAAuB,OAAO,CAAC,CAAC,CACzF,OAAO,OAAO;CACZ,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,MAAM,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,KAAK,oBAAoB,IAAI,KAAK,GAAG,OAAO,QAAQ;CAC7E,OAAO,OAAO,OAAO;EACnB,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,KAAK,SAAS;CAChB,CAAC,CAAC,CAAC,KAAK,oBAAoB,IAAI,KAAK,CAAC;AACxC,CAAC,CAAC,CAAC,KACD,gBAAgB,IAAI,CAAC,MAAM,CAAC,GAC5B,eAAe,IAAI,CAAC,MAAM,CAAC,GAC3B,WAAW,eAAe,IAAI;CAAE,MAAM;CAAsB,KAAK;AAAQ,CAAC,CAC5E,CACF,CAAC,CAAC,CAAC;;;;AASH,IAAa,QAAQ,EACnB,MACA,QAAQ;CAAE,KAAK;CAAI,KAAK,MAAM,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAC;AAAI,GAC3D,SACa,CAAC,MAAa;CAC3B,OAAO,IAAI,KAAK,OAAO;EAAE;EAAM,MAAM,QAAQ,IAAI,KAAK,IAAI;EAAG;CAAM,CAAC;AACtE"}
1
+ {"version":3,"file":"Graph.mjs","names":[],"sources":["../../src/types/Graph.ts"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Annotation, DXN, Filter, Obj, Query, QueryAST, Ref, Type, View } from '@dxos/echo';\nimport { ViewAnnotation } from '@dxos/schema';\n\nexport class Graph extends Type.makeObject<Graph>(DXN.make('org.dxos.type.graph', '0.1.0'))(\n Schema.Struct({\n name: Schema.optional(Schema.String),\n view: Ref.Ref(View.View).pipe(Annotation.FormInputAnnotation.set(false), Schema.optional),\n query: Schema.Struct({\n raw: Schema.optional(Schema.String),\n ast: QueryAST.Query,\n }).pipe(Annotation.FormInputAnnotation.set(false)),\n }).pipe(\n Annotation.LabelAnnotation.set(['name']),\n ViewAnnotation.set(['view']),\n Annotation.IconAnnotation.set({ icon: 'ph--graph--regular', hue: 'green' }),\n Annotation.UserType.set(),\n ),\n) {}\n\ntype MakeProps = Omit<Partial<Obj.MakeProps<typeof Graph>>, 'view'> & {\n view?: View.View;\n};\n\n/**\n * Make a graph as a view of a data set.\n */\nexport const make = ({\n name,\n query = { raw: '', ast: Query.select(Filter.nothing()).ast },\n view,\n}: MakeProps = {}): Graph => {\n return Obj.make(Graph, { name, view: view && Ref.make(view), query });\n};\n"],"mappings":";;;;;;;;;AASA,IAAa,QAAb,cAA2B,KAAK,WAAkB,IAAI,KAAK,uBAAuB,OAAO,CAAC,CAAC,CACzF,OAAO,OAAO;CACZ,MAAM,OAAO,SAAS,OAAO,MAAM;CACnC,MAAM,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,KAAK,WAAW,oBAAoB,IAAI,KAAK,GAAG,OAAO,QAAQ;CACxF,OAAO,OAAO,OAAO;EACnB,KAAK,OAAO,SAAS,OAAO,MAAM;EAClC,KAAK,SAAS;CAChB,CAAC,CAAC,CAAC,KAAK,WAAW,oBAAoB,IAAI,KAAK,CAAC;AACnD,CAAC,CAAC,CAAC,KACD,WAAW,gBAAgB,IAAI,CAAC,MAAM,CAAC,GACvC,eAAe,IAAI,CAAC,MAAM,CAAC,GAC3B,WAAW,eAAe,IAAI;CAAE,MAAM;CAAsB,KAAK;AAAQ,CAAC,GAC1E,WAAW,SAAS,IAAI,CAC1B,CACF,CAAC,CAAC,CAAC;;;;AASH,IAAa,QAAQ,EACnB,MACA,QAAQ;CAAE,KAAK;CAAI,KAAK,MAAM,OAAO,OAAO,QAAQ,CAAC,CAAC,CAAC;AAAI,GAC3D,SACa,CAAC,MAAa;CAC3B,OAAO,IAAI,KAAK,OAAO;EAAE;EAAM,MAAM,QAAQ,IAAI,KAAK,IAAI;EAAG;CAAM,CAAC;AACtE"}
@@ -0,0 +1,21 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
3
+ import * as SpaceCapability from "@dxos/plugin-space/SpaceCapability";
4
+ import { translations } from "#translations";
5
+ import { meta } from "#meta";
6
+ //#region src/capabilities/gen/browser.ts
7
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"));
8
+ var CreateObject = SpaceCapability.createObject(() => import("./chunk-create-object.mjs"));
9
+ var PluginAsset = AppCapability.pluginAsset({
10
+ pluginId: meta.profile.key,
11
+ path: "PLUGIN.mdl",
12
+ content: PLUGIN_default,
13
+ mimeType: "application/x-mdl"
14
+ });
15
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article", "org.dxos.role.section"] });
16
+ var Schema = AppCapability.schema(() => import("./chunk-schema.mjs"));
17
+ var Translations = AppCapability.translations(translations);
18
+ //#endregion
19
+ export { AppGraphBuilder, CreateObject, PluginAsset, ReactSurface, Schema, Translations };
20
+
21
+ //# sourceMappingURL=capabilities.browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.browser.mjs","names":[],"sources":["../../src/capabilities/gen/browser.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'browser' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object.ts'));\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.section'],\n});\n\nexport const Schema = AppCapability.schema(() => import('../schema.ts'));\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;AAcA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAA0B;AAEpG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAsB;AAE5F,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,yBAAyB,uBAAuB,EAC1D,CAAC;AAED,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAe;AAEvE,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -1,10 +1,8 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
1
2
  import * as AppCapability from "@dxos/app-toolkit/AppCapability";
2
3
  import * as SpaceCapability from "@dxos/plugin-space/SpaceCapability";
3
4
  import { translations } from "#translations";
4
5
  import { meta } from "#meta";
5
- //#region PLUGIN.mdl?raw
6
- var PLUGIN_default = "---\nid: org.dxos.plugin.explorer\nname: ExplorerPlugin\nversion: 0.1.0\n---\n\nAn interactive hypergraph visualization plugin for `DXOS` Composer that reveals relationships between objects in a workspace.\nThe plugin renders a live `Graph` object — backed by a `View` and a `QueryAST` query — through four switchable layout\nvariants: force-directed, radial cluster, edge bundling, and lattice.\nNode colours are derived from ECHO object types; hovering a node triggers an anchor-card preview.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype QueryInput\n fields:\n raw?: string # raw query string entered by the user\n ast: QueryAST.Query # compiled AST produced by QueryBuilder\n```\n\n```mdl\ntype GraphObject\n desc: ECHO-persistent object that describes a hypergraph visualisation session.\n fields:\n name?: string\n view: Ref<View> # schema view that defines visible fields\n query: QueryInput\n```\n\n```mdl\ntype ExplorerVariant\n literals: force | cluster | bundle | lattice\n```\n\n## Components\n\n```mdl\ncomponent ExplorerArticle\n desc: |\n Top-level article / section surface for a Graph object.\n Renders one of four SVG layout variants and a toolbar for switching between them.\n props:\n role: article | section\n subject: Ref<View>\n attendableId?: string\n state:\n variant: ExplorerVariant # active layout; default force\n filter?: Filter.Any # compiled from toolbar query input\n model?: SpaceGraphModel # live reactive graph built from db + filter\n slots:\n toolbar?: ReactNode # shown only when role === article\n actions:\n setVariant(v: ExplorerVariant)\n setFilter(raw: string)\n layout: |\n ┌────────────────────────────────┐\n │ [toolbar slot — article only] │\n │ [QueryEditor] [variant tabs] │\n ├────────────────────────────────┤\n │ │\n │ SVG canvas (force / cluster │\n │ / bundle / lattice) │\n │ │\n └────────────────────────────────┘\n```\n\n```mdl\ncomponent Visualization\n desc: |\n Internal component that owns a single persistent SVG.Graph mount.\n Swaps the active GraphProjector when the variant changes, seeding the\n new projector with the previous layout so node positions tween smoothly.\n props:\n variant: ExplorerVariant\n model: SpaceGraphModel\n state:\n projector?: GraphProjector<SpaceGraphNode>\n actions:\n createProjector(variant: ExplorerVariant, prev?: GraphLayout) → GraphProjector\n createRenderNode(variant: ExplorerVariant) → RenderNode\n```\n\n## Operations\n\n```mdl\nop createGraph\n desc: |\n Creates a new Graph object scoped to a target space or collection.\n Derives a ViewModel from the database for the selected typename, then\n writes the object via SpaceOperation.AddObject.\n input:\n name?: string\n typename?: string # ECHO typename used to seed the initial view\n target: Space | Collection\n targetNodeId?: string\n output: GraphObject\n effects: [echo:write]\n note: |\n The typename is resolved through ViewModel.makeFromDatabase; the resulting\n View is stored as a Ref inside the Graph object.\n```\n\n```mdl\nop buildFilter\n desc: |\n Compiles a raw query string into a Filter via QueryBuilder.\n Pure — no side effects; result is passed to SpaceGraphModel.setFilter.\n input:\n raw: string\n output: Filter.Any\n errors:\n ParseError: raw string is not valid query syntax\n```\n\n## Features\n\n```mdl\nfeat F-1: Graph Object\n\n req F-1.1: A Graph object stores a name, a View ref, and a compiled QueryAST.\n req F-1.2:\n when: user creates a new graph\n then: op:createGraph derives a ViewModel from the chosen typename and writes the Graph to ECHO\n\n req F-1.3:\n when: Graph is persisted\n then: it appears in the space object list and can be opened as an article\n```\n\n```mdl\nfeat F-2: Live Graph Model\n\n req F-2.1:\n when: ExplorerArticle mounts with a valid Graph subject\n then: SpaceGraphModel is opened against the subject's database\n\n req F-2.2:\n when: user types a query in the toolbar\n then: op:buildFilter compiles the raw string; model.setFilter applied; SVG re-renders\n\n req F-2.3:\n when: Graph is unmounted\n then: SpaceGraphModel is closed and all subscriptions released\n\n req F-2.4:\n when: an ECHO object in the database changes\n then: SpaceGraphModel emits an update and SVG.Graph re-renders without full remount\n tags: [reactive, collaborative]\n```\n\n```mdl\nfeat F-3: Visualization Variants\n\n req F-3.1:\n when: variant tab is selected\n then: Visualization swaps projector; previous node x/y seed the new projector so positions tween\n\n req F-3.2:\n when: variant is force\n then: SVG.Zoom wrapper is mounted enabling pan/zoom drag interaction\n\n req F-3.3:\n when: variant is cluster or bundle\n then: no SVG.Zoom wrapper; leaves grouped by typename; radial labels fade in after tween\n\n req F-3.4:\n when: variant is lattice\n then: nodes rendered as small rounded rectangles sorted by typename then label\n\n req F-3.5:\n when: variant is cluster and user clicks a root or group node\n then: subtree toggles collapsed/expanded via GraphClusterProjector.toggleCollapsed\n```\n\n```mdl\nfeat F-4: Node Interaction\n\n req F-4.1:\n when: pointer enters a node\n then: DxAnchorActivate event dispatched with the object's DXN and label, kind: card\n\n req F-4.2:\n when: pointer leaves a node\n then: DxAnchorActivate cleared (onNodeHover called with null)\n\n req F-4.3:\n when: node has no underlying ECHO object (synthetic root / group)\n then: no preview dispatched; node rendered in neutral colour\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Graph creation\n given: user opens the object creation dialog and selects Graph\n when: a typename is selected and the form submitted\n then:\n - op:createGraph runs without error\n - new Graph object visible in space object list\n - Graph.view references a valid View object\n```\n\n```mdl\ntest T-2: Article mounts model\n given: a Graph with a populated query\n when: ExplorerArticle is rendered with role === article\n then:\n - SpaceGraphModel is opened\n - SVG canvas renders nodes derived from the database\n - toolbar shows QueryEditor and variant tabs\n```\n\n```mdl\ntest T-3: Variant switch preserves positions\n given: force variant is active with nodes positioned\n when: user switches to cluster variant\n then:\n - projector is recreated from previous layout\n - nodes tween from old positions to cluster target positions\n - SVG.Zoom wrapper is absent in the new mount\n```\n\n```mdl\ntest T-4: Query filter updates graph\n given: ExplorerArticle is open with all objects visible\n when: user types a typename filter in QueryEditor\n then:\n - op:buildFilter returns a Filter without error\n - SpaceGraphModel.setFilter applied\n - only matching nodes remain visible in the SVG\n```\n\n```mdl\ntest T-5: Node hover preview\n given: force-directed graph with at least one ECHO object node\n when: pointer enters that node\n then:\n - DxAnchorActivate event fired with correct DXN\n - kind === card\n```\n\n```mdl\ntest T-6: Lattice sort order\n given: database contains objects of two typenames A and B\n when: lattice variant is active\n then:\n - all typename-A nodes appear before typename-B nodes (or vice-versa, consistent order)\n - within each group nodes are ordered alphabetically by label\n```\n\n```mdl\ntest T-7: Model closed on unmount\n given: ExplorerArticle is mounted and SpaceGraphModel is open\n when: component unmounts\n then:\n - SpaceGraphModel.close() is called\n - no lingering ECHO subscriptions remain\n```\n\n---\n\n## Appendix: Extension Definitions\n\nExtension block types used in this document are defined below using\nthe core `ext` primitive — the only construct the base language provides.\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap # name[?]: TypeExpr (# inline comment)\n literals?: UnionList # a | b | c\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self # feat blocks may contain feat blocks\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap # external inputs (immutable inside component)\n state?: FieldMap # internal reactive state\n slots?: FieldMap # named ReactNode injection points\n actions?: ActionMap # methods the component exposes or handles\n emits?: EventMap # events the component raises to its parent\n layout?: CodeBlock # ASCII sketch of visual structure (non-normative)\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap # named input parameters\n output?: TypeExpr # return type\n errors?: ErrorMap # name: Prose (when this error occurs)\n effects?: EffectList # echo:read | echo:write | http | fs | ...\n requires?: ServiceList # injected service dependencies\n note?: Prose # implementation guidance (non-normative)\n```\n";
7
- //#endregion
8
6
  //#region src/capabilities/index.ts
9
7
  var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"));
10
8
  var CreateObject = SpaceCapability.createObject(() => import("./chunk-create-object.mjs"));
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('./app-graph-builder'));\nexport const CreateObject = SpaceCapability.createObject(() => import('./create-object'));\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.section'],\n});\nexport const Schema = AppCapability.schema(() => import('./schema'));\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;AAaA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAAsB;AAChG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAkB;AACxF,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAoB,EACjF,OAAO,CAAC,yBAAyB,uBAAuB,EAC1D,CAAC;AACD,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAW;AACnE,IAAa,eAAe,cAAc,aAAa,YAAY"}
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('./app-graph-builder.ts'));\nexport const CreateObject = SpaceCapability.createObject(() => import('./create-object.ts'));\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.section'],\n});\nexport const Schema = AppCapability.schema(() => import('./schema.ts'));\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;AAaA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAAyB;AACnG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAqB;AAC3F,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAuB,EACpF,OAAO,CAAC,yBAAyB,uBAAuB,EAC1D,CAAC;AACD,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAc;AACtE,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { translations } from '#translations';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object'));\n\nexport const Schema = AppCapability.schema(() => import('../schema'));\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;AAWA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAAuB;AAEjG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAmB;AAEzF,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAY;AAEpE,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
1
+ {"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { translations } from '#translations';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object.ts'));\n\nexport const Schema = AppCapability.schema(() => import('../schema.ts'));\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;AAWA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAA0B;AAEpG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAsB;AAE5F,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAe;AAEvE,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,21 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
3
+ import * as SpaceCapability from "@dxos/plugin-space/SpaceCapability";
4
+ import { translations } from "#translations";
5
+ import { meta } from "#meta";
6
+ //#region src/capabilities/gen/tauri.ts
7
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"));
8
+ var CreateObject = SpaceCapability.createObject(() => import("./chunk-create-object.mjs"));
9
+ var PluginAsset = AppCapability.pluginAsset({
10
+ pluginId: meta.profile.key,
11
+ path: "PLUGIN.mdl",
12
+ content: PLUGIN_default,
13
+ mimeType: "application/x-mdl"
14
+ });
15
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article", "org.dxos.role.section"] });
16
+ var Schema = AppCapability.schema(() => import("./chunk-schema.mjs"));
17
+ var Translations = AppCapability.translations(translations);
18
+ //#endregion
19
+ export { AppGraphBuilder, CreateObject, PluginAsset, ReactSurface, Schema, Translations };
20
+
21
+ //# sourceMappingURL=capabilities.tauri.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.tauri.mjs","names":[],"sources":["../../src/capabilities/gen/tauri.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'tauri' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object.ts'));\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.section'],\n});\n\nexport const Schema = AppCapability.schema(() => import('../schema.ts'));\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;AAcA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAA0B;AAEpG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAsB;AAE5F,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,yBAAyB,uBAAuB,EAC1D,CAAC;AAED,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAe;AAEvE,IAAa,eAAe,cAAc,aAAa,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { translations } from '#translations';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object'));\n\nexport const Schema = AppCapability.schema(() => import('../schema'));\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;AAWA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAAuB;AAEjG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAmB;AAEzF,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAY;AAEpE,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
1
+ {"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' condition.\n\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as SpaceCapability from '@dxos/plugin-space/SpaceCapability';\n\nimport { translations } from '#translations';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'));\n\nexport const CreateObject = SpaceCapability.createObject(() => import('../create-object.ts'));\n\nexport const Schema = AppCapability.schema(() => import('../schema.ts'));\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;AAWA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,gCAA0B;AAEpG,IAAa,eAAe,gBAAgB,mBAAmB,OAAO,4BAAsB;AAE5F,IAAa,SAAS,cAAc,aAAa,OAAO,qBAAe;AAEvE,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -1,13 +1,16 @@
1
+ import { useGraphModel } from "#hooks";
1
2
  import { useCallback, useEffect, useState } from "react";
2
- import { Obj } from "@dxos/echo";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
- import { DxAnchorActivate, Icon, Panel, Toolbar } from "@dxos/react-ui";
4
+ import { Obj } from "@dxos/echo";
5
5
  import "@dxos/react-ui-graph/styles/graph.css";
6
- import { AppSurface } from "@dxos/app-toolkit/ui";
6
+ import * as AppSurface from "@dxos/app-toolkit/AppSurface";
7
7
  import { useObject } from "@dxos/echo-react";
8
- import { QueryEditor } from "@dxos/react-ui-components";
8
+ import { QueryEditor } from "@dxos/react-ui-query";
9
+ import * as Panel from "@dxos/react-ui/Panel";
10
+ import * as ToggleGroup from "@dxos/react-ui/ToggleGroup";
11
+ import * as Toolbar from "@dxos/react-ui/Toolbar";
12
+ import { DxAnchorActivate } from "@dxos/ui-types";
9
13
  import { VARIANTS, Visualization, isVariant } from "#components";
10
- import { useGraphModel } from "#hooks";
11
14
  //#region src/containers/ExplorerArticle/ExplorerArticle.tsx
12
15
  var ExplorerArticle = ({ role, subject, variant }) => {
13
16
  const [view] = useObject(subject);
@@ -24,7 +27,7 @@ var ExplorerArticle = ({ role, subject, variant }) => {
24
27
  }, []);
25
28
  const handleDismiss = useCallback(() => {
26
29
  document.defaultView?.dispatchEvent(new DxAnchorActivate({
27
- dxn: "",
30
+ eid: "",
28
31
  label: "",
29
32
  trigger: document.body,
30
33
  state: false
@@ -34,40 +37,34 @@ var ExplorerArticle = ({ role, subject, variant }) => {
34
37
  if (!node || !event) return;
35
38
  const obj = node.data;
36
39
  if (!obj || !Obj.isObject(obj)) return;
37
- const dxn = Obj.getURI(obj);
38
- if (!dxn) return;
40
+ const eid = Obj.getURI(obj);
41
+ if (!eid) return;
39
42
  const target = event.target;
40
43
  target.dispatchEvent(new DxAnchorActivate({
41
- dxn,
44
+ eid,
42
45
  kind: "card",
43
46
  trigger: target,
44
- label: Obj.getLabel(obj) ?? dxn
47
+ label: Obj.getLabel(obj) ?? eid
45
48
  }));
46
49
  }, []);
47
50
  const showToolbar = role === AppSurface.Article.role;
48
51
  if (!db || !model) return null;
49
52
  return /* @__PURE__ */ jsxs(Panel.Root, {
50
53
  role,
51
- children: [showToolbar && /* @__PURE__ */ jsx(Panel.Toolbar, {
52
- asChild: true,
53
- children: /* @__PURE__ */ jsxs(Toolbar.Root, { children: [/* @__PURE__ */ jsx(QueryEditor, {
54
- db,
55
- onFilterChange: handleFilterChange
56
- }), /* @__PURE__ */ jsx(Toolbar.ToggleGroup, {
57
- type: "single",
58
- value: selected,
59
- onValueChange: handleVariantChange,
60
- children: VARIANTS.map(({ value, icon, label }) => /* @__PURE__ */ jsx(Toolbar.ToggleGroupItem, {
61
- value,
62
- "aria-label": label,
63
- title: label,
64
- children: /* @__PURE__ */ jsx(Icon, {
65
- icon,
66
- size: 4
67
- })
68
- }, value))
69
- })] })
70
- }), /* @__PURE__ */ jsx(Panel.Content, {
54
+ children: [showToolbar && /* @__PURE__ */ jsx(Panel.Header, { children: /* @__PURE__ */ jsxs(Toolbar.Root, { children: [/* @__PURE__ */ jsx(QueryEditor, {
55
+ db,
56
+ onFilterChange: handleFilterChange
57
+ }), /* @__PURE__ */ jsx(Toolbar.ToggleGroup, {
58
+ type: "single",
59
+ value: selected,
60
+ onValueChange: handleVariantChange,
61
+ children: VARIANTS.map(({ value, icon, label }) => /* @__PURE__ */ jsx(ToggleGroup.Item, {
62
+ value,
63
+ icon,
64
+ iconOnly: true,
65
+ label
66
+ }, value))
67
+ })] }) }), /* @__PURE__ */ jsx(Panel.Body, {
71
68
  asChild: true,
72
69
  children: /* @__PURE__ */ jsx(Visualization.Root, {
73
70
  classNames: "dx-base-surface",
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-ExplorerArticle.mjs","names":[],"sources":["../../src/containers/ExplorerArticle/ExplorerArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { type Filter, Obj, type View } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport { DxAnchorActivate, Icon, Panel, Toolbar } from '@dxos/react-ui';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-components';\nimport { type TreeNode } from '@dxos/react-ui-graph';\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nimport { type ExplorerArticleVariant, VARIANTS, Visualization, isVariant } from '#components';\nimport { useGraphModel } from '#hooks';\n\nexport type { ExplorerArticleVariant } from '#components';\n\nexport type ExplorerArticleProps = AppSurface.ObjectArticleProps<View.View>;\n\nexport const ExplorerArticle = ({ role, subject, variant }: ExplorerArticleProps) => {\n const [view] = useObject(subject);\n const [filter, setFilter] = useState<Filter.Any>();\n\n const db = view && Obj.getDatabase(view);\n const model = useGraphModel(db, filter);\n\n const handleFilterChange = useCallback<NonNullable<QueryEditorProps['onFilterChange']>>(\n ({ filter }) => setFilter(filter),\n [],\n );\n\n const [selected, setSelected] = useState<ExplorerArticleVariant>(isVariant(variant) ? variant : 'force');\n useEffect(() => {\n if (isVariant(variant)) {\n setSelected(variant);\n }\n }, [variant]);\n\n const handleVariantChange = useCallback((value: string) => {\n if (isVariant(value)) {\n setSelected(value);\n }\n }, []);\n\n // Dismiss the preview popover. The dxn/label/trigger fields are placeholders ignored on\n // `state: false`.\n const handleDismiss = useCallback(() => {\n document.defaultView?.dispatchEvent(\n new DxAnchorActivate({ dxn: '', label: '', trigger: document.body, state: false }),\n );\n }, []);\n\n const handleHover = useCallback((node: TreeNode | null, event?: MouseEvent) => {\n // Pointer left the node/label: keep the popover open so it can be hovered/interacted with.\n // The popover is dismissed only on an explicit click on the component surface (handleDismiss).\n if (!node || !event) {\n return;\n }\n const obj = node.data;\n if (!obj || !Obj.isObject(obj)) {\n return;\n }\n const dxn = Obj.getURI(obj);\n if (!dxn) {\n return;\n }\n\n const target = event.target as HTMLElement;\n target.dispatchEvent(\n new DxAnchorActivate({\n dxn,\n kind: 'card',\n trigger: target,\n label: Obj.getLabel(obj) ?? dxn,\n }),\n );\n }, []);\n\n const showToolbar = role === AppSurface.Article.role;\n\n if (!db || !model) {\n return null;\n }\n\n return (\n <Panel.Root role={role}>\n {showToolbar && (\n <Panel.Toolbar asChild>\n <Toolbar.Root>\n <QueryEditor db={db} onFilterChange={handleFilterChange} />\n <Toolbar.ToggleGroup type='single' value={selected} onValueChange={handleVariantChange}>\n {VARIANTS.map(({ value, icon, label }) => (\n <Toolbar.ToggleGroupItem key={value} value={value} aria-label={label} title={label}>\n <Icon icon={icon} size={4} />\n </Toolbar.ToggleGroupItem>\n ))}\n </Toolbar.ToggleGroup>\n </Toolbar.Root>\n </Panel.Toolbar>\n )}\n <Panel.Content asChild>\n <Visualization.Root\n classNames='dx-base-surface'\n variant={selected}\n model={model}\n onSurfaceClick={handleDismiss}\n >\n <Visualization.Graph onNodeHover={handleHover} />\n </Visualization.Root>\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nExplorerArticle.displayName = 'ExplorerArticle';\n"],"mappings":";;;;;;;;;;;AAqBA,IAAa,mBAAmB,EAAE,MAAM,SAAS,cAAoC;CACnF,MAAM,CAAC,QAAQ,UAAU,OAAO;CAChC,MAAM,CAAC,QAAQ,aAAa,SAAqB;CAEjD,MAAM,KAAK,QAAQ,IAAI,YAAY,IAAI;CACvC,MAAM,QAAQ,cAAc,IAAI,MAAM;CAEtC,MAAM,qBAAqB,aACxB,EAAE,aAAa,UAAU,MAAM,GAChC,CAAC,CACH;CAEA,MAAM,CAAC,UAAU,eAAe,SAAiC,UAAU,OAAO,IAAI,UAAU,OAAO;CACvG,gBAAgB;EACd,IAAI,UAAU,OAAO,GACnB,YAAY,OAAO;CAEvB,GAAG,CAAC,OAAO,CAAC;CAEZ,MAAM,sBAAsB,aAAa,UAAkB;EACzD,IAAI,UAAU,KAAK,GACjB,YAAY,KAAK;CAErB,GAAG,CAAC,CAAC;CAIL,MAAM,gBAAgB,kBAAkB;EACtC,SAAS,aAAa,cACpB,IAAI,iBAAiB;GAAE,KAAK;GAAI,OAAO;GAAI,SAAS,SAAS;GAAM,OAAO;EAAM,CAAC,CACnF;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,aAAa,MAAuB,UAAuB;EAG7E,IAAI,CAAC,QAAQ,CAAC,OACZ;EAEF,MAAM,MAAM,KAAK;EACjB,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS,GAAG,GAC3B;EAEF,MAAM,MAAM,IAAI,OAAO,GAAG;EAC1B,IAAI,CAAC,KACH;EAGF,MAAM,SAAS,MAAM;EACrB,OAAO,cACL,IAAI,iBAAiB;GACnB;GACA,MAAM;GACN,SAAS;GACT,OAAO,IAAI,SAAS,GAAG,KAAK;EAC9B,CAAC,CACH;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,SAAS,WAAW,QAAQ;CAEhD,IAAI,CAAC,MAAM,CAAC,OACV,OAAO;CAGT,OACE,qBAAC,MAAM,MAAP;EAAkB;EAAlB,UAAA,CACG,eACC,oBAAC,MAAM,SAAP;GAAe,SAAA;GACb,UAAA,qBAAC,QAAQ,MAAT,EAAA,UAAA,CACE,oBAAC,aAAD;IAAiB;IAAI,gBAAgB;GAAqB,CAAA,GAC1D,oBAAC,QAAQ,aAAT;IAAqB,MAAK;IAAS,OAAO;IAAU,eAAe;IAChE,UAAA,SAAS,KAAK,EAAE,OAAO,MAAM,YAC5B,oBAAC,QAAQ,iBAAT;KAA4C;KAAO,cAAY;KAAO,OAAO;KAC3E,UAAA,oBAAC,MAAD;MAAY;MAAM,MAAM;KAAI,CAAA;IACL,GAFK,KAEL,CAC1B;GACkB,CAAA,CACT,EAAA,CAAA;EACD,CAAA,GAEjB,oBAAC,MAAM,SAAP;GAAe,SAAA;GACb,UAAA,oBAAC,cAAc,MAAf;IACE,YAAW;IACX,SAAS;IACF;IACP,gBAAgB;IAEhB,UAAA,oBAAC,cAAc,OAAf,EAAqB,aAAa,YAAc,CAAA;GAC9B,CAAA;EACP,CAAA,CACL;;AAEhB;AAEA,gBAAgB,cAAc"}
1
+ {"version":3,"file":"chunk-ExplorerArticle.mjs","names":[],"sources":["../../src/containers/ExplorerArticle/ExplorerArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useCallback, useEffect, useState } from 'react';\n\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport { type Filter, Obj, type View } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport { type TreeNode } from '@dxos/react-ui-graph';\nimport { QueryEditor, type QueryEditorProps } from '@dxos/react-ui-query';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as ToggleGroup from '@dxos/react-ui/ToggleGroup';\nimport * as Toolbar from '@dxos/react-ui/Toolbar';\nimport { DxAnchorActivate } from '@dxos/ui-types';\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nimport { type ExplorerArticleVariant, VARIANTS, Visualization, isVariant } from '#components';\nimport { useGraphModel } from '#hooks';\n\nexport type { ExplorerArticleVariant } from '#components';\n\nexport type ExplorerArticleProps = AppSurface.ObjectArticleProps<View.View>;\n\nexport const ExplorerArticle = ({ role, subject, variant }: ExplorerArticleProps) => {\n const [view] = useObject(subject);\n const [filter, setFilter] = useState<Filter.Any>();\n\n const db = view && Obj.getDatabase(view);\n const model = useGraphModel(db, filter);\n\n const handleFilterChange = useCallback<NonNullable<QueryEditorProps['onFilterChange']>>(\n ({ filter }) => setFilter(filter),\n [],\n );\n\n const [selected, setSelected] = useState<ExplorerArticleVariant>(isVariant(variant) ? variant : 'force');\n useEffect(() => {\n if (isVariant(variant)) {\n setSelected(variant);\n }\n }, [variant]);\n\n const handleVariantChange = useCallback((value: string) => {\n if (isVariant(value)) {\n setSelected(value);\n }\n }, []);\n\n // Dismiss the preview popover. The eid/label/trigger fields are placeholders ignored on\n // `state: false`.\n const handleDismiss = useCallback(() => {\n document.defaultView?.dispatchEvent(\n new DxAnchorActivate({ eid: '', label: '', trigger: document.body, state: false }),\n );\n }, []);\n\n const handleHover = useCallback((node: TreeNode | null, event?: MouseEvent) => {\n // Pointer left the node/label: keep the popover open so it can be hovered/interacted with.\n // The popover is dismissed only on an explicit click on the component surface (handleDismiss).\n if (!node || !event) {\n return;\n }\n const obj = node.data;\n if (!obj || !Obj.isObject(obj)) {\n return;\n }\n const eid = Obj.getURI(obj);\n if (!eid) {\n return;\n }\n\n const target = event.target as HTMLElement;\n target.dispatchEvent(\n new DxAnchorActivate({\n eid,\n kind: 'card',\n trigger: target,\n label: Obj.getLabel(obj) ?? eid,\n }),\n );\n }, []);\n\n const showToolbar = role === AppSurface.Article.role;\n\n if (!db || !model) {\n return null;\n }\n\n return (\n <Panel.Root role={role}>\n {showToolbar && (\n <Panel.Header>\n <Toolbar.Root>\n <QueryEditor db={db} onFilterChange={handleFilterChange} />\n <Toolbar.ToggleGroup type='single' value={selected} onValueChange={handleVariantChange}>\n {VARIANTS.map(({ value, icon, label }) => (\n <ToggleGroup.Item key={value} value={value} icon={icon} iconOnly label={label} />\n ))}\n </Toolbar.ToggleGroup>\n </Toolbar.Root>\n </Panel.Header>\n )}\n <Panel.Body asChild>\n <Visualization.Root\n classNames='dx-base-surface'\n variant={selected}\n model={model}\n onSurfaceClick={handleDismiss}\n >\n <Visualization.Graph onNodeHover={handleHover} />\n </Visualization.Root>\n </Panel.Body>\n </Panel.Root>\n );\n};\n\nExplorerArticle.displayName = 'ExplorerArticle';\n"],"mappings":";;;;;;;;;;;;;;AAwBA,IAAa,mBAAmB,EAAE,MAAM,SAAS,cAAoC;CACnF,MAAM,CAAC,QAAQ,UAAU,OAAO;CAChC,MAAM,CAAC,QAAQ,aAAa,SAAqB;CAEjD,MAAM,KAAK,QAAQ,IAAI,YAAY,IAAI;CACvC,MAAM,QAAQ,cAAc,IAAI,MAAM;CAEtC,MAAM,qBAAqB,aACxB,EAAE,aAAa,UAAU,MAAM,GAChC,CAAC,CACH;CAEA,MAAM,CAAC,UAAU,eAAe,SAAiC,UAAU,OAAO,IAAI,UAAU,OAAO;CACvG,gBAAgB;EACd,IAAI,UAAU,OAAO,GACnB,YAAY,OAAO;CAEvB,GAAG,CAAC,OAAO,CAAC;CAEZ,MAAM,sBAAsB,aAAa,UAAkB;EACzD,IAAI,UAAU,KAAK,GACjB,YAAY,KAAK;CAErB,GAAG,CAAC,CAAC;CAIL,MAAM,gBAAgB,kBAAkB;EACtC,SAAS,aAAa,cACpB,IAAI,iBAAiB;GAAE,KAAK;GAAI,OAAO;GAAI,SAAS,SAAS;GAAM,OAAO;EAAM,CAAC,CACnF;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,aAAa,MAAuB,UAAuB;EAG7E,IAAI,CAAC,QAAQ,CAAC,OACZ;EAEF,MAAM,MAAM,KAAK;EACjB,IAAI,CAAC,OAAO,CAAC,IAAI,SAAS,GAAG,GAC3B;EAEF,MAAM,MAAM,IAAI,OAAO,GAAG;EAC1B,IAAI,CAAC,KACH;EAGF,MAAM,SAAS,MAAM;EACrB,OAAO,cACL,IAAI,iBAAiB;GACnB;GACA,MAAM;GACN,SAAS;GACT,OAAO,IAAI,SAAS,GAAG,KAAK;EAC9B,CAAC,CACH;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,SAAS,WAAW,QAAQ;CAEhD,IAAI,CAAC,MAAM,CAAC,OACV,OAAO;CAGT,OACE,qBAAC,MAAM,MAAP;EAAkB;EAAlB,UAAA,CACG,eACC,oBAAC,MAAM,QAAP,EAAA,UACE,qBAAC,QAAQ,MAAT,EAAA,UAAA,CACE,oBAAC,aAAD;GAAiB;GAAI,gBAAgB;EAAqB,CAAA,GAC1D,oBAAC,QAAQ,aAAT;GAAqB,MAAK;GAAS,OAAO;GAAU,eAAe;GAChE,UAAA,SAAS,KAAK,EAAE,OAAO,MAAM,YAC5B,oBAAC,YAAY,MAAb;IAAqC;IAAa;IAAM,UAAA;IAAgB;GAAQ,GAAzD,KAAyD,CACjF;EACkB,CAAA,CACT,EAAA,CAAA,EACF,CAAA,GAEhB,oBAAC,MAAM,MAAP;GAAY,SAAA;GACV,UAAA,oBAAC,cAAc,MAAf;IACE,YAAW;IACX,SAAS;IACF;IACP,gBAAgB;IAEhB,UAAA,oBAAC,cAAc,OAAf,EAAqB,aAAa,YAAc,CAAA;GAC9B,CAAA;EACV,CAAA,CACF;;AAEhB;AAEA,gBAAgB,cAAc"}
@@ -0,0 +1,161 @@
1
+ import { forceLink, forceManyBody } from "d3";
2
+ import NativeForceGraph from "force-graph";
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
+ import { useResizeDetector } from "react-resize-detector";
5
+ import * as Util from "@dxos/react-ui/Util";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { useAtomValue } from "@effect/atom-react/Hooks";
8
+ import * as Atom from "effect/reactivity/Atom";
9
+ import { Obj } from "@dxos/echo";
10
+ import * as SelectionModel from "@dxos/graph/SelectionModel";
11
+ import { GraphForceProjector, SVG } from "@dxos/react-ui-graph";
12
+ import { getHashStyles } from "@dxos/ui-theme";
13
+ import "@dxos/react-ui-graph/styles/graph.css";
14
+ //#region src/components/Graph/graph-adapter.ts
15
+ /**
16
+ * Map common graph to force-graph format.
17
+ */
18
+ var GraphAdapter = class {
19
+ graph;
20
+ _nodes = [];
21
+ _links = [];
22
+ constructor(graph) {
23
+ this.graph = graph;
24
+ this._nodes = graph.nodes.map((node) => ({
25
+ id: node.id,
26
+ type: node.type,
27
+ data: node.data
28
+ }));
29
+ const nodeIds = new Set(this._nodes.map((node) => node.id));
30
+ this._links = graph.edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target)).map((edge) => ({
31
+ type: edge.type,
32
+ source: edge.source,
33
+ target: edge.target,
34
+ data: edge.data
35
+ }));
36
+ }
37
+ get nodes() {
38
+ return this._nodes;
39
+ }
40
+ get links() {
41
+ return this._links;
42
+ }
43
+ };
44
+ //#endregion
45
+ //#region src/components/Graph/CanvasForceGraph.tsx
46
+ /**
47
+ * More performance optimized version of the ForceGraph.
48
+ */
49
+ var CanvasForceGraph = Util.composable(({ model, match, onClick, ...props }, forwardedRef) => {
50
+ const { ref: resizeRef, width, height } = useResizeDetector({ refreshRate: 200 });
51
+ const setRef = useCallback((node) => {
52
+ resizeRef(node);
53
+ assignRef(forwardedRef, node);
54
+ }, [resizeRef, forwardedRef]);
55
+ const rootRef = useRef(null);
56
+ const forceGraph = useRef(null);
57
+ const [data, setData] = useState();
58
+ useEffect(() => {
59
+ return model?.subscribe((model) => setData(new GraphAdapter(model.graph)));
60
+ }, [model]);
61
+ useEffect(() => {
62
+ if (rootRef.current) forceGraph.current = new NativeForceGraph(rootRef.current).nodeRelSize(6).nodeLabel((node) => node.type === "schema" ? node.data.typename : node.data.label ?? node.id).nodeAutoColorBy((node) => node.type === "schema" ? "schema" : node.data.typename).linkAutoColorBy((link) => link.type);
63
+ return () => {
64
+ forceGraph.current?.pauseAnimation().graphData({
65
+ nodes: [],
66
+ links: []
67
+ });
68
+ forceGraph.current = null;
69
+ };
70
+ }, []);
71
+ useEffect(() => {
72
+ if (!data || !width || !height || !forceGraph.current) return;
73
+ forceGraph.current.pauseAnimation().width(width).height(height).onEngineStop(() => handleZoomToFit()).onNodeClick((node) => {
74
+ forceGraph.current?.emitParticle(node);
75
+ }).d3Force("link", forceLink().distance(160).strength(.5)).d3Force("charge", forceManyBody().strength(-30)).graphData(data).warmupTicks(100).cooldownTime(1e3).resumeAnimation();
76
+ }, [
77
+ data,
78
+ width,
79
+ height
80
+ ]);
81
+ const handleZoomToFit = () => {
82
+ forceGraph.current?.zoomToFit(400, 40);
83
+ };
84
+ const handleClick = useCallback((event) => {
85
+ onClick?.(event);
86
+ if (!event.defaultPrevented) handleZoomToFit();
87
+ }, [onClick]);
88
+ return /* @__PURE__ */ jsx("div", {
89
+ ...Util.composableProps(props, { classNames: "relative grow" }),
90
+ onClick: handleClick,
91
+ ref: setRef,
92
+ children: /* @__PURE__ */ jsx("div", {
93
+ ref: rootRef,
94
+ className: "dx-cover"
95
+ })
96
+ });
97
+ });
98
+ var assignRef = (ref, value) => {
99
+ if (typeof ref === "function") ref(value);
100
+ else if (ref) ref.current = value;
101
+ };
102
+ //#endregion
103
+ //#region src/components/Graph/ForceGraph.tsx
104
+ var EMPTY_ATOM = Atom.make({
105
+ nodes: [],
106
+ edges: []
107
+ });
108
+ var ForceGraph = Util.composable(({ model, selection: selectionProp, grid, drag, onInspect, ...props }, forwardedRef) => {
109
+ useAtomValue(model?.graphAtom ?? EMPTY_ATOM);
110
+ const graph = useRef(null);
111
+ const selection = useMemo(() => selectionProp ?? new SelectionModel.SelectionModel(), [selectionProp]);
112
+ useEffect(() => {
113
+ return selection.subscribe(() => graph.current?.repaint());
114
+ }, [selection]);
115
+ const svgRef = useRef(null);
116
+ const [projector, setProjector] = useState();
117
+ useEffect(() => {
118
+ if (svgRef.current) setProjector(new GraphForceProjector(svgRef.current, {
119
+ attributes: { linkForce: (edge) => edge.data?.object?.active !== false },
120
+ forces: { point: { strength: .01 } }
121
+ }));
122
+ }, []);
123
+ const handleSelect = useCallback((node) => {
124
+ if (selection.contains(node.id)) selection.remove(node.id);
125
+ else selection.add(node.id);
126
+ }, [selection]);
127
+ return /* @__PURE__ */ jsx("div", {
128
+ ...Util.composableProps(props, { classNames: "dx-expand" }),
129
+ ref: forwardedRef,
130
+ children: /* @__PURE__ */ jsxs(SVG.Root, {
131
+ ref: svgRef,
132
+ children: [
133
+ /* @__PURE__ */ jsx(SVG.Markers, {}),
134
+ grid && /* @__PURE__ */ jsx(SVG.Grid, { axis: true }),
135
+ /* @__PURE__ */ jsx(SVG.Zoom, {
136
+ extent: [1 / 2, 2],
137
+ children: /* @__PURE__ */ jsx(SVG.Graph, {
138
+ ref: graph,
139
+ drag,
140
+ model,
141
+ projector,
142
+ labels: { text: (node) => node.data?.data.label ?? node.id },
143
+ attributes: { node: (node) => {
144
+ const obj = node.data?.data.object;
145
+ return {
146
+ data: { color: getHashStyles(obj && Obj.getTypename(obj))?.hue },
147
+ classes: { "dx-selected": selection.contains(node.id) }
148
+ };
149
+ } },
150
+ onSelect: handleSelect,
151
+ onInspect
152
+ })
153
+ })
154
+ ]
155
+ })
156
+ });
157
+ });
158
+ //#endregion
159
+ export { CanvasForceGraph as n, ForceGraph as t };
160
+
161
+ //# sourceMappingURL=chunk-Graph.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-Graph.mjs","names":[],"sources":["../../src/components/Graph/graph-adapter.ts","../../src/components/Graph/CanvasForceGraph.tsx","../../src/components/Graph/ForceGraph.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as GraphEdge from '@dxos/graph/GraphEdge';\nimport * as GraphModel from '@dxos/graph/GraphModel';\nimport * as GraphNode from '@dxos/graph/GraphNode';\n\nexport type ForceNode = {\n id?: string;\n};\n\nexport type ForceLink = {\n source?: string;\n target?: string;\n};\n\nexport type GraphData = {\n nodes: ForceNode[];\n links: ForceLink[];\n};\n\n/**\n * Map common graph to force-graph format.\n */\nexport class GraphAdapter implements GraphData {\n private readonly _nodes: ForceNode[] = [];\n private readonly _links: ForceLink[] = [];\n\n constructor(private readonly graph: GraphModel.AnyData) {\n this._nodes = graph.nodes.map((node: GraphNode.Any) => ({\n id: node.id,\n type: node.type,\n data: node.data,\n }));\n\n // Build a set of node IDs for efficient lookup.\n const nodeIds = new Set(this._nodes.map((node) => node.id));\n\n // Filter out edges where source or target node doesn't exist.\n this._links = graph.edges\n .filter((edge: GraphEdge.Any) => nodeIds.has(edge.source) && nodeIds.has(edge.target))\n .map((edge: GraphEdge.Any) => ({\n type: edge.type,\n source: edge.source,\n target: edge.target,\n data: edge.data,\n }));\n }\n\n get nodes() {\n return this._nodes;\n }\n\n get links() {\n return this._links;\n }\n}\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { forceLink, forceManyBody } from 'd3';\nimport NativeForceGraph from 'force-graph';\nimport React, {\n type ComponentPropsWithoutRef,\n type Ref,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useResizeDetector } from 'react-resize-detector';\n\nimport * as Util from '@dxos/react-ui/Util';\nimport { type SpaceGraphModel } from '@dxos/schema';\n\nimport { GraphAdapter } from './graph-adapter.ts';\n\nexport type CanvasForceGraphProps = {\n model?: SpaceGraphModel;\n match?: RegExp;\n};\n\n/**\n * More performance optimized version of the ForceGraph.\n */\nexport const CanvasForceGraph = Util.composable<HTMLDivElement, CanvasForceGraphProps>(\n ({ model, match, onClick, ...props }, forwardedRef) => {\n const { ref: resizeRef, width, height } = useResizeDetector({ refreshRate: 200 });\n const setRef = useCallback(\n (node: HTMLDivElement | null) => {\n resizeRef(node);\n assignRef(forwardedRef, node);\n },\n [resizeRef, forwardedRef],\n );\n\n const rootRef = useRef<HTMLDivElement>(null);\n const forceGraph = useRef<NativeForceGraph>(null);\n\n const [data, setData] = useState<GraphAdapter>();\n useEffect(() => {\n return model?.subscribe((model) => setData(new GraphAdapter(model.graph)));\n }, [model]);\n\n useEffect(() => {\n if (rootRef.current) {\n // https://github.com/vasturiano/force-graph\n // https://github.com/vasturiano/3d-force-graph\n forceGraph.current = new NativeForceGraph(rootRef.current)\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#node-styling\n .nodeRelSize(6)\n .nodeLabel((node: any) => (node.type === 'schema' ? node.data.typename : (node.data.label ?? node.id)))\n .nodeAutoColorBy((node: any) => (node.type === 'schema' ? 'schema' : node.data.typename))\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#link-styling\n .linkAutoColorBy((link: any) => link.type);\n }\n\n return () => {\n forceGraph.current?.pauseAnimation().graphData({ nodes: [], links: [] });\n forceGraph.current = null;\n };\n }, []);\n\n useEffect(() => {\n if (!data || !width || !height || !forceGraph.current) {\n return;\n }\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#container-layout\n forceGraph.current\n .pauseAnimation()\n .width(width)\n .height(height)\n .onEngineStop(() => handleZoomToFit())\n .onNodeClick((node: any) => {\n forceGraph.current?.emitParticle(node);\n })\n\n // https://github.com/vasturiano/force-graph?tab=readme-ov-file#force-engine-d3-force-configuration\n // .d3Force('center', forceCenter().strength(0.9))\n .d3Force('link', forceLink().distance(160).strength(0.5))\n .d3Force('charge', forceManyBody().strength(-30))\n\n .graphData(data)\n .warmupTicks(100)\n .cooldownTime(1_000)\n .resumeAnimation();\n }, [data, width, height]);\n\n const handleZoomToFit = () => {\n forceGraph.current?.zoomToFit(400, 40);\n };\n\n const handleClick = useCallback<NonNullable<ComponentPropsWithoutRef<'div'>['onClick']>>(\n (event) => {\n onClick?.(event);\n if (!event.defaultPrevented) {\n handleZoomToFit();\n }\n },\n [onClick],\n );\n\n return (\n <div {...Util.composableProps(props, { classNames: 'relative grow' })} onClick={handleClick} ref={setRef}>\n <div ref={rootRef} className='dx-cover' />\n </div>\n );\n },\n);\n\nconst assignRef = <T,>(ref: Ref<T> | undefined, value: T | null): void => {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref) {\n (ref as RefObject<T | null>).current = value;\n }\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { useAtomValue } from '@effect/atom-react/Hooks';\nimport * as Atom from 'effect/reactivity/Atom';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { Obj } from '@dxos/echo';\nimport * as SelectionModel from '@dxos/graph/SelectionModel';\nimport {\n type GraphController,\n GraphForceProjector,\n type GraphLayoutNode,\n type GraphProps,\n SVG,\n type SVGContext,\n} from '@dxos/react-ui-graph';\nimport * as Util from '@dxos/react-ui/Util';\nimport { type SpaceGraphEdge, type SpaceGraphModel, type SpaceGraphNode } from '@dxos/schema';\nimport { getHashStyles } from '@dxos/ui-theme';\nimport '@dxos/react-ui-graph/styles/graph.css';\n\nconst EMPTY_ATOM = Atom.make<{ nodes: SpaceGraphNode[]; edges: SpaceGraphEdge[] }>({ nodes: [], edges: [] });\n\nexport type ForceGraphProps = {\n model?: SpaceGraphModel;\n grid?: boolean;\n selection?: SelectionModel.SelectionModel;\n onInspect?: GraphProps<SpaceGraphNode, SpaceGraphEdge>['onInspect'];\n} & Pick<GraphProps, 'drag'>;\n\nexport const ForceGraph = Util.composable<HTMLDivElement, ForceGraphProps>(\n ({ model, selection: selectionProp, grid, drag, onInspect, ...props }, forwardedRef) => {\n // TODO(wittjosiah): This should go into Graph.tsx but for some reason doesn't work.\n useAtomValue(model?.graphAtom ?? EMPTY_ATOM);\n\n const graph = useRef<GraphController>(null);\n const selection = useMemo(() => selectionProp ?? new SelectionModel.SelectionModel(), [selectionProp]);\n useEffect(() => {\n const unsubscribe = selection.subscribe(() => graph.current?.repaint());\n return unsubscribe;\n }, [selection]);\n\n const svgRef = useRef<SVGContext>(null);\n const [projector, setProjector] = useState<GraphForceProjector>();\n useEffect(() => {\n if (svgRef.current) {\n setProjector(\n new GraphForceProjector(svgRef.current, {\n attributes: {\n // TODO(burdon): Check type (currently assumes Employee property).\n // Edge shouldn't contribute to force if it's not active.\n linkForce: (edge) => edge.data?.object?.active !== false,\n },\n forces: {\n point: {\n strength: 0.01,\n },\n },\n }),\n );\n }\n // SVG.Graph owns projector start/stop; nothing to clean up here.\n }, []);\n\n const handleSelect = useCallback<NonNullable<GraphProps['onSelect']>>(\n (node) => {\n if (selection.contains(node.id)) {\n selection.remove(node.id);\n } else {\n selection.add(node.id);\n }\n },\n [selection],\n );\n\n return (\n <div {...Util.composableProps(props, { classNames: 'dx-expand' })} ref={forwardedRef}>\n <SVG.Root ref={svgRef}>\n <SVG.Markers />\n {grid && <SVG.Grid axis />}\n <SVG.Zoom extent={[1 / 2, 2]}>\n <SVG.Graph<SpaceGraphNode, SpaceGraphEdge>\n ref={graph}\n drag={drag}\n model={model}\n projector={projector}\n labels={{\n text: (node) => node.data?.data.label ?? node.id,\n }}\n attributes={{\n node: (node: GraphLayoutNode<SpaceGraphNode>) => {\n const obj = node.data?.data.object;\n return {\n data: {\n color: getHashStyles(obj && Obj.getTypename(obj))?.hue,\n },\n classes: {\n 'dx-selected': selection.contains(node.id),\n },\n };\n },\n }}\n onSelect={handleSelect}\n onInspect={onInspect}\n />\n </SVG.Zoom>\n </SVG.Root>\n </div>\n );\n },\n);\n"],"mappings":"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"}