@dxos/plugin-presenter 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 (132) hide show
  1. package/PLUGIN.mdl +78 -22
  2. package/dist/lib/PresenterCapabilities.mjs.map +1 -1
  3. package/dist/lib/capabilities.browser.mjs +36 -0
  4. package/dist/lib/capabilities.browser.mjs.map +1 -0
  5. package/dist/lib/capabilities.mjs +6 -4
  6. package/dist/lib/capabilities.mjs.map +1 -1
  7. package/dist/lib/capabilities.node.mjs +5 -1
  8. package/dist/lib/capabilities.node.mjs.map +1 -1
  9. package/dist/lib/capabilities.tauri.mjs +36 -0
  10. package/dist/lib/capabilities.tauri.mjs.map +1 -0
  11. package/dist/lib/capabilities.workerd.mjs.map +1 -1
  12. package/dist/lib/chunk-CollectionArticle.mjs +13 -8
  13. package/dist/lib/chunk-CollectionArticle.mjs.map +1 -1
  14. package/dist/lib/chunk-DocumentArticle.mjs +8 -6
  15. package/dist/lib/chunk-DocumentArticle.mjs.map +1 -1
  16. package/dist/lib/chunk-PLUGIN.mjs +6 -0
  17. package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
  18. package/dist/lib/chunk-SlideArticle.mjs +2 -1
  19. package/dist/lib/chunk-SlideArticle.mjs.map +1 -1
  20. package/dist/lib/chunk-app-graph-builder.mjs +2 -0
  21. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -1
  22. package/dist/lib/chunk-markdown-extension.mjs.map +1 -1
  23. package/dist/lib/chunk-paths.mjs +11 -6
  24. package/dist/lib/chunk-paths.mjs.map +1 -1
  25. package/dist/lib/chunk-react-surface.mjs +3 -3
  26. package/dist/lib/chunk-react-surface.mjs.map +1 -1
  27. package/dist/lib/chunk-set-presenting.mjs +26 -21
  28. package/dist/lib/chunk-set-presenting.mjs.map +1 -1
  29. package/dist/lib/chunk-settings.mjs +2 -2
  30. package/dist/lib/chunk-settings.mjs.map +1 -1
  31. package/dist/lib/chunk-useExitPresenter.mjs +2 -2
  32. package/dist/lib/chunk-useExitPresenter.mjs.map +1 -1
  33. package/dist/lib/components.mjs +132 -69
  34. package/dist/lib/components.mjs.map +1 -1
  35. package/dist/lib/containers.mjs.map +1 -1
  36. package/dist/lib/index.mjs +0 -1
  37. package/dist/lib/meta.mjs.map +1 -1
  38. package/dist/lib/operations.mjs.map +1 -1
  39. package/dist/lib/translations.mjs.map +1 -1
  40. package/dist/types/src/capabilities/gen/browser.d.ts +9 -0
  41. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
  42. package/dist/types/src/capabilities/gen/tauri.d.ts +9 -0
  43. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
  44. package/dist/types/src/components/Markdown/Panel.d.ts +2 -2
  45. package/dist/types/src/components/Markdown/Panel.d.ts.map +1 -1
  46. package/dist/types/src/components/Markdown/Panel.stories.d.ts +1 -1
  47. package/dist/types/src/components/Markdown/Panel.stories.d.ts.map +1 -1
  48. package/dist/types/src/components/Markdown/Slide.stories.d.ts +1 -1
  49. package/dist/types/src/components/Markdown/Slide.stories.d.ts.map +1 -1
  50. package/dist/types/src/components/Markdown/index.d.ts +2 -2
  51. package/dist/types/src/components/Markdown/index.d.ts.map +1 -1
  52. package/dist/types/src/components/Presenter/Pager.d.ts.map +1 -1
  53. package/dist/types/src/components/Presenter/Pager.stories.d.ts +1 -1
  54. package/dist/types/src/components/Presenter/Pager.stories.d.ts.map +1 -1
  55. package/dist/types/src/components/Presenter/PresentationShell.d.ts +2 -2
  56. package/dist/types/src/components/Presenter/PresentationShell.d.ts.map +1 -1
  57. package/dist/types/src/components/Presenter/index.d.ts +4 -4
  58. package/dist/types/src/components/Presenter/index.d.ts.map +1 -1
  59. package/dist/types/src/components/RevealPlayer/RevealPlayer.d.ts.map +1 -1
  60. package/dist/types/src/components/RevealPlayer/RevealPlayer.stories.d.ts +9 -5
  61. package/dist/types/src/components/RevealPlayer/RevealPlayer.stories.d.ts.map +1 -1
  62. package/dist/types/src/components/RevealPlayer/index.d.ts +1 -1
  63. package/dist/types/src/components/RevealPlayer/index.d.ts.map +1 -1
  64. package/dist/types/src/components/index.d.ts +3 -3
  65. package/dist/types/src/components/index.d.ts.map +1 -1
  66. package/dist/types/src/containers/CollectionArticle/CollectionArticle.d.ts +1 -1
  67. package/dist/types/src/containers/CollectionArticle/CollectionArticle.d.ts.map +1 -1
  68. package/dist/types/src/containers/CollectionArticle/index.d.ts +1 -1
  69. package/dist/types/src/containers/CollectionArticle/index.d.ts.map +1 -1
  70. package/dist/types/src/containers/DocumentArticle/DocumentArticle.d.ts +1 -1
  71. package/dist/types/src/containers/DocumentArticle/DocumentArticle.d.ts.map +1 -1
  72. package/dist/types/src/containers/DocumentArticle/index.d.ts +1 -1
  73. package/dist/types/src/containers/DocumentArticle/index.d.ts.map +1 -1
  74. package/dist/types/src/containers/SlideArticle/SlideArticle.d.ts +1 -1
  75. package/dist/types/src/containers/SlideArticle/SlideArticle.d.ts.map +1 -1
  76. package/dist/types/src/containers/SlideArticle/index.d.ts +1 -1
  77. package/dist/types/src/containers/SlideArticle/index.d.ts.map +1 -1
  78. package/dist/types/src/containers/index.d.ts.map +1 -1
  79. package/dist/types/src/index.d.ts +1 -2
  80. package/dist/types/src/index.d.ts.map +1 -1
  81. package/dist/types/src/operations/set-presenting.d.ts +3 -2
  82. package/dist/types/src/operations/set-presenting.d.ts.map +1 -1
  83. package/dist/types/src/paths.d.ts +5 -4
  84. package/dist/types/src/paths.d.ts.map +1 -1
  85. package/dist/types/src/translations.d.ts.map +1 -1
  86. package/dist/types/src/types/PresenterCapabilities.d.ts +2 -2
  87. package/dist/types/src/types/PresenterCapabilities.d.ts.map +1 -1
  88. package/dist/types/src/types/index.d.ts +4 -4
  89. package/dist/types/src/types/index.d.ts.map +1 -1
  90. package/dist/types/tsconfig.tsbuildinfo +1 -1
  91. package/package.json +38 -29
  92. package/src/capabilities/app-graph-builder.ts +5 -3
  93. package/src/capabilities/gen/browser.ts +49 -0
  94. package/src/capabilities/gen/node.ts +5 -5
  95. package/src/capabilities/gen/tauri.ts +49 -0
  96. package/src/capabilities/gen/workerd.ts +3 -3
  97. package/src/capabilities/index.ts +6 -6
  98. package/src/capabilities/markdown-extension.ts +1 -1
  99. package/src/capabilities/react-surface.ts +3 -3
  100. package/src/capabilities/settings.ts +2 -2
  101. package/src/components/Markdown/Panel.stories.tsx +2 -2
  102. package/src/components/Markdown/Panel.tsx +3 -3
  103. package/src/components/Markdown/Slide.stories.tsx +1 -1
  104. package/src/components/Markdown/Slide.tsx +1 -1
  105. package/src/components/Markdown/index.ts +2 -2
  106. package/src/components/Presenter/Layout.tsx +3 -3
  107. package/src/components/Presenter/Pager.stories.tsx +1 -1
  108. package/src/components/Presenter/Pager.tsx +18 -17
  109. package/src/components/Presenter/PresentationShell.tsx +25 -8
  110. package/src/components/Presenter/index.ts +4 -4
  111. package/src/components/RevealPlayer/RevealPlayer.stories.tsx +125 -3
  112. package/src/components/RevealPlayer/RevealPlayer.tsx +153 -72
  113. package/src/components/RevealPlayer/index.ts +1 -1
  114. package/src/components/index.ts +3 -3
  115. package/src/containers/CollectionArticle/CollectionArticle.tsx +17 -10
  116. package/src/containers/CollectionArticle/index.ts +1 -1
  117. package/src/containers/DocumentArticle/DocumentArticle.tsx +12 -10
  118. package/src/containers/DocumentArticle/index.ts +1 -1
  119. package/src/containers/SlideArticle/SlideArticle.tsx +3 -2
  120. package/src/containers/SlideArticle/index.ts +1 -1
  121. package/src/containers/index.ts +3 -3
  122. package/src/index.ts +1 -2
  123. package/src/meta.ts +1 -1
  124. package/src/operations/index.ts +1 -1
  125. package/src/operations/set-presenting.ts +28 -26
  126. package/src/paths.ts +17 -8
  127. package/src/plugin.test.ts +2 -2
  128. package/src/translations.ts +2 -2
  129. package/src/types/PresenterCapabilities.ts +2 -2
  130. package/src/types/index.ts +4 -4
  131. package/src/typings.d.ts +10 -1
  132. package/src/useExitPresenter.ts +2 -2
package/PLUGIN.mdl CHANGED
@@ -15,9 +15,11 @@ Each extension is defined in the Appendix or resolved via its URI.
15
15
  |-------------|--------------------------------|
16
16
  | `type` | `org.dxos.mdl.type@1.0` |
17
17
  | `feat` | `org.dxos.mdl.feat@1.0` |
18
- | `test` | `org.dxos.mdl.test@1.0` |
18
+ | `scenario` | `org.dxos.mdl.scenario@1.0` |
19
19
  | `component` | `org.dxos.mdl.component@1.0` |
20
- | `op` | `org.dxos.mdl.op@1.0` |
20
+ | `op` | `org.dxos.mdl.op@1.1` |
21
+ | `test` | `org.dxos.mdl.test@1.0` |
22
+ | `step` | `org.dxos.mdl.step@1.0` |
21
23
 
22
24
  ## Types
23
25
 
@@ -109,20 +111,20 @@ component SlideArticle
109
111
 
110
112
  ```mdl
111
113
  op TogglePresentation
114
+ key: org.dxos.operation.presenter.setPresenting
112
115
  desc: |
113
- Toggles presentation mode for a Markdown document or Collection.
114
- Opens the presenter companion node via the Deck plugin, driving the deck's ephemeral
115
- fullscreen state (EphemeralDeckState.fullscreen) rather than a layout mode.
116
- If the presenter companion isn't already fullscreen, toggles it fullscreen before opening;
117
- exiting reverts fullscreen and re-opens the source object.
116
+ Enters or exits presentation for a Markdown document or Collection by toggling the deck's
117
+ fullscreen overlay (EphemeralDeckState.fullscreen) onto the presenter companion node.
118
+ The overlay is independent of what is open, so neither direction navigates: the URL and the
119
+ open planks are unchanged.
118
120
  input:
119
121
  object: Markdown.Document | Collection.Collection
120
- state?: boolean # explicit on/off override; omit to toggle
122
+ state: boolean # on or off; callers that flip read the current state first
121
123
  output: void
122
- effects: [layout:navigate, deck:fullscreen]
123
- requires: [DeckCapabilities.State, DeckOperation.Adjust, LayoutOperation.Open]
124
+ effects: [deck:fullscreen]
125
+ requires: [DeckCapabilities.EphemeralState, DeckOperation.Adjust]
124
126
  note: |
125
- Resolves the presenter companion node path as `<objectPath>/presenter`.
127
+ Resolves the presenter companion node path as `<objectPath>/~presenter`.
126
128
  Keyboard shortcut: Shift+Cmd+P (macOS), Shift+Alt+P (Windows/Linux).
127
129
  ```
128
130
 
@@ -137,7 +139,7 @@ feat F-1: Presentation Mode
137
139
  then: every Collection also has a companion Presenter node
138
140
  req F-1.3:
139
141
  when: user activates TogglePresentation on a document or collection
140
- then: Composer opens the presenter node in solo-fullscreen mode
142
+ then: the presenter companion fills the screen in the deck's fullscreen overlay, without the companion tab strip, and the URL does not change
141
143
  req F-1.4:
142
144
  when: user presses Shift+Cmd+P (macOS) or Shift+Alt+P (Windows)
143
145
  then: TogglePresentation is invoked for the focused object
@@ -182,7 +184,7 @@ feat F-4: Plugin Settings
182
184
  ## Acceptance
183
185
 
184
186
  ```mdl
185
- test T-1: Document presenter opens in fullscreen
187
+ scenario T-1: Document presenter opens in fullscreen
186
188
  given: a Markdown document exists in the workspace
187
189
  when: user invokes TogglePresentation (keyboard or action menu)
188
190
  then:
@@ -192,7 +194,7 @@ test T-1: Document presenter opens in fullscreen
192
194
  ```
193
195
 
194
196
  ```mdl
195
- test T-2: Slide navigation via Reveal.js
197
+ scenario T-2: Slide navigation via Reveal.js
196
198
  given: a Markdown document with three `---`-separated sections
197
199
  when: DocumentArticle renders the document
198
200
  then:
@@ -201,14 +203,14 @@ test T-2: Slide navigation via Reveal.js
201
203
  ```
202
204
 
203
205
  ```mdl
204
- test T-3: Exit returns to document view
206
+ scenario T-3: Exit returns to document view
205
207
  given: DocumentArticle is open in fullscreen
206
208
  when: user presses Escape
207
- then: Composer navigates back to the document article view
209
+ then: the fullscreen overlay closes, leaving the document and its companion as they were
208
210
  ```
209
211
 
210
212
  ```mdl
211
- test T-4: Collection slideshow renders per-item surfaces
213
+ scenario T-4: Collection slideshow renders per-item surfaces
212
214
  given: a Collection with two Markdown documents and settings.presentCollections = true
213
215
  when: CollectionArticle mounts
214
216
  then:
@@ -217,7 +219,7 @@ test T-4: Collection slideshow renders per-item surfaces
217
219
  ```
218
220
 
219
221
  ```mdl
220
- test T-5: Collection slide advance
222
+ scenario T-5: Collection slide advance
221
223
  given: CollectionArticle at slide 0 with a three-item collection
222
224
  when: user clicks the next-slide control in Pager
223
225
  then:
@@ -227,14 +229,14 @@ test T-5: Collection slide advance
227
229
  ```
228
230
 
229
231
  ```mdl
230
- test T-6: Collections hidden when setting disabled
232
+ scenario T-6: Collections hidden when setting disabled
231
233
  given: settings.presentCollections is false (default)
232
234
  when: app graph is built for a Collection node
233
235
  then: no Presenter companion node is created for the collection
234
236
  ```
235
237
 
236
238
  ```mdl
237
- test T-7: Keyboard shortcut registered
239
+ scenario T-7: Keyboard shortcut registered
238
240
  given: a Markdown document node is focused in the app graph
239
241
  then:
240
242
  - action with key TogglePresentation is present on the node
@@ -243,6 +245,60 @@ test T-7: Keyboard shortcut registered
243
245
 
244
246
  ---
245
247
 
248
+ ## QA
249
+
250
+ Executable tests. Each step carries a human instruction (`do`) and, where the step maps to an
251
+ invocable operation, an agent binding (`invoke`). Report failures by test and step number.
252
+
253
+ ```mdl
254
+ test QA-1: Preview a document in the companion, then present it
255
+ desc: The core presenter round-trip — create a document with slide separators, preview it in the presenter companion, present it fullscreen, then exit.
256
+ actors: both
257
+ covers: [F-1.1, F-1.3, F-2.1, F-2.2, F-2.3, T-1, T-3]
258
+ status: unverified
259
+ automated:
260
+ - composer-e2e:presenter.spec.ts#Presenter › preview a document in the companion, then present it
261
+ given:
262
+ - an identity exists
263
+ - space: a space is open
264
+ - collection: a collection in that space, to create into
265
+ - plugin-presenter is enabled — it is OFF by default (absent from `getDefaults` in
266
+ `plugin-defs.tsx`), though the plugin itself is registered unconditionally so it always
267
+ appears in the plugin registry to enable manually
268
+ - no document named "QA Slides" exists — ABORT rather than deleting one this test did not create
269
+ steps:
270
+ - name: Create a document with slides
271
+ do: In the navtree, click + on a collection and choose Markdown. Name it "QA Slides".
272
+ invoke: org.dxos.operation.markdown.createDraft { name: "QA Slides", content: "# Slide one\n\n---\n\n# Slide two\n" }
273
+ capture: created
274
+ expect: a Document named "QA Slides" now exists with two `---`-separated sections
275
+ assert: return !!$created.object
276
+ - name: Place it
277
+ do: (the navtree create action places it for you)
278
+ invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }
279
+ expect: "QA Slides" appears as a row under the collection
280
+ - name: Preview in the companion
281
+ do: Open "QA Slides", open its companion and pick the Presenter tab.
282
+ expect: the companion shows "Slide one" as a slide scaled to the companion's width
283
+ - name: Enter presentation mode
284
+ do: Choose Present from the document's actions menu, or press Shift+Cmd+P (macOS) / Shift+Alt+P (Windows/Linux).
285
+ invoke: org.dxos.operation.presenter.setPresenting { object: $created.object, state: true }
286
+ expect: the slides fill the screen showing "Slide one", with no companion tab strip; the URL is unchanged
287
+ assert: return document.body.innerText.includes('Slide one');
288
+ - name: Exit presentation mode
289
+ do: Press Escape.
290
+ invoke: org.dxos.operation.presenter.setPresenting { object: $created.object, state: false }
291
+ expect: the document plank and its presenter companion are back as they were, and the URL is unchanged
292
+ assert: return !!document.querySelector('[data-testid="deck.viewport"]');
293
+ after:
294
+ - name: Delete the document
295
+ do: Right-click "QA Slides" in the navtree and choose Delete.
296
+ invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }
297
+ expect: the row leaves the navtree and its plank closes
298
+ ```
299
+
300
+ ---
301
+
246
302
  ## Appendix: Extension Definitions
247
303
 
248
304
  Extension block types used in this document are defined below using
@@ -270,8 +326,8 @@ ext feat
270
326
  ```
271
327
 
272
328
  ```mdl
273
- ext test
274
- uri: org.dxos.mdl.test@1.0
329
+ ext scenario
330
+ uri: org.dxos.mdl.scenario@1.0
275
331
  desc: An acceptance scenario expressed as given / when / then steps.
276
332
  fields:
277
333
  given?: Step | Step[]
@@ -1 +1 @@
1
- {"version":3,"file":"PresenterCapabilities.mjs","names":[],"sources":["../../src/types/PresenterCapabilities.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/unstable/reactivity/Atom';\n\nimport * as Capability from '@dxos/app-framework/Capability';\n\nimport { meta } from '#meta';\n\n// Inline import to avoid `Settings` namespace alias colliding with the\n// `Settings` capability export below.\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n"],"mappings":";;;;;AAcA,IAAa,WAAW,WAAW,cAA4D,CAAC,CAC9F,GAAG,KAAK,QAAQ,IAAI,qBACtB"}
1
+ {"version":3,"file":"PresenterCapabilities.mjs","names":[],"sources":["../../src/types/PresenterCapabilities.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/reactivity/Atom';\n\nimport * as Capability from '@dxos/app-framework/Capability';\n\nimport { meta } from '#meta';\n\n// Inline import to avoid `Settings` namespace alias colliding with the\n// `Settings` capability export below.\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings.ts').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n"],"mappings":";;;;;AAcA,IAAa,WAAW,WAAW,cAA+D,CAAC,CACjG,GAAG,KAAK,QAAQ,IAAI,qBACtB"}
@@ -0,0 +1,36 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import * as MarkdownCapabilities from "@dxos/plugin-markdown/MarkdownCapabilities";
6
+ import * as MarkdownEvents from "@dxos/plugin-markdown/MarkdownEvents";
7
+ import { translations } from "#translations";
8
+ import { PresenterCapabilities } from "#types";
9
+ import { meta } from "#meta";
10
+ //#region src/capabilities/gen/browser.ts
11
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: [
12
+ "browser",
13
+ "node",
14
+ "tauri"
15
+ ] });
16
+ var MarkdownExtension = Capability.lazyModule("MarkdownExtension", {
17
+ provides: [MarkdownCapabilities.ExtensionProvider],
18
+ activatesOn: MarkdownEvents.Start
19
+ }, () => import("./chunk-markdown-extension.mjs"));
20
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
21
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article", "org.dxos.role.slide"] });
22
+ var PresenterSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
23
+ activatesOn: ActivationEvents.Idle,
24
+ provides: [PresenterCapabilities.Settings]
25
+ });
26
+ var Translations = AppCapability.translations(translations);
27
+ var PluginAsset = AppCapability.pluginAsset({
28
+ pluginId: meta.profile.key,
29
+ path: "PLUGIN.mdl",
30
+ content: PLUGIN_default,
31
+ mimeType: "application/x-mdl"
32
+ });
33
+ //#endregion
34
+ export { AppGraphBuilder, MarkdownExtension, OperationHandler, PluginAsset, PresenterSettings, ReactSurface, Translations };
35
+
36
+ //# 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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'), {\n environments: ['browser', 'node', 'tauri'],\n});\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.slide'],\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\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"],"mappings":";;;;;;;;;;AAkBA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAA4B,EACpG,cAAc;CAAC;CAAW;CAAQ;AAAO,EAC3C,CAAC;AAED,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,yBAAyB,qBAAqB,EACxD,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAmB;CACtF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
1
2
  import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
2
3
  import * as Capability from "@dxos/app-framework/Capability";
3
4
  import * as AppCapability from "@dxos/app-toolkit/AppCapability";
@@ -6,11 +7,12 @@ import * as MarkdownEvents from "@dxos/plugin-markdown/MarkdownEvents";
6
7
  import { translations } from "#translations";
7
8
  import { PresenterCapabilities } from "#types";
8
9
  import { meta } from "#meta";
9
- //#region PLUGIN.mdl?raw
10
- var PLUGIN_default = "---\nid: org.dxos.plugin.presenter\nname: PresenterPlugin\nversion: 0.1.0\n---\n\nA presentation plugin for DXOS Composer that turns existing workspace objects — markdown documents and collections — into interactive slideshows with fullscreen mode and keyboard navigation.\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 PresentationTarget\n literals: document | collection\n desc: The kind of workspace object being presented.\n```\n\n```mdl\ntype SlideIndex\n fields:\n current: number # zero-based index of the active slide\n count: number # total number of slides in the presentation\n```\n\n```mdl\ntype PresentationSettings\n fields:\n presentCollections?: boolean # when true, Collections may also be presented as slideshows (experimental)\n```\n\n## Components\n\n```mdl\ncomponent DocumentArticle\n desc: |\n Full-screen Reveal.js player for a single Markdown document.\n Parses the document content into slides using horizontal/vertical `---` separators.\n Renders in a Panel that fills the available viewport.\n props:\n document: Markdown.Document\n slots:\n (none)\n actions:\n exit() # navigates back to the originating document view\n layout: |\n ┌─────────────────────────────┐\n │ │\n │ RevealPlayer │\n │ (full-screen slide canvas) │\n │ │\n └─────────────────────────────┘\n```\n\n```mdl\ncomponent CollectionArticle\n desc: |\n Slideshow player for a Collection.\n Renders one slide per object in the collection's ordered items array.\n The active slide is delegated to the AppSurface.Slide surface, so each\n item's own plugin renders it (e.g. SlideArticle for documents).\n props:\n subject: Collection.Collection\n role?: string\n state:\n slide: number # zero-based index of the current slide\n running: boolean # whether keyboard navigation is active (from PresenterContext)\n slots:\n (none)\n actions:\n setSlide(index: number)\n exit()\n layout: |\n ┌─────────────────────────────┐\n │ │\n │ Surface (slide N) │ ← AppSurface.Slide surface\n │ │\n ├────────────────┬────────────┤\n │ [Pager] │ [PageNum] │\n └────────────────┴────────────┘\n```\n\n```mdl\ncomponent SlideArticle\n desc: |\n Renders a single Markdown document as a slide panel inside a Collection presentation.\n Used as the AppSurface.Slide surface implementation for Markdown.Document objects.\n props:\n document: Markdown.Document\n layout: |\n ┌─────────────────────────────┐\n │ Panel │\n │ └─ Slide (markdown) │\n └─────────────────────────────┘\n```\n\n## Operations\n\n```mdl\nop TogglePresentation\n desc: |\n Toggles presentation mode for a Markdown document or Collection.\n Opens the presenter companion node via the Deck plugin, driving the deck's ephemeral\n fullscreen state (EphemeralDeckState.fullscreen) rather than a layout mode.\n If the presenter companion isn't already fullscreen, toggles it fullscreen before opening;\n exiting reverts fullscreen and re-opens the source object.\n input:\n object: Markdown.Document | Collection.Collection\n state?: boolean # explicit on/off override; omit to toggle\n output: void\n effects: [layout:navigate, deck:fullscreen]\n requires: [DeckCapabilities.State, DeckOperation.Adjust, LayoutOperation.Open]\n note: |\n Resolves the presenter companion node path as `<objectPath>/presenter`.\n Keyboard shortcut: Shift+Cmd+P (macOS), Shift+Alt+P (Windows/Linux).\n```\n\n## Features\n\n```mdl\nfeat F-1: Presentation Mode\n\n req F-1.1: Every Markdown document in the workspace has a companion \"Presenter\" node in the app graph.\n req F-1.2:\n when: settings.presentCollections is true\n then: every Collection also has a companion Presenter node\n req F-1.3:\n when: user activates TogglePresentation on a document or collection\n then: Composer opens the presenter node in solo-fullscreen mode\n req F-1.4:\n when: user presses Shift+Cmd+P (macOS) or Shift+Alt+P (Windows)\n then: TogglePresentation is invoked for the focused object\n```\n\n```mdl\nfeat F-2: Document Slideshow (Reveal.js)\n\n req F-2.1:\n when: DocumentArticle mounts with a Markdown.Document\n then: RevealPlayer parses the document content and renders slides\n req F-2.2: Horizontal slides are separated by `---`; vertical slides by `----`.\n req F-2.3:\n when: user presses Escape or the exit action is triggered\n then: presenter navigates back to the originating document view\n```\n\n```mdl\nfeat F-3: Collection Slideshow\n\n req F-3.1:\n when: CollectionArticle mounts with a Collection\n then: slide 0 is shown, corresponding to collection.objects[0]\n req F-3.2:\n when: user navigates to slide N via the Pager\n then: the AppSurface.Slide surface renders collection.objects[N]\n req F-3.3: PageNumber displays the current slide index and total count.\n req F-3.4:\n when: user presses Escape or the exit action is triggered\n then: presenter navigates back to the collection view\n```\n\n```mdl\nfeat F-4: Plugin Settings\n\n req F-4.1: PresenterSettings panel is registered for the plugin settings surface.\n req F-4.2:\n when: user enables \"Present collections (experimental)\"\n then: settings.presentCollections is set to true and Collection nodes gain Presenter companions\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Document presenter opens in fullscreen\n given: a Markdown document exists in the workspace\n when: user invokes TogglePresentation (keyboard or action menu)\n then:\n - Composer switches to solo-fullscreen layout\n - DocumentArticle is shown with the document content\n - RevealPlayer is visible with at least one slide\n```\n\n```mdl\ntest T-2: Slide navigation via Reveal.js\n given: a Markdown document with three `---`-separated sections\n when: DocumentArticle renders the document\n then:\n - three horizontal slides are produced\n - arrow-key navigation advances and retreats between slides\n```\n\n```mdl\ntest T-3: Exit returns to document view\n given: DocumentArticle is open in fullscreen\n when: user presses Escape\n then: Composer navigates back to the document article view\n```\n\n```mdl\ntest T-4: Collection slideshow renders per-item surfaces\n given: a Collection with two Markdown documents and settings.presentCollections = true\n when: CollectionArticle mounts\n then:\n - slide 0 shows SlideArticle for collection.objects[0]\n - Pager shows count = 2\n```\n\n```mdl\ntest T-5: Collection slide advance\n given: CollectionArticle at slide 0 with a three-item collection\n when: user clicks the next-slide control in Pager\n then:\n - slide index advances to 1\n - AppSurface.Slide renders collection.objects[1]\n - PageNumber shows \"2 / 3\"\n```\n\n```mdl\ntest T-6: Collections hidden when setting disabled\n given: settings.presentCollections is false (default)\n when: app graph is built for a Collection node\n then: no Presenter companion node is created for the collection\n```\n\n```mdl\ntest T-7: Keyboard shortcut registered\n given: a Markdown document node is focused in the app graph\n then:\n - action with key TogglePresentation is present on the node\n - keyBinding shows Shift+Cmd+P on macOS\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\n literals?: UnionList\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\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\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\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\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n";
11
- //#endregion
12
10
  //#region src/capabilities/index.ts
13
- var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: ["node"] });
11
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: [
12
+ "browser",
13
+ "node",
14
+ "tauri"
15
+ ] });
14
16
  var MarkdownExtension = Capability.lazyModule("MarkdownExtension", {
15
17
  provides: [MarkdownCapabilities.ExtensionProvider],
16
18
  activatesOn: MarkdownEvents.Start
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\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'), {\n environments: ['node'],\n});\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('./markdown-extension'),\n);\nexport const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler'), {\n activatesOn: ActivationEvents.Idle,\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.slide'],\n});\nexport const PresenterSettings = AppCapability.settings(() => import('./settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\nexport const Translations = AppCapability.translations(translations);\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n"],"mappings":";;;;;;;;;;;;AAiBA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAAwB,EAChG,cAAc,CAAC,MAAM,EACvB,CAAC;AACD,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AACA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAAwB,EAClG,aAAa,iBAAiB,KAChC,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAoB,EACjF,OAAO,CAAC,yBAAyB,qBAAqB,EACxD,CAAC;AACD,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAe;CAClF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY;AACnE,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC"}
1
+ {"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\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'), {\n environments: ['browser', 'node', 'tauri'],\n});\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('./markdown-extension.ts'),\n);\nexport const OperationHandler = AppCapability.operationHandler(() => import('./operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\nexport const ReactSurface = AppCapability.surface(() => import('./react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.slide'],\n});\nexport const PresenterSettings = AppCapability.settings(() => import('./settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\nexport const Translations = AppCapability.translations(translations);\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n"],"mappings":";;;;;;;;;;AAiBA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAA2B,EACnG,cAAc;CAAC;CAAW;CAAQ;AAAO,EAC3C,CAAC;AACD,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AACA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA2B,EACrG,aAAa,iBAAiB,KAChC,CAAC;AACD,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAuB,EACpF,OAAO,CAAC,yBAAyB,qBAAqB,EACxD,CAAC;AACD,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAkB;CACrF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY;AACnE,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC"}
@@ -6,7 +6,11 @@ import * as MarkdownEvents from "@dxos/plugin-markdown/MarkdownEvents";
6
6
  import { translations } from "#translations";
7
7
  import { PresenterCapabilities } from "#types";
8
8
  //#region src/capabilities/gen/node.ts
9
- var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: ["node"] });
9
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: [
10
+ "browser",
11
+ "node",
12
+ "tauri"
13
+ ] });
10
14
  var MarkdownExtension = Capability.lazyModule("MarkdownExtension", {
11
15
  provides: [MarkdownCapabilities.ExtensionProvider],
12
16
  activatesOn: MarkdownEvents.Start
@@ -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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder'), {\n environments: ['node'],\n});\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;AAeA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAAyB,EACjG,cAAc,CAAC,MAAM,EACvB,CAAC;AAED,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAAyB,EACnG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAgB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'), {\n environments: ['browser', 'node', 'tauri'],\n});\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;AAeA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAA4B,EACpG,cAAc;CAAC;CAAW;CAAQ;AAAO,EAC3C,CAAC;AAED,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAmB;CACtF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -0,0 +1,36 @@
1
+ import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
2
+ import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
3
+ import * as Capability from "@dxos/app-framework/Capability";
4
+ import * as AppCapability from "@dxos/app-toolkit/AppCapability";
5
+ import * as MarkdownCapabilities from "@dxos/plugin-markdown/MarkdownCapabilities";
6
+ import * as MarkdownEvents from "@dxos/plugin-markdown/MarkdownEvents";
7
+ import { translations } from "#translations";
8
+ import { PresenterCapabilities } from "#types";
9
+ import { meta } from "#meta";
10
+ //#region src/capabilities/gen/tauri.ts
11
+ var AppGraphBuilder = AppCapability.appGraphBuilder(() => import("./chunk-app-graph-builder.mjs"), { environments: [
12
+ "browser",
13
+ "node",
14
+ "tauri"
15
+ ] });
16
+ var MarkdownExtension = Capability.lazyModule("MarkdownExtension", {
17
+ provides: [MarkdownCapabilities.ExtensionProvider],
18
+ activatesOn: MarkdownEvents.Start
19
+ }, () => import("./chunk-markdown-extension.mjs"));
20
+ var OperationHandler = AppCapability.operationHandler(() => import("./chunk-operation-handler.mjs"), { activatesOn: ActivationEvents.Idle });
21
+ var ReactSurface = AppCapability.surface(() => import("./chunk-react-surface.mjs"), { roles: ["org.dxos.role.article", "org.dxos.role.slide"] });
22
+ var PresenterSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
23
+ activatesOn: ActivationEvents.Idle,
24
+ provides: [PresenterCapabilities.Settings]
25
+ });
26
+ var Translations = AppCapability.translations(translations);
27
+ var PluginAsset = AppCapability.pluginAsset({
28
+ pluginId: meta.profile.key,
29
+ path: "PLUGIN.mdl",
30
+ content: PLUGIN_default,
31
+ mimeType: "application/x-mdl"
32
+ });
33
+ //#endregion
34
+ export { AppGraphBuilder, MarkdownExtension, OperationHandler, PluginAsset, PresenterSettings, ReactSurface, Translations };
35
+
36
+ //# 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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\nexport const AppGraphBuilder = AppCapability.appGraphBuilder(() => import('../app-graph-builder.ts'), {\n environments: ['browser', 'node', 'tauri'],\n});\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const ReactSurface = AppCapability.surface(() => import('../react-surface.ts'), {\n roles: ['org.dxos.role.article', 'org.dxos.role.slide'],\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\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"],"mappings":";;;;;;;;;;AAkBA,IAAa,kBAAkB,cAAc,sBAAsB,OAAO,kCAA4B,EACpG,cAAc;CAAC;CAAW;CAAQ;AAAO,EAC3C,CAAC;AAED,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,eAAe,cAAc,cAAc,OAAO,8BAAwB,EACrF,OAAO,CAAC,yBAAyB,qBAAqB,EACxD,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAmB;CACtF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC"}
@@ -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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const AppGraphBuilder = undefined;\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;AAeA,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAAyB,EACnG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAgB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,kBAAkB,KAAA;AAC/B,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 ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as MarkdownCapabilities from '@dxos/plugin-markdown/MarkdownCapabilities';\nimport * as MarkdownEvents from '@dxos/plugin-markdown/MarkdownEvents';\n\nimport { translations } from '#translations';\nimport { PresenterCapabilities } from '#types';\n\nexport const MarkdownExtension = Capability.lazyModule(\n 'MarkdownExtension',\n { provides: [MarkdownCapabilities.ExtensionProvider], activatesOn: MarkdownEvents.Start },\n () => import('../markdown-extension.ts'),\n);\n\nexport const OperationHandler = AppCapability.operationHandler(() => import('../operation-handler.ts'), {\n activatesOn: ActivationEvents.Idle,\n});\n\nexport const PresenterSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [PresenterCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const AppGraphBuilder = undefined;\nexport const PluginAsset = undefined;\nexport const ReactSurface = undefined;\n"],"mappings":";;;;;;;;AAeA,IAAa,oBAAoB,WAAW,WAC1C,qBACA;CAAE,UAAU,CAAC,qBAAqB,iBAAiB;CAAG,aAAa,eAAe;AAAM,SAClF,OAAO,iCACf;AAEA,IAAa,mBAAmB,cAAc,uBAAuB,OAAO,kCAA4B,EACtG,aAAa,iBAAiB,KAChC,CAAC;AAED,IAAa,oBAAoB,cAAc,eAAe,OAAO,yBAAmB;CACtF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,sBAAsB,QAAQ;AAC3C,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,kBAAkB,KAAA;AAC/B,IAAa,cAAc,KAAA;AAC3B,IAAa,eAAe,KAAA"}
@@ -1,38 +1,43 @@
1
1
  import { t as useExitPresenter } from "./chunk-useExitPresenter.mjs";
2
2
  import { useContext, useState } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
- import { Panel } from "@dxos/react-ui";
5
4
  import { Obj } from "@dxos/echo";
6
- import { Surface } from "@dxos/app-framework/ui";
7
- import { AppSurface } from "@dxos/app-toolkit/ui";
5
+ import * as Surface from "@dxos/app-framework/Surface";
6
+ import * as AppSurface from "@dxos/app-toolkit/AppSurface";
7
+ import * as Hooks from "@dxos/app-toolkit/Hooks";
8
+ import { useObject } from "@dxos/echo-react";
9
+ import * as Panel$1 from "@dxos/react-ui/Panel";
8
10
  import { Layout, PageNumber, Pager, PresentationShell, PresenterContext } from "#components";
9
11
  //#region src/containers/CollectionArticle/CollectionArticle.tsx
10
12
  var CollectionArticle = ({ role, subject: collection }) => {
11
13
  const [slide, setSlide] = useState(0);
12
14
  const { running } = useContext(PresenterContext);
13
15
  const handleExit = useExitPresenter(collection);
14
- return /* @__PURE__ */ jsx(Panel.Root, {
16
+ const fullscreen = Hooks.useLayout().mode === "solo--fullscreen";
17
+ const [liveCollection] = useObject(collection);
18
+ return /* @__PURE__ */ jsx(Panel$1.Root, {
15
19
  role,
16
20
  classNames: "relative",
17
- children: /* @__PURE__ */ jsx(Panel.Content, {
21
+ children: /* @__PURE__ */ jsx(Panel$1.Body, {
18
22
  asChild: true,
19
23
  children: /* @__PURE__ */ jsx(PresentationShell, {
24
+ fullscreen,
20
25
  onExit: handleExit,
21
26
  children: /* @__PURE__ */ jsx(Layout, {
22
27
  bottomRight: /* @__PURE__ */ jsx(PageNumber, {
23
28
  index: slide,
24
- count: collection.objects.length
29
+ count: liveCollection.objects.length
25
30
  }),
26
31
  bottomLeft: /* @__PURE__ */ jsx(Pager, {
27
32
  index: slide,
28
- count: collection.objects.length,
33
+ count: liveCollection.objects.length,
29
34
  keys: running,
30
35
  onChange: setSlide
31
36
  }),
32
37
  children: /* @__PURE__ */ jsx(Surface.Surface, {
33
38
  type: AppSurface.Slide,
34
39
  data: {
35
- subject: collection.objects[slide],
40
+ subject: liveCollection.objects[slide],
36
41
  attendableId: Obj.getURI(collection)
37
42
  }
38
43
  })
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-CollectionArticle.mjs","names":[],"sources":["../../src/containers/CollectionArticle/CollectionArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useContext, useState } from 'react';\n\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { type Collection, Obj } from '@dxos/echo';\nimport { Panel } from '@dxos/react-ui';\n\nimport { PageNumber, Pager, PresentationShell, PresenterContext, Layout as PresenterLayout } from '#components';\n\nimport { useExitPresenter } from '../../useExitPresenter';\n\nexport type CollectionArticleProps = AppSurface.ObjectArticleProps<Collection.Collection>;\n\nexport const CollectionArticle = ({ role, subject: collection }: CollectionArticleProps) => {\n const [slide, setSlide] = useState(0);\n const { running } = useContext(PresenterContext);\n const handleExit = useExitPresenter(collection);\n\n return (\n <Panel.Root role={role} classNames='relative'>\n <Panel.Content asChild>\n <PresentationShell onExit={handleExit}>\n <PresenterLayout\n bottomRight={<PageNumber index={slide} count={collection.objects.length} />}\n bottomLeft={<Pager index={slide} count={collection.objects.length} keys={running} onChange={setSlide} />}\n >\n <Surface.Surface\n type={AppSurface.Slide}\n data={{\n subject: collection.objects[slide],\n attendableId: Obj.getURI(collection),\n }}\n />\n </PresenterLayout>\n </PresentationShell>\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nCollectionArticle.displayName = 'CollectionArticle';\n"],"mappings":";;;;;;;;;AAiBA,IAAa,qBAAqB,EAAE,MAAM,SAAS,iBAAyC;CAC1F,MAAM,CAAC,OAAO,YAAY,SAAS,CAAC;CACpC,MAAM,EAAE,YAAY,WAAW,gBAAgB;CAC/C,MAAM,aAAa,iBAAiB,UAAU;CAE9C,OACE,oBAAC,MAAM,MAAP;EAAkB;EAAM,YAAW;EACjC,UAAA,oBAAC,MAAM,SAAP;GAAe,SAAA;GACb,UAAA,oBAAC,mBAAD;IAAmB,QAAQ;IACzB,UAAA,oBAAC,QAAD;KACE,aAAa,oBAAC,YAAD;MAAY,OAAO;MAAO,OAAO,WAAW,QAAQ;KAAS,CAAA;KAC1E,YAAY,oBAAC,OAAD;MAAO,OAAO;MAAO,OAAO,WAAW,QAAQ;MAAQ,MAAM;MAAS,UAAU;KAAW,CAAA;KAEvG,UAAA,oBAAC,QAAQ,SAAT;MACE,MAAM,WAAW;MACjB,MAAM;OACJ,SAAS,WAAW,QAAQ;OAC5B,cAAc,IAAI,OAAO,UAAU;MACrC;KACD,CAAA;IACc,CAAA;GACA,CAAA;EACN,CAAA;CACL,CAAA;AAEhB;AAEA,kBAAkB,cAAc"}
1
+ {"version":3,"file":"chunk-CollectionArticle.mjs","names":[],"sources":["../../src/containers/CollectionArticle/CollectionArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useContext, useState } from 'react';\n\nimport * as Surface from '@dxos/app-framework/Surface';\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport { type Collection, Obj } from '@dxos/echo';\nimport { useObject } from '@dxos/echo-react';\nimport * as Panel from '@dxos/react-ui/Panel';\n\nimport { PageNumber, Pager, PresentationShell, PresenterContext, Layout as PresenterLayout } from '#components';\n\nimport { useExitPresenter } from '../../useExitPresenter.ts';\n\nexport type CollectionArticleProps = AppSurface.ObjectArticleProps<Collection.Collection>;\n\nexport const CollectionArticle = ({ role, subject: collection }: CollectionArticleProps) => {\n const [slide, setSlide] = useState(0);\n const { running } = useContext(PresenterContext);\n const handleExit = useExitPresenter(collection);\n const layout = Hooks.useLayout();\n const fullscreen = layout.mode === 'solo--fullscreen';\n const [liveCollection] = useObject(collection);\n\n return (\n <Panel.Root role={role} classNames='relative'>\n <Panel.Body asChild>\n <PresentationShell fullscreen={fullscreen} onExit={handleExit}>\n <PresenterLayout\n bottomRight={<PageNumber index={slide} count={liveCollection.objects.length} />}\n bottomLeft={\n <Pager index={slide} count={liveCollection.objects.length} keys={running} onChange={setSlide} />\n }\n >\n <Surface.Surface\n type={AppSurface.Slide}\n data={{\n subject: liveCollection.objects[slide],\n attendableId: Obj.getURI(collection),\n }}\n />\n </PresenterLayout>\n </PresentationShell>\n </Panel.Body>\n </Panel.Root>\n );\n};\n\nCollectionArticle.displayName = 'CollectionArticle';\n"],"mappings":";;;;;;;;;;;AAmBA,IAAa,qBAAqB,EAAE,MAAM,SAAS,iBAAyC;CAC1F,MAAM,CAAC,OAAO,YAAY,SAAS,CAAC;CACpC,MAAM,EAAE,YAAY,WAAW,gBAAgB;CAC/C,MAAM,aAAa,iBAAiB,UAAU;CAE9C,MAAM,aADS,MAAM,UACF,CAAA,CAAO,SAAS;CACnC,MAAM,CAAC,kBAAkB,UAAU,UAAU;CAE7C,OACE,oBAAC,QAAM,MAAP;EAAkB;EAAM,YAAW;EACjC,UAAA,oBAAC,QAAM,MAAP;GAAY,SAAA;GACV,UAAA,oBAAC,mBAAD;IAA+B;IAAY,QAAQ;IACjD,UAAA,oBAAC,QAAD;KACE,aAAa,oBAAC,YAAD;MAAY,OAAO;MAAO,OAAO,eAAe,QAAQ;KAAS,CAAA;KAC9E,YACE,oBAAC,OAAD;MAAO,OAAO;MAAO,OAAO,eAAe,QAAQ;MAAQ,MAAM;MAAS,UAAU;KAAW,CAAA;KAGjG,UAAA,oBAAC,QAAQ,SAAT;MACE,MAAM,WAAW;MACjB,MAAM;OACJ,SAAS,eAAe,QAAQ;OAChC,cAAc,IAAI,OAAO,UAAU;MACrC;KACD,CAAA;IACc,CAAA;GACA,CAAA;EACT,CAAA;CACF,CAAA;AAEhB;AAEA,kBAAkB,cAAc"}
@@ -1,23 +1,25 @@
1
1
  import { t as useExitPresenter } from "./chunk-useExitPresenter.mjs";
2
2
  import "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
- import { Panel } from "@dxos/react-ui";
5
- import { useLayout } from "@dxos/app-toolkit/ui";
4
+ import * as Hooks from "@dxos/app-toolkit/Hooks";
5
+ import { useObject } from "@dxos/echo-react";
6
+ import * as Panel$1 from "@dxos/react-ui/Panel";
6
7
  import { PresentationShell, RevealPlayer } from "#components";
7
8
  //#region src/containers/DocumentArticle/DocumentArticle.tsx
8
9
  var DocumentArticle = ({ role, subject: document }) => {
9
10
  const handleExit = useExitPresenter(document);
10
- const fullscreen = useLayout().mode === "solo--fullscreen";
11
- const content = document.content.target?.content;
12
- return /* @__PURE__ */ jsx(Panel.Root, {
11
+ const fullscreen = Hooks.useLayout().mode === "solo--fullscreen";
12
+ const [content] = useObject(document.content, "content");
13
+ return /* @__PURE__ */ jsx(Panel$1.Root, {
13
14
  role,
14
15
  classNames: "relative",
15
- children: /* @__PURE__ */ jsx(Panel.Content, {
16
+ children: /* @__PURE__ */ jsx(Panel$1.Body, {
16
17
  asChild: true,
17
18
  children: /* @__PURE__ */ jsx(PresentationShell, {
18
19
  fullscreen,
19
20
  onExit: handleExit,
20
21
  children: content !== void 0 && /* @__PURE__ */ jsx(RevealPlayer, {
22
+ "data-testid": "presenter.deck",
21
23
  fullscreen,
22
24
  content
23
25
  })
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-DocumentArticle.mjs","names":[],"sources":["../../src/containers/DocumentArticle/DocumentArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { AppSurface, useLayout } from '@dxos/app-toolkit/ui';\nimport type * as Markdown from '@dxos/plugin-markdown/Markdown';\nimport { Panel } from '@dxos/react-ui';\n\nimport { PresentationShell, RevealPlayer } from '#components';\n\nimport { useExitPresenter } from '../../useExitPresenter';\n\nexport type DocumentArticleProps = AppSurface.ObjectArticleProps<Markdown.Document>;\n\nexport const DocumentArticle = ({ role, subject: document }: DocumentArticleProps) => {\n const handleExit = useExitPresenter(document);\n const layout = useLayout();\n const fullscreen = layout.mode === 'solo--fullscreen';\n // RevealPlayer seeds its deck once from `content` (via a `defaultValue`); wait for the markdown ref to\n // resolve so the presentation isn't initialized empty and left blank when the content arrives later.\n const content = document.content.target?.content;\n\n return (\n <Panel.Root role={role} classNames='relative'>\n <Panel.Content asChild>\n <PresentationShell fullscreen={fullscreen} onExit={handleExit}>\n {content !== undefined && <RevealPlayer fullscreen={fullscreen} content={content} />}\n </PresentationShell>\n </Panel.Content>\n </Panel.Root>\n );\n};\n\nDocumentArticle.displayName = 'DocumentArticle';\n"],"mappings":";;;;;;;AAgBA,IAAa,mBAAmB,EAAE,MAAM,SAAS,eAAqC;CACpF,MAAM,aAAa,iBAAiB,QAAQ;CAE5C,MAAM,aADS,UACI,CAAA,CAAO,SAAS;CAGnC,MAAM,UAAU,SAAS,QAAQ,QAAQ;CAEzC,OACE,oBAAC,MAAM,MAAP;EAAkB;EAAM,YAAW;EACjC,UAAA,oBAAC,MAAM,SAAP;GAAe,SAAA;GACb,UAAA,oBAAC,mBAAD;IAA+B;IAAY,QAAQ;IAChD,UAAA,YAAY,KAAA,KAAa,oBAAC,cAAD;KAA0B;KAAqB;IAAU,CAAA;GAClE,CAAA;EACN,CAAA;CACL,CAAA;AAEhB;AAEA,gBAAgB,cAAc"}
1
+ {"version":3,"file":"chunk-DocumentArticle.mjs","names":[],"sources":["../../src/containers/DocumentArticle/DocumentArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport { useObject } from '@dxos/echo-react';\nimport type * as Markdown from '@dxos/plugin-markdown/Markdown';\nimport * as Panel from '@dxos/react-ui/Panel';\n\nimport { PresentationShell, RevealPlayer } from '#components';\n\nimport { useExitPresenter } from '../../useExitPresenter.ts';\n\nexport type DocumentArticleProps = AppSurface.ObjectArticleProps<Markdown.Document>;\n\nexport const DocumentArticle = ({ role, subject: document }: DocumentArticleProps) => {\n const handleExit = useExitPresenter(document);\n const layout = Hooks.useLayout();\n const fullscreen = layout.mode === 'solo--fullscreen';\n const [content] = useObject(document.content, 'content');\n\n return (\n <Panel.Root role={role} classNames='relative'>\n <Panel.Body asChild>\n <PresentationShell fullscreen={fullscreen} onExit={handleExit}>\n {content !== undefined && (\n <RevealPlayer data-testid='presenter.deck' fullscreen={fullscreen} content={content} />\n )}\n </PresentationShell>\n </Panel.Body>\n </Panel.Root>\n );\n};\n\nDocumentArticle.displayName = 'DocumentArticle';\n"],"mappings":";;;;;;;;AAkBA,IAAa,mBAAmB,EAAE,MAAM,SAAS,eAAqC;CACpF,MAAM,aAAa,iBAAiB,QAAQ;CAE5C,MAAM,aADS,MAAM,UACF,CAAA,CAAO,SAAS;CACnC,MAAM,CAAC,WAAW,UAAU,SAAS,SAAS,SAAS;CAEvD,OACE,oBAAC,QAAM,MAAP;EAAkB;EAAM,YAAW;EACjC,UAAA,oBAAC,QAAM,MAAP;GAAY,SAAA;GACV,UAAA,oBAAC,mBAAD;IAA+B;IAAY,QAAQ;IAChD,UAAA,YAAY,KAAA,KACX,oBAAC,cAAD;KAAc,eAAY;KAA6B;KAAqB;IAAU,CAAA;GAEvE,CAAA;EACT,CAAA;CACF,CAAA;AAEhB;AAEA,gBAAgB,cAAc"}
@@ -0,0 +1,6 @@
1
+ //#region PLUGIN.mdl?raw
2
+ var PLUGIN_default = "---\nid: org.dxos.plugin.presenter\nname: PresenterPlugin\nversion: 0.1.0\n---\n\nA presentation plugin for DXOS Composer that turns existing workspace objects — markdown documents and collections — into interactive slideshows with fullscreen mode and keyboard navigation.\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| `scenario` | `org.dxos.mdl.scenario@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.1` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `step` | `org.dxos.mdl.step@1.0` |\n\n## Types\n\n```mdl\ntype PresentationTarget\n literals: document | collection\n desc: The kind of workspace object being presented.\n```\n\n```mdl\ntype SlideIndex\n fields:\n current: number # zero-based index of the active slide\n count: number # total number of slides in the presentation\n```\n\n```mdl\ntype PresentationSettings\n fields:\n presentCollections?: boolean # when true, Collections may also be presented as slideshows (experimental)\n```\n\n## Components\n\n```mdl\ncomponent DocumentArticle\n desc: |\n Full-screen Reveal.js player for a single Markdown document.\n Parses the document content into slides using horizontal/vertical `---` separators.\n Renders in a Panel that fills the available viewport.\n props:\n document: Markdown.Document\n slots:\n (none)\n actions:\n exit() # navigates back to the originating document view\n layout: |\n ┌─────────────────────────────┐\n │ │\n │ RevealPlayer │\n │ (full-screen slide canvas) │\n │ │\n └─────────────────────────────┘\n```\n\n```mdl\ncomponent CollectionArticle\n desc: |\n Slideshow player for a Collection.\n Renders one slide per object in the collection's ordered items array.\n The active slide is delegated to the AppSurface.Slide surface, so each\n item's own plugin renders it (e.g. SlideArticle for documents).\n props:\n subject: Collection.Collection\n role?: string\n state:\n slide: number # zero-based index of the current slide\n running: boolean # whether keyboard navigation is active (from PresenterContext)\n slots:\n (none)\n actions:\n setSlide(index: number)\n exit()\n layout: |\n ┌─────────────────────────────┐\n │ │\n │ Surface (slide N) │ ← AppSurface.Slide surface\n │ │\n ├────────────────┬────────────┤\n │ [Pager] │ [PageNum] │\n └────────────────┴────────────┘\n```\n\n```mdl\ncomponent SlideArticle\n desc: |\n Renders a single Markdown document as a slide panel inside a Collection presentation.\n Used as the AppSurface.Slide surface implementation for Markdown.Document objects.\n props:\n document: Markdown.Document\n layout: |\n ┌─────────────────────────────┐\n │ Panel │\n │ └─ Slide (markdown) │\n └─────────────────────────────┘\n```\n\n## Operations\n\n```mdl\nop TogglePresentation\n key: org.dxos.operation.presenter.setPresenting\n desc: |\n Enters or exits presentation for a Markdown document or Collection by toggling the deck's\n fullscreen overlay (EphemeralDeckState.fullscreen) onto the presenter companion node.\n The overlay is independent of what is open, so neither direction navigates: the URL and the\n open planks are unchanged.\n input:\n object: Markdown.Document | Collection.Collection\n state: boolean # on or off; callers that flip read the current state first\n output: void\n effects: [deck:fullscreen]\n requires: [DeckCapabilities.EphemeralState, DeckOperation.Adjust]\n note: |\n Resolves the presenter companion node path as `<objectPath>/~presenter`.\n Keyboard shortcut: Shift+Cmd+P (macOS), Shift+Alt+P (Windows/Linux).\n```\n\n## Features\n\n```mdl\nfeat F-1: Presentation Mode\n\n req F-1.1: Every Markdown document in the workspace has a companion \"Presenter\" node in the app graph.\n req F-1.2:\n when: settings.presentCollections is true\n then: every Collection also has a companion Presenter node\n req F-1.3:\n when: user activates TogglePresentation on a document or collection\n then: the presenter companion fills the screen in the deck's fullscreen overlay, without the companion tab strip, and the URL does not change\n req F-1.4:\n when: user presses Shift+Cmd+P (macOS) or Shift+Alt+P (Windows)\n then: TogglePresentation is invoked for the focused object\n```\n\n```mdl\nfeat F-2: Document Slideshow (Reveal.js)\n\n req F-2.1:\n when: DocumentArticle mounts with a Markdown.Document\n then: RevealPlayer parses the document content and renders slides\n req F-2.2: Horizontal slides are separated by `---`; vertical slides by `----`.\n req F-2.3:\n when: user presses Escape or the exit action is triggered\n then: presenter navigates back to the originating document view\n```\n\n```mdl\nfeat F-3: Collection Slideshow\n\n req F-3.1:\n when: CollectionArticle mounts with a Collection\n then: slide 0 is shown, corresponding to collection.objects[0]\n req F-3.2:\n when: user navigates to slide N via the Pager\n then: the AppSurface.Slide surface renders collection.objects[N]\n req F-3.3: PageNumber displays the current slide index and total count.\n req F-3.4:\n when: user presses Escape or the exit action is triggered\n then: presenter navigates back to the collection view\n```\n\n```mdl\nfeat F-4: Plugin Settings\n\n req F-4.1: PresenterSettings panel is registered for the plugin settings surface.\n req F-4.2:\n when: user enables \"Present collections (experimental)\"\n then: settings.presentCollections is set to true and Collection nodes gain Presenter companions\n```\n\n## Acceptance\n\n```mdl\nscenario T-1: Document presenter opens in fullscreen\n given: a Markdown document exists in the workspace\n when: user invokes TogglePresentation (keyboard or action menu)\n then:\n - Composer switches to solo-fullscreen layout\n - DocumentArticle is shown with the document content\n - RevealPlayer is visible with at least one slide\n```\n\n```mdl\nscenario T-2: Slide navigation via Reveal.js\n given: a Markdown document with three `---`-separated sections\n when: DocumentArticle renders the document\n then:\n - three horizontal slides are produced\n - arrow-key navigation advances and retreats between slides\n```\n\n```mdl\nscenario T-3: Exit returns to document view\n given: DocumentArticle is open in fullscreen\n when: user presses Escape\n then: the fullscreen overlay closes, leaving the document and its companion as they were\n```\n\n```mdl\nscenario T-4: Collection slideshow renders per-item surfaces\n given: a Collection with two Markdown documents and settings.presentCollections = true\n when: CollectionArticle mounts\n then:\n - slide 0 shows SlideArticle for collection.objects[0]\n - Pager shows count = 2\n```\n\n```mdl\nscenario T-5: Collection slide advance\n given: CollectionArticle at slide 0 with a three-item collection\n when: user clicks the next-slide control in Pager\n then:\n - slide index advances to 1\n - AppSurface.Slide renders collection.objects[1]\n - PageNumber shows \"2 / 3\"\n```\n\n```mdl\nscenario T-6: Collections hidden when setting disabled\n given: settings.presentCollections is false (default)\n when: app graph is built for a Collection node\n then: no Presenter companion node is created for the collection\n```\n\n```mdl\nscenario T-7: Keyboard shortcut registered\n given: a Markdown document node is focused in the app graph\n then:\n - action with key TogglePresentation is present on the node\n - keyBinding shows Shift+Cmd+P on macOS\n```\n\n---\n\n## QA\n\nExecutable tests. Each step carries a human instruction (`do`) and, where the step maps to an\ninvocable operation, an agent binding (`invoke`). Report failures by test and step number.\n\n```mdl\ntest QA-1: Preview a document in the companion, then present it\n desc: The core presenter round-trip — create a document with slide separators, preview it in the presenter companion, present it fullscreen, then exit.\n actors: both\n covers: [F-1.1, F-1.3, F-2.1, F-2.2, F-2.3, T-1, T-3]\n status: unverified\n automated:\n - composer-e2e:presenter.spec.ts#Presenter › preview a document in the companion, then present it\n given:\n - an identity exists\n - space: a space is open\n - collection: a collection in that space, to create into\n - plugin-presenter is enabled — it is OFF by default (absent from `getDefaults` in\n `plugin-defs.tsx`), though the plugin itself is registered unconditionally so it always\n appears in the plugin registry to enable manually\n - no document named \"QA Slides\" exists — ABORT rather than deleting one this test did not create\n steps:\n - name: Create a document with slides\n do: In the navtree, click + on a collection and choose Markdown. Name it \"QA Slides\".\n invoke: org.dxos.operation.markdown.createDraft { name: \"QA Slides\", content: \"# Slide one\\n\\n---\\n\\n# Slide two\\n\" }\n capture: created\n expect: a Document named \"QA Slides\" now exists with two `---`-separated sections\n assert: return !!$created.object\n - name: Place it\n do: (the navtree create action places it for you)\n invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }\n expect: \"QA Slides\" appears as a row under the collection\n - name: Preview in the companion\n do: Open \"QA Slides\", open its companion and pick the Presenter tab.\n expect: the companion shows \"Slide one\" as a slide scaled to the companion's width\n - name: Enter presentation mode\n do: Choose Present from the document's actions menu, or press Shift+Cmd+P (macOS) / Shift+Alt+P (Windows/Linux).\n invoke: org.dxos.operation.presenter.setPresenting { object: $created.object, state: true }\n expect: the slides fill the screen showing \"Slide one\", with no companion tab strip; the URL is unchanged\n assert: return document.body.innerText.includes('Slide one');\n - name: Exit presentation mode\n do: Press Escape.\n invoke: org.dxos.operation.presenter.setPresenting { object: $created.object, state: false }\n expect: the document plank and its presenter companion are back as they were, and the URL is unchanged\n assert: return !!document.querySelector('[data-testid=\"deck.viewport\"]');\n after:\n - name: Delete the document\n do: Right-click \"QA Slides\" in the navtree and choose Delete.\n invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }\n expect: the row leaves the navtree and its plank closes\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\n literals?: UnionList\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\n```\n\n```mdl\next scenario\n uri: org.dxos.mdl.scenario@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\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\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\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n";
3
+ //#endregion
4
+ export { PLUGIN_default as t };
5
+
6
+ //# sourceMappingURL=chunk-PLUGIN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-PLUGIN.mjs","names":[],"sources":[],"mappings":""}
@@ -1,9 +1,10 @@
1
1
  import "react";
2
2
  import { jsx } from "react/jsx-runtime";
3
+ import { useObject } from "@dxos/echo-react";
3
4
  import { Panel, Slide } from "#components";
4
5
  //#region src/containers/SlideArticle/SlideArticle.tsx
5
6
  var SlideArticle = ({ subject: document }) => {
6
- const content = document.content.target?.content;
7
+ const [content] = useObject(document.content, "content");
7
8
  if (!content) return null;
8
9
  return /* @__PURE__ */ jsx(Panel, {
9
10
  classNames: "border",
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-SlideArticle.mjs","names":[],"sources":["../../src/containers/SlideArticle/SlideArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport type * as Markdown from '@dxos/plugin-markdown/Markdown';\n\nimport { Panel, Slide } from '#components';\n\nexport type SlideArticleProps = AppSurface.ObjectSectionProps<Markdown.Document>;\n\nexport const SlideArticle = ({ subject: document }: SlideArticleProps) => {\n const content = document.content.target?.content;\n if (!content) {\n return null;\n }\n\n return (\n <Panel classNames='border'>\n <Slide content={content} />\n </Panel>\n );\n};\n\nSlideArticle.displayName = 'SlideArticle';\n"],"mappings":";;;;AAaA,IAAa,gBAAgB,EAAE,SAAS,eAAkC;CACxE,MAAM,UAAU,SAAS,QAAQ,QAAQ;CACzC,IAAI,CAAC,SACH,OAAO;CAGT,OACE,oBAAC,OAAD;EAAO,YAAW;EAChB,UAAA,oBAAC,OAAD,EAAgB,QAAU,CAAA;CACrB,CAAA;AAEX;AAEA,aAAa,cAAc"}
1
+ {"version":3,"file":"chunk-SlideArticle.mjs","names":[],"sources":["../../src/containers/SlideArticle/SlideArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport { useObject } from '@dxos/echo-react';\nimport type * as Markdown from '@dxos/plugin-markdown/Markdown';\n\nimport { Panel, Slide } from '#components';\n\nexport type SlideArticleProps = AppSurface.ObjectSectionProps<Markdown.Document>;\n\nexport const SlideArticle = ({ subject: document }: SlideArticleProps) => {\n const [content] = useObject(document.content, 'content');\n if (!content) {\n return null;\n }\n\n return (\n <Panel classNames='border'>\n <Slide content={content} />\n </Panel>\n );\n};\n\nSlideArticle.displayName = 'SlideArticle';\n"],"mappings":";;;;;AAcA,IAAa,gBAAgB,EAAE,SAAS,eAAkC;CACxE,MAAM,CAAC,WAAW,UAAU,SAAS,SAAS,SAAS;CACvD,IAAI,CAAC,SACH,OAAO;CAGT,OACE,oBAAC,OAAD;EAAO,YAAW;EAChB,UAAA,oBAAC,OAAD,EAAgB,QAAU,CAAA;CACrB,CAAA;AAEX;AAEA,aAAa,cAAc"}
@@ -24,6 +24,7 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
24
24
  };
25
25
  const extensions = yield* AppGraphBuilder.createExtension({
26
26
  id: "root",
27
+ relation: AppNode.companion,
27
28
  match: whenPresentable,
28
29
  connector: (object, get) => {
29
30
  if (!isPresentable(object, get)) return Effect.succeed([]);
@@ -53,6 +54,7 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
53
54
  label: ["toggle-presentation.label", { ns: meta.profile.key }],
54
55
  icon: "ph--presentation--regular",
55
56
  disposition: "list-item",
57
+ testId: "presenter.present",
56
58
  keyBinding: {
57
59
  macos: "shift+meta+p",
58
60
  windows: "shift+alt+p"
@@ -1 +1 @@
1
- {"version":3,"file":"chunk-app-graph-builder.mjs","names":[],"sources":["../../src/capabilities/app-graph-builder.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\nimport type * as Atom from 'effect/unstable/reactivity/Atom';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppGraphBuilder from '@dxos/app-graph/AppGraphBuilder';\nimport type * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppNode from '@dxos/app-toolkit/AppNode';\nimport * as AppNodeMatcher from '@dxos/app-toolkit/AppNodeMatcher';\nimport * as Operation from '@dxos/compute/Operation';\nimport { Collection, Obj } from '@dxos/echo';\nimport * as DeckCapabilities from '@dxos/plugin-deck/DeckCapabilities';\nimport * as Markdown from '@dxos/plugin-markdown/Markdown';\n\nimport { meta } from '#meta';\nimport { PresenterCapabilities, PresenterOperation } from '#types';\n\nimport { isPresenting } from '../paths';\n\n/** Match nodes that can be presented (Collection or Document). */\nconst whenPresentable = (node: AppGraphNode.Node, get: Atom.AtomContext) =>\n Option.orElse(AppNodeMatcher.whenEchoType(Collection.Collection)(node, get), () =>\n AppNodeMatcher.whenEchoType(Markdown.Document)(node, get),\n );\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n // Read reactively so the extension establishes a dependency and heals once this\n // capability lands (dependency modules contribute individually, not batched per wave).\n const settingsCapabilityAtom = yield* Capability.atom(PresenterCapabilities.Settings);\n\n const isPresentable = (object: Obj.Any, get: Atom.AtomContext) => {\n const [settingsAtom] = get(settingsCapabilityAtom);\n const settings = settingsAtom ? get(settingsAtom) : undefined;\n return settings?.presentCollections\n ? Obj.instanceOf(Collection.Collection, object) || Obj.instanceOf(Markdown.Document, object)\n : Obj.instanceOf(Markdown.Document, object);\n };\n\n const extensions = yield* AppGraphBuilder.createExtension({\n id: 'root',\n // TODO(wittjosiah): This is a hack to work around presenter previously relying on \"variant\". Remove.\n match: whenPresentable,\n connector: (object, get) => {\n if (!isPresentable(object, get)) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n AppNode.makeCompanion({\n variant: 'presenter',\n label: 'Presenter',\n icon: 'ph--presentation--regular',\n data: { type: meta.profile.key, object },\n }),\n ]);\n },\n actions: (object, get) => {\n const db = Obj.getDatabase(object);\n if (!isPresentable(object, get) || !db) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n {\n id: PresenterOperation.SetPresenting.meta.key,\n // The menu item flips, so it reads the current state and states the one it wants.\n data: Effect.fnUntraced(function* () {\n const ephemeral = yield* Capabilities.getAtomValue(DeckCapabilities.EphemeralState);\n yield* Operation.invoke(PresenterOperation.SetPresenting, {\n object,\n state: !isPresenting(ephemeral, object),\n });\n }),\n properties: {\n label: ['toggle-presentation.label', { ns: meta.profile.key }],\n icon: 'ph--presentation--regular',\n disposition: 'list-item',\n keyBinding: {\n macos: 'shift+meta+p',\n windows: 'shift+alt+p',\n },\n },\n },\n ]);\n },\n });\n\n return Capability.contribute(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAM,mBAAmB,MAAyB,QAChD,OAAO,OAAO,eAAe,aAAa,WAAW,UAAU,CAAC,CAAC,MAAM,GAAG,SACxE,eAAe,aAAa,SAAS,QAAQ,CAAC,CAAC,MAAM,GAAG,CAC1D;AAEF,IAAA,4BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAG7B,MAAM,yBAAyB,OAAO,WAAW,KAAK,sBAAsB,QAAQ;CAEpF,MAAM,iBAAiB,QAAiB,QAA0B;EAChE,MAAM,CAAC,gBAAgB,IAAI,sBAAsB;EAEjD,QADiB,eAAe,IAAI,YAAY,IAAI,KAAA,EAAA,EACnC,qBACb,IAAI,WAAW,WAAW,YAAY,MAAM,KAAK,IAAI,WAAW,SAAS,UAAU,MAAM,IACzF,IAAI,WAAW,SAAS,UAAU,MAAM;CAC9C;CAEA,MAAM,aAAa,OAAO,gBAAgB,gBAAgB;EACxD,IAAI;EAEJ,OAAO;EACP,YAAY,QAAQ,QAAQ;GAC1B,IAAI,CAAC,cAAc,QAAQ,GAAG,GAC5B,OAAO,OAAO,QAAQ,CAAC,CAAC;GAG1B,OAAO,OAAO,QAAQ,CACpB,QAAQ,cAAc;IACpB,SAAS;IACT,OAAO;IACP,MAAM;IACN,MAAM;KAAE,MAAM,KAAK,QAAQ;KAAK;IAAO;GACzC,CAAC,CACH,CAAC;EACH;EACA,UAAU,QAAQ,QAAQ;GACxB,MAAM,KAAK,IAAI,YAAY,MAAM;GACjC,IAAI,CAAC,cAAc,QAAQ,GAAG,KAAK,CAAC,IAClC,OAAO,OAAO,QAAQ,CAAC,CAAC;GAG1B,OAAO,OAAO,QAAQ,CACpB;IACE,IAAI,mBAAmB,cAAc,KAAK;IAE1C,MAAM,OAAO,WAAW,aAAa;KACnC,MAAM,YAAY,OAAO,aAAa,aAAa,iBAAiB,cAAc;KAClF,OAAO,UAAU,OAAO,mBAAmB,eAAe;MACxD;MACA,OAAO,CAAC,aAAa,WAAW,MAAM;KACxC,CAAC;IACH,CAAC;IACD,YAAY;KACV,OAAO,CAAC,6BAA6B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;KAC7D,MAAM;KACN,aAAa;KACb,YAAY;MACV,OAAO;MACP,SAAS;KACX;IACF;GACF,CACF,CAAC;EACH;CACF,CAAC;CAED,OAAO,WAAW,WAAW,gBAAgB,iBAAiB,UAAU;AAC1E,CAAC,CACH"}
1
+ {"version":3,"file":"chunk-app-graph-builder.mjs","names":[],"sources":["../../src/capabilities/app-graph-builder.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\nimport type * as Atom from 'effect/reactivity/Atom';\n\nimport * as Capabilities from '@dxos/app-framework/Capabilities';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppGraphBuilder from '@dxos/app-graph/AppGraphBuilder';\nimport * as AppGraphNode from '@dxos/app-graph/AppGraphNode';\nimport * as AppCapabilities from '@dxos/app-toolkit/AppCapabilities';\nimport * as AppNode from '@dxos/app-toolkit/AppNode';\nimport * as AppNodeMatcher from '@dxos/app-toolkit/AppNodeMatcher';\nimport * as Operation from '@dxos/compute/Operation';\nimport { Collection, Obj } from '@dxos/echo';\nimport * as DeckCapabilities from '@dxos/plugin-deck/DeckCapabilities';\nimport * as Markdown from '@dxos/plugin-markdown/Markdown';\n\nimport { meta } from '#meta';\nimport { PresenterCapabilities, PresenterOperation } from '#types';\n\nimport { isPresenting } from '../paths.ts';\n\n/** Match nodes that can be presented (Collection or Document). */\nconst whenPresentable = (node: AppGraphNode.Node, get: Atom.AtomContext) =>\n Option.orElse(AppNodeMatcher.whenEchoType(Collection.Collection)(node, get), () =>\n AppNodeMatcher.whenEchoType(Markdown.Document)(node, get),\n );\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n // Read reactively so the extension establishes a dependency and heals once this\n // capability lands (dependency modules contribute individually, not batched per wave).\n const settingsCapabilityAtom = yield* Capability.atom(PresenterCapabilities.Settings);\n\n const isPresentable = (object: Obj.Any, get: Atom.AtomContext) => {\n const [settingsAtom] = get(settingsCapabilityAtom);\n const settings = settingsAtom ? get(settingsAtom) : undefined;\n return settings?.presentCollections\n ? Obj.instanceOf(Collection.Collection, object) || Obj.instanceOf(Markdown.Document, object)\n : Obj.instanceOf(Markdown.Document, object);\n };\n\n const extensions = yield* AppGraphBuilder.createExtension({\n id: 'root',\n relation: AppNode.companion,\n // TODO(wittjosiah): This is a hack to work around presenter previously relying on \"variant\". Remove.\n match: whenPresentable,\n connector: (object, get) => {\n if (!isPresentable(object, get)) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n AppNode.makeCompanion({\n variant: 'presenter',\n label: 'Presenter',\n icon: 'ph--presentation--regular',\n data: { type: meta.profile.key, object },\n }),\n ]);\n },\n actions: (object, get) => {\n const db = Obj.getDatabase(object);\n if (!isPresentable(object, get) || !db) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n {\n id: PresenterOperation.SetPresenting.meta.key,\n // The menu item flips, so it reads the current state and states the one it wants.\n data: Effect.fnUntraced(function* () {\n const ephemeral = yield* Capabilities.getAtomValue(DeckCapabilities.EphemeralState);\n yield* Operation.invoke(PresenterOperation.SetPresenting, {\n object,\n state: !isPresenting(ephemeral, object),\n });\n }),\n properties: {\n label: ['toggle-presentation.label', { ns: meta.profile.key }],\n icon: 'ph--presentation--regular',\n disposition: 'list-item',\n testId: 'presenter.present',\n keyBinding: {\n macos: 'shift+meta+p',\n windows: 'shift+alt+p',\n },\n },\n },\n ]);\n },\n });\n\n return Capability.contribute(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAM,mBAAmB,MAAyB,QAChD,OAAO,OAAO,eAAe,aAAa,WAAW,UAAU,CAAC,CAAC,MAAM,GAAG,SACxE,eAAe,aAAa,SAAS,QAAQ,CAAC,CAAC,MAAM,GAAG,CAC1D;AAEF,IAAA,4BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAG7B,MAAM,yBAAyB,OAAO,WAAW,KAAK,sBAAsB,QAAQ;CAEpF,MAAM,iBAAiB,QAAiB,QAA0B;EAChE,MAAM,CAAC,gBAAgB,IAAI,sBAAsB;EAEjD,QADiB,eAAe,IAAI,YAAY,IAAI,KAAA,EAAA,EACnC,qBACb,IAAI,WAAW,WAAW,YAAY,MAAM,KAAK,IAAI,WAAW,SAAS,UAAU,MAAM,IACzF,IAAI,WAAW,SAAS,UAAU,MAAM;CAC9C;CAEA,MAAM,aAAa,OAAO,gBAAgB,gBAAgB;EACxD,IAAI;EACJ,UAAU,QAAQ;EAElB,OAAO;EACP,YAAY,QAAQ,QAAQ;GAC1B,IAAI,CAAC,cAAc,QAAQ,GAAG,GAC5B,OAAO,OAAO,QAAQ,CAAC,CAAC;GAG1B,OAAO,OAAO,QAAQ,CACpB,QAAQ,cAAc;IACpB,SAAS;IACT,OAAO;IACP,MAAM;IACN,MAAM;KAAE,MAAM,KAAK,QAAQ;KAAK;IAAO;GACzC,CAAC,CACH,CAAC;EACH;EACA,UAAU,QAAQ,QAAQ;GACxB,MAAM,KAAK,IAAI,YAAY,MAAM;GACjC,IAAI,CAAC,cAAc,QAAQ,GAAG,KAAK,CAAC,IAClC,OAAO,OAAO,QAAQ,CAAC,CAAC;GAG1B,OAAO,OAAO,QAAQ,CACpB;IACE,IAAI,mBAAmB,cAAc,KAAK;IAE1C,MAAM,OAAO,WAAW,aAAa;KACnC,MAAM,YAAY,OAAO,aAAa,aAAa,iBAAiB,cAAc;KAClF,OAAO,UAAU,OAAO,mBAAmB,eAAe;MACxD;MACA,OAAO,CAAC,aAAa,WAAW,MAAM;KACxC,CAAC;IACH,CAAC;IACD,YAAY;KACV,OAAO,CAAC,6BAA6B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;KAC7D,MAAM;KACN,aAAa;KACb,QAAQ;KACR,YAAY;MACV,OAAO;MACP,SAAS;KACX;IACF;GACF,CACF,CAAC;EACH;CACF,CAAC;CAED,OAAO,WAAW,WAAW,gBAAgB,iBAAiB,UAAU;AAC1E,CAAC,CACH"}