@dxos/plugin-presenter 0.9.0 → 0.9.1-main.c7dcc2e112

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 (104) hide show
  1. package/dist/lib/neutral/{CollectionPresenterArticle-DFREOQTG.mjs → CollectionPresenterArticle-ZRYWBX2H.mjs} +7 -6
  2. package/dist/lib/neutral/CollectionPresenterArticle-ZRYWBX2H.mjs.map +7 -0
  3. package/dist/lib/neutral/{DocumentPresenterContainer-KCDZ2O2C.mjs → DocumentPresenterContainer-5QF4P736.mjs} +7 -6
  4. package/dist/lib/neutral/DocumentPresenterContainer-5QF4P736.mjs.map +7 -0
  5. package/dist/lib/neutral/PresenterPlugin.mjs +10 -3
  6. package/dist/lib/neutral/PresenterPlugin.mjs.map +4 -4
  7. package/dist/lib/neutral/{PresenterSettings-2G4XD4QY.mjs → PresenterSettings-4YFP4K5G.mjs} +3 -3
  8. package/dist/lib/neutral/{PresenterSettings-2G4XD4QY.mjs.map → PresenterSettings-4YFP4K5G.mjs.map} +3 -3
  9. package/dist/lib/neutral/{app-graph-builder-DIEDSRPX.mjs → app-graph-builder-JMQVBFG2.mjs} +7 -23
  10. package/dist/lib/neutral/app-graph-builder-JMQVBFG2.mjs.map +7 -0
  11. package/dist/lib/neutral/capabilities/index.mjs +7 -3
  12. package/dist/lib/neutral/capabilities/index.mjs.map +3 -3
  13. package/dist/lib/neutral/chunk-63IF7OXT.mjs +19 -0
  14. package/dist/lib/neutral/chunk-63IF7OXT.mjs.map +7 -0
  15. package/dist/lib/neutral/{chunk-VVALMI52.mjs → chunk-H5JLSLAO.mjs} +7 -3
  16. package/dist/lib/neutral/chunk-H5JLSLAO.mjs.map +7 -0
  17. package/dist/lib/neutral/chunk-MSQDHOPV.mjs +47 -0
  18. package/dist/lib/neutral/chunk-MSQDHOPV.mjs.map +7 -0
  19. package/dist/lib/neutral/components/index.mjs +87 -18
  20. package/dist/lib/neutral/components/index.mjs.map +4 -4
  21. package/dist/lib/neutral/containers/index.mjs +2 -2
  22. package/dist/lib/neutral/index.mjs +2 -2
  23. package/dist/lib/neutral/markdown-extension-HGLRVZDF.mjs +37 -0
  24. package/dist/lib/neutral/markdown-extension-HGLRVZDF.mjs.map +7 -0
  25. package/dist/lib/neutral/meta.json +1 -1
  26. package/dist/lib/neutral/meta.mjs +1 -1
  27. package/dist/lib/neutral/operation-handler-3ZESW5AK.mjs +13 -0
  28. package/dist/lib/neutral/operation-handler-3ZESW5AK.mjs.map +7 -0
  29. package/dist/lib/neutral/operations/index.mjs +9 -0
  30. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  31. package/dist/lib/neutral/plugin.mjs +1 -1
  32. package/dist/lib/neutral/{react-surface-SPJGAJIF.mjs → react-surface-YGBE3TDK.mjs} +4 -4
  33. package/dist/lib/neutral/react-surface-YGBE3TDK.mjs.map +7 -0
  34. package/dist/lib/neutral/{settings-R6LRDAAK.mjs → settings-DBV7N5HT.mjs} +3 -3
  35. package/dist/lib/neutral/{settings-R6LRDAAK.mjs.map → settings-DBV7N5HT.mjs.map} +3 -3
  36. package/dist/lib/neutral/toggle-presentation-PH7ZJJDD.mjs +60 -0
  37. package/dist/lib/neutral/toggle-presentation-PH7ZJJDD.mjs.map +7 -0
  38. package/dist/lib/neutral/translations.mjs +1 -1
  39. package/dist/lib/neutral/translations.mjs.map +3 -3
  40. package/dist/lib/neutral/types/index.mjs +1 -1
  41. package/dist/types/dx.config.d.ts +28 -0
  42. package/dist/types/dx.config.d.ts.map +1 -0
  43. package/dist/types/src/PresenterPlugin.d.ts.map +1 -1
  44. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  45. package/dist/types/src/capabilities/index.d.ts +6 -3
  46. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  47. package/dist/types/src/capabilities/markdown-extension.d.ts +9 -0
  48. package/dist/types/src/capabilities/markdown-extension.d.ts.map +1 -0
  49. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  50. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  51. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  52. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  53. package/dist/types/src/components/Presenter/PresentationShell.d.ts +18 -0
  54. package/dist/types/src/components/Presenter/PresentationShell.d.ts.map +1 -0
  55. package/dist/types/src/components/Presenter/index.d.ts +1 -0
  56. package/dist/types/src/components/Presenter/index.d.ts.map +1 -1
  57. package/dist/types/src/containers/CollectionPresenterArticle/CollectionPresenterArticle.d.ts.map +1 -1
  58. package/dist/types/src/containers/DocumentPresenterContainer/DocumentPresenterContainer.d.ts.map +1 -1
  59. package/dist/types/src/meta.d.ts +28 -2
  60. package/dist/types/src/meta.d.ts.map +1 -1
  61. package/dist/types/src/operations/index.d.ts +3 -0
  62. package/dist/types/src/operations/index.d.ts.map +1 -0
  63. package/dist/types/src/operations/toggle-presentation.d.ts +10 -0
  64. package/dist/types/src/operations/toggle-presentation.d.ts.map +1 -0
  65. package/dist/types/src/paths.d.ts +3 -0
  66. package/dist/types/src/paths.d.ts.map +1 -0
  67. package/dist/types/src/types/PresenterCapabilities.d.ts.map +1 -1
  68. package/dist/types/src/types/PresenterOperation.d.ts +2 -1
  69. package/dist/types/src/types/PresenterOperation.d.ts.map +1 -1
  70. package/dist/types/src/useExitPresenter.d.ts +6 -1
  71. package/dist/types/src/useExitPresenter.d.ts.map +1 -1
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/dx.config.ts +37 -0
  74. package/package.json +30 -22
  75. package/src/PresenterPlugin.test.ts +1 -1
  76. package/src/PresenterPlugin.tsx +9 -2
  77. package/src/capabilities/app-graph-builder.ts +5 -21
  78. package/src/capabilities/index.ts +6 -0
  79. package/src/capabilities/markdown-extension.ts +45 -0
  80. package/src/capabilities/operation-handler.ts +16 -0
  81. package/src/capabilities/react-surface.tsx +7 -7
  82. package/src/capabilities/settings.ts +2 -2
  83. package/src/components/Presenter/PresentationShell.tsx +96 -0
  84. package/src/components/Presenter/index.ts +1 -0
  85. package/src/components/PresenterSettings/PresenterSettings.tsx +2 -2
  86. package/src/containers/CollectionPresenterArticle/CollectionPresenterArticle.tsx +14 -20
  87. package/src/containers/DocumentPresenterContainer/DocumentPresenterContainer.tsx +4 -2
  88. package/src/meta.ts +2 -30
  89. package/src/operations/index.ts +7 -0
  90. package/src/operations/toggle-presentation.ts +59 -0
  91. package/src/paths.ts +8 -0
  92. package/src/translations.ts +1 -1
  93. package/src/types/PresenterCapabilities.ts +3 -1
  94. package/src/types/PresenterOperation.ts +3 -2
  95. package/src/useExitPresenter.ts +13 -26
  96. package/dist/lib/neutral/CollectionPresenterArticle-DFREOQTG.mjs.map +0 -7
  97. package/dist/lib/neutral/DocumentPresenterContainer-KCDZ2O2C.mjs.map +0 -7
  98. package/dist/lib/neutral/app-graph-builder-DIEDSRPX.mjs.map +0 -7
  99. package/dist/lib/neutral/chunk-PPL2FF6R.mjs +0 -38
  100. package/dist/lib/neutral/chunk-PPL2FF6R.mjs.map +0 -7
  101. package/dist/lib/neutral/chunk-V323QBC3.mjs +0 -41
  102. package/dist/lib/neutral/chunk-V323QBC3.mjs.map +0 -7
  103. package/dist/lib/neutral/chunk-VVALMI52.mjs.map +0 -7
  104. package/dist/lib/neutral/react-surface-SPJGAJIF.mjs.map +0 -7
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useExitPresenter
3
- } from "./chunk-V323QBC3.mjs";
3
+ } from "./chunk-63IF7OXT.mjs";
4
4
  import "./chunk-J5LGTIGS.mjs";
5
5
 
6
6
  // src/containers/CollectionPresenterArticle/CollectionPresenterArticle.tsx
@@ -9,7 +9,7 @@ import { Surface } from "@dxos/app-framework/ui";
9
9
  import { AppSurface } from "@dxos/app-toolkit/ui";
10
10
  import { Obj } from "@dxos/echo";
11
11
  import { Panel } from "@dxos/react-ui";
12
- import { PageNumber, Pager, Layout as PresenterLayout } from "#components";
12
+ import { PageNumber, Pager, PresentationShell, Layout as PresenterLayout } from "#components";
13
13
  import { PresenterContext } from "#types";
14
14
  var CollectionPresenterArticle = ({ role, subject: collection }) => {
15
15
  const [slide, setSlide] = useState(0);
@@ -20,6 +20,8 @@ var CollectionPresenterArticle = ({ role, subject: collection }) => {
20
20
  classNames: "relative"
21
21
  }, /* @__PURE__ */ React.createElement(Panel.Content, {
22
22
  asChild: true
23
+ }, /* @__PURE__ */ React.createElement(PresentationShell, {
24
+ onExit: handleExit
23
25
  }, /* @__PURE__ */ React.createElement(PresenterLayout, {
24
26
  bottomRight: /* @__PURE__ */ React.createElement(PageNumber, {
25
27
  index: slide,
@@ -29,8 +31,7 @@ var CollectionPresenterArticle = ({ role, subject: collection }) => {
29
31
  index: slide,
30
32
  count: collection.objects.length,
31
33
  keys: running,
32
- onChange: setSlide,
33
- onExit: handleExit
34
+ onChange: setSlide
34
35
  })
35
36
  }, /* @__PURE__ */ React.createElement(Surface.Surface, {
36
37
  type: AppSurface.Slide,
@@ -38,9 +39,9 @@ var CollectionPresenterArticle = ({ role, subject: collection }) => {
38
39
  subject: collection.objects[slide],
39
40
  attendableId: Obj.getURI(collection)
40
41
  }
41
- }))));
42
+ })))));
42
43
  };
43
44
  export {
44
45
  CollectionPresenterArticle as default
45
46
  };
46
- //# sourceMappingURL=CollectionPresenterArticle-DFREOQTG.mjs.map
47
+ //# sourceMappingURL=CollectionPresenterArticle-ZRYWBX2H.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/containers/CollectionPresenterArticle/CollectionPresenterArticle.tsx"],
4
+ "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, Layout as PresenterLayout } from '#components';\nimport { PresenterContext } from '#types';\n\nimport { useExitPresenter } from '../../useExitPresenter';\n\nexport type CollectionPresenterArticleProps = AppSurface.ObjectArticleProps<Collection.Collection>;\n\nexport const CollectionPresenterArticle = ({ role, subject: collection }: CollectionPresenterArticleProps) => {\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"],
5
+ "mappings": ";;;;;;AAIA,OAAOA,SAASC,YAAYC,gBAAgB;AAE5C,SAASC,eAAe;AACxB,SAASC,kBAAkB;AAC3B,SAA0BC,WAAW;AACrC,SAASC,aAAa;AAEtB,SAASC,YAAYC,OAAOC,mBAAmBC,UAAUC,uBAAuB;AAChF,SAASC,wBAAwB;AAM1B,IAAMC,6BAA6B,CAAC,EAAEC,MAAMC,SAASC,WAAU,MAAmC;AACvG,QAAM,CAACC,OAAOC,QAAAA,IAAYC,SAAS,CAAA;AACnC,QAAM,EAAEC,QAAO,IAAKC,WAAWC,gBAAAA;AAC/B,QAAMC,aAAaC,iBAAiBR,UAAAA;AAEpC,SACE,sBAAA,cAACS,MAAMC,MAAI;IAACZ;IAAYa,YAAW;KACjC,sBAAA,cAACF,MAAMG,SAAO;IAACC,SAAAA;KACb,sBAAA,cAACC,mBAAAA;IAAkBC,QAAQR;KACzB,sBAAA,cAACS,iBAAAA;IACCC,aAAa,sBAAA,cAACC,YAAAA;MAAWC,OAAOlB;MAAOmB,OAAOpB,WAAWqB,QAAQC;;IACjEC,YAAY,sBAAA,cAACC,OAAAA;MAAML,OAAOlB;MAAOmB,OAAOpB,WAAWqB,QAAQC;MAAQG,MAAMrB;MAASsB,UAAUxB;;KAE5F,sBAAA,cAACyB,QAAQA,SAAO;IACdC,MAAMC,WAAWC;IACjBC,MAAM;MACJhC,SAASC,WAAWqB,QAAQpB,KAAAA;MAC5B+B,cAAcC,IAAIC,OAAOlC,UAAAA;IAC3B;;AAOd;",
6
+ "names": ["React", "useContext", "useState", "Surface", "AppSurface", "Obj", "Panel", "PageNumber", "Pager", "PresentationShell", "Layout", "PresenterLayout", "PresenterContext", "CollectionPresenterArticle", "role", "subject", "collection", "slide", "setSlide", "useState", "running", "useContext", "PresenterContext", "handleExit", "useExitPresenter", "Panel", "Root", "classNames", "Content", "asChild", "PresentationShell", "onExit", "PresenterLayout", "bottomRight", "PageNumber", "index", "count", "objects", "length", "bottomLeft", "Pager", "keys", "onChange", "Surface", "type", "AppSurface", "Slide", "data", "attendableId", "Obj", "getURI"]
7
+ }
@@ -1,24 +1,25 @@
1
1
  import {
2
2
  useExitPresenter
3
- } from "./chunk-V323QBC3.mjs";
3
+ } from "./chunk-63IF7OXT.mjs";
4
4
  import "./chunk-J5LGTIGS.mjs";
5
5
 
6
6
  // src/containers/DocumentPresenterContainer/DocumentPresenterContainer.tsx
7
7
  import React from "react";
8
8
  import { Panel } from "@dxos/react-ui";
9
- import { RevealPlayer } from "#components";
9
+ import { PresentationShell, RevealPlayer } from "#components";
10
10
  var DocumentPresenterContainer = ({ document }) => {
11
11
  const handleExit = useExitPresenter(document);
12
12
  return /* @__PURE__ */ React.createElement(Panel.Root, {
13
13
  classNames: "relative"
14
14
  }, /* @__PURE__ */ React.createElement(Panel.Content, {
15
15
  asChild: true
16
- }, /* @__PURE__ */ React.createElement(RevealPlayer, {
17
- content: document.content.target?.content ?? "",
16
+ }, /* @__PURE__ */ React.createElement(PresentationShell, {
18
17
  onExit: handleExit
19
- })));
18
+ }, /* @__PURE__ */ React.createElement(RevealPlayer, {
19
+ content: document.content.target?.content ?? ""
20
+ }))));
20
21
  };
21
22
  export {
22
23
  DocumentPresenterContainer as default
23
24
  };
24
- //# sourceMappingURL=DocumentPresenterContainer-KCDZ2O2C.mjs.map
25
+ //# sourceMappingURL=DocumentPresenterContainer-5QF4P736.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/containers/DocumentPresenterContainer/DocumentPresenterContainer.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { type FC } from 'react';\n\nimport { type Markdown } from '@dxos/plugin-markdown';\nimport { Panel } from '@dxos/react-ui';\n\nimport { PresentationShell, RevealPlayer } from '#components';\n\nimport { useExitPresenter } from '../../useExitPresenter';\n\nexport const DocumentPresenterContainer: FC<{ document: Markdown.Document }> = ({ document }) => {\n const handleExit = useExitPresenter(document);\n\n return (\n <Panel.Root classNames='relative'>\n <Panel.Content asChild>\n <PresentationShell onExit={handleExit}>\n <RevealPlayer content={document.content.target?.content ?? ''} />\n </PresentationShell>\n </Panel.Content>\n </Panel.Root>\n );\n};\n"],
5
+ "mappings": ";;;;;;AAIA,OAAOA,WAAwB;AAG/B,SAASC,aAAa;AAEtB,SAASC,mBAAmBC,oBAAoB;AAIzC,IAAMC,6BAAkE,CAAC,EAAEC,SAAQ,MAAE;AAC1F,QAAMC,aAAaC,iBAAiBF,QAAAA;AAEpC,SACE,sBAAA,cAACG,MAAMC,MAAI;IAACC,YAAW;KACrB,sBAAA,cAACF,MAAMG,SAAO;IAACC,SAAAA;KACb,sBAAA,cAACC,mBAAAA;IAAkBC,QAAQR;KACzB,sBAAA,cAACS,cAAAA;IAAaC,SAASX,SAASW,QAAQC,QAAQD,WAAW;;AAKrE;",
6
+ "names": ["React", "Panel", "PresentationShell", "RevealPlayer", "DocumentPresenterContainer", "document", "handleExit", "useExitPresenter", "Panel", "Root", "classNames", "Content", "asChild", "PresentationShell", "onExit", "RevealPlayer", "content", "target"]
7
+ }
@@ -3,25 +3,32 @@ import "./chunk-J5LGTIGS.mjs";
3
3
  // src/PresenterPlugin.tsx
4
4
  import { Plugin } from "@dxos/app-framework";
5
5
  import { AppPlugin } from "@dxos/app-toolkit";
6
- import { AppGraphBuilder, PresenterSettings, ReactSurface } from "#capabilities";
6
+ import { MarkdownEvents } from "@dxos/plugin-markdown";
7
+ import { AppGraphBuilder, MarkdownExtension, OperationHandler, PresenterSettings, ReactSurface } from "#capabilities";
7
8
  import { meta } from "#meta";
8
9
  import { translations } from "#translations";
9
10
 
10
- // raw-loader:/__w/dxos/dxos/packages/plugins/plugin-presenter/PLUGIN.mdl?raw
11
+ // raw-loader:/__w/dxos/dxos/packages/plugins/plugin-presenter/PLUGIN.mdl
11
12
  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 \u2014 markdown documents and collections \u2014 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 DocumentPresenterContainer\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 RevealPlayer \u2502\n \u2502 (full-screen slide canvas) \u2502\n \u2502 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent CollectionPresenterArticle\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. MarkdownSlide 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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 Surface (slide N) \u2502 \u2190 AppSurface.Slide surface\n \u2502 \u2502\n \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 [Pager] \u2502 [PageNum] \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent MarkdownSlide\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 Panel \u2502\n \u2502 \u2514\u2500 Slide (markdown) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\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 in solo-fullscreen layout via the Deck plugin.\n If the deck is not already in fullscreen, switches to solo--fullscreen before opening.\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:solo-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: DocumentPresenterContainer 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: CollectionPresenterArticle 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 - DocumentPresenterContainer 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: DocumentPresenterContainer 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: DocumentPresenterContainer 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: CollectionPresenterArticle mounts\n then:\n - slide 0 shows MarkdownSlide for collection.objects[0]\n - Pager shows count = 2\n```\n\n```mdl\ntest T-5: Collection slide advance\n given: CollectionPresenterArticle 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 \u2014 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';
12
13
 
13
14
  // src/PresenterPlugin.tsx
14
15
  var PresenterPlugin = Plugin.define(meta).pipe(AppPlugin.addAppGraphModule({
15
16
  activate: AppGraphBuilder
17
+ }), AppPlugin.addOperationHandlerModule({
18
+ activate: OperationHandler
16
19
  }), AppPlugin.addSettingsModule({
17
20
  activate: PresenterSettings
18
21
  }), AppPlugin.addSurfaceModule({
19
22
  activate: ReactSurface
23
+ }), Plugin.addModule({
24
+ id: `${meta.profile.key}/markdown`,
25
+ activatesOn: MarkdownEvents.SetupExtensions,
26
+ activate: MarkdownExtension
20
27
  }), AppPlugin.addTranslationsModule({
21
28
  translations
22
29
  }), AppPlugin.addPluginAssetModule({
23
30
  asset: {
24
- pluginId: meta.id,
31
+ pluginId: meta.profile.key,
25
32
  path: "PLUGIN.mdl",
26
33
  content: PLUGIN_default,
27
34
  mimeType: "application/x-mdl"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../src/PresenterPlugin.tsx", "raw-loader:/__w/dxos/dxos/packages/plugins/plugin-presenter/PLUGIN.mdl?raw"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\n\nimport { AppGraphBuilder, PresenterSettings, ReactSurface } from '#capabilities';\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\n// TODO(burdon): Only scale markdown content.\n// TODO(burdon): Map stack content; Slide content type (e.g., markdown, sketch, IPFS image, table, etc.)\n\nexport const PresenterPlugin = Plugin.define(meta).pipe(\n AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),\n AppPlugin.addSettingsModule({ activate: PresenterSettings }),\n AppPlugin.addSurfaceModule({ activate: ReactSurface }),\n AppPlugin.addTranslationsModule({ translations }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.id, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nexport default PresenterPlugin;\n", "---\nid: org.dxos.plugin.presenter\nname: PresenterPlugin\nversion: 0.1.0\n---\n\nA presentation plugin for DXOS Composer that turns existing workspace objects \u2014 markdown documents and collections \u2014 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 DocumentPresenterContainer\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 RevealPlayer \u2502\n \u2502 (full-screen slide canvas) \u2502\n \u2502 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent CollectionPresenterArticle\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. MarkdownSlide 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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 Surface (slide N) \u2502 \u2190 AppSurface.Slide surface\n \u2502 \u2502\n \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 [Pager] \u2502 [PageNum] \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent MarkdownSlide\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 Panel \u2502\n \u2502 \u2514\u2500 Slide (markdown) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\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 in solo-fullscreen layout via the Deck plugin.\n If the deck is not already in fullscreen, switches to solo--fullscreen before opening.\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:solo-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: DocumentPresenterContainer 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: CollectionPresenterArticle 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 - DocumentPresenterContainer 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: DocumentPresenterContainer 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: DocumentPresenterContainer 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: CollectionPresenterArticle mounts\n then:\n - slide 0 shows MarkdownSlide for collection.objects[0]\n - Pager shows count = 2\n```\n\n```mdl\ntest T-5: Collection slide advance\n given: CollectionPresenterArticle 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 \u2014 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"],
5
- "mappings": ";;;AAIA,SAASA,cAAc;AACvB,SAASC,iBAAiB;AAE1B,SAASC,iBAAiBC,mBAAmBC,oBAAoB;AACjE,SAASC,YAAY;AACrB,SAASC,oBAAoB;;;ACT7B;;;ADiBO,IAAMC,kBAAkBC,OAAOC,OAAOC,IAAAA,EAAMC,KACjDC,UAAUC,kBAAkB;EAAEC,UAAUC;AAAgB,CAAA,GACxDH,UAAUI,kBAAkB;EAAEF,UAAUG;AAAkB,CAAA,GAC1DL,UAAUM,iBAAiB;EAAEJ,UAAUK;AAAa,CAAA,GACpDP,UAAUQ,sBAAsB;EAAEC;AAAa,CAAA,GAC/CT,UAAUU,qBAAqB;EAC7BC,OAAO;IAAEC,UAAUd,KAAKe;IAAIC,MAAM;IAAcC,SAASC;IAAYC,UAAU;EAAoB;AACrG,CAAA,GACArB,OAAOsB,IAAI;AAGb,IAAA,0BAAevB;",
6
- "names": ["Plugin", "AppPlugin", "AppGraphBuilder", "PresenterSettings", "ReactSurface", "meta", "translations", "PresenterPlugin", "Plugin", "define", "meta", "pipe", "AppPlugin", "addAppGraphModule", "activate", "AppGraphBuilder", "addSettingsModule", "PresenterSettings", "addSurfaceModule", "ReactSurface", "addTranslationsModule", "translations", "addPluginAssetModule", "asset", "pluginId", "id", "path", "content", "pluginSpec", "mimeType", "make"]
3
+ "sources": ["../../../src/PresenterPlugin.tsx", "raw-loader:/__w/dxos/dxos/packages/plugins/plugin-presenter/PLUGIN.mdl"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { MarkdownEvents } from '@dxos/plugin-markdown';\n\nimport { AppGraphBuilder, MarkdownExtension, OperationHandler, PresenterSettings, ReactSurface } from '#capabilities';\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\n// TODO(burdon): Only scale markdown content.\n// TODO(burdon): Map stack content; Slide content type (e.g., markdown, sketch, IPFS image, table, etc.)\n\nexport const PresenterPlugin = Plugin.define(meta).pipe(\n AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),\n AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),\n AppPlugin.addSettingsModule({ activate: PresenterSettings }),\n AppPlugin.addSurfaceModule({ activate: ReactSurface }),\n Plugin.addModule({\n id: `${meta.profile.key}/markdown`,\n activatesOn: MarkdownEvents.SetupExtensions,\n activate: MarkdownExtension,\n }),\n AppPlugin.addTranslationsModule({ translations }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nexport default PresenterPlugin;\n", "---\nid: org.dxos.plugin.presenter\nname: PresenterPlugin\nversion: 0.1.0\n---\n\nA presentation plugin for DXOS Composer that turns existing workspace objects \u2014 markdown documents and collections \u2014 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 DocumentPresenterContainer\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 RevealPlayer \u2502\n \u2502 (full-screen slide canvas) \u2502\n \u2502 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent CollectionPresenterArticle\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. MarkdownSlide 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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 \u2502\n \u2502 Surface (slide N) \u2502 \u2190 AppSurface.Slide surface\n \u2502 \u2502\n \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n \u2502 [Pager] \u2502 [PageNum] \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n```mdl\ncomponent MarkdownSlide\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 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n \u2502 Panel \u2502\n \u2502 \u2514\u2500 Slide (markdown) \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\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 in solo-fullscreen layout via the Deck plugin.\n If the deck is not already in fullscreen, switches to solo--fullscreen before opening.\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:solo-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: DocumentPresenterContainer 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: CollectionPresenterArticle 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 - DocumentPresenterContainer 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: DocumentPresenterContainer 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: DocumentPresenterContainer 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: CollectionPresenterArticle mounts\n then:\n - slide 0 shows MarkdownSlide for collection.objects[0]\n - Pager shows count = 2\n```\n\n```mdl\ntest T-5: Collection slide advance\n given: CollectionPresenterArticle 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 \u2014 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"],
5
+ "mappings": ";;;AAIA,SAASA,cAAc;AACvB,SAASC,iBAAiB;AAC1B,SAASC,sBAAsB;AAE/B,SAASC,iBAAiBC,mBAAmBC,kBAAkBC,mBAAmBC,oBAAoB;AACtG,SAASC,YAAY;AACrB,SAASC,oBAAoB;;;ACV7B;;;ADkBO,IAAMC,kBAAkBC,OAAOC,OAAOC,IAAAA,EAAMC,KACjDC,UAAUC,kBAAkB;EAAEC,UAAUC;AAAgB,CAAA,GACxDH,UAAUI,0BAA0B;EAAEF,UAAUG;AAAiB,CAAA,GACjEL,UAAUM,kBAAkB;EAAEJ,UAAUK;AAAkB,CAAA,GAC1DP,UAAUQ,iBAAiB;EAAEN,UAAUO;AAAa,CAAA,GACpDb,OAAOc,UAAU;EACfC,IAAI,GAAGb,KAAKc,QAAQC,GAAG;EACvBC,aAAaC,eAAeC;EAC5Bd,UAAUe;AACZ,CAAA,GACAjB,UAAUkB,sBAAsB;EAAEC;AAAa,CAAA,GAC/CnB,UAAUoB,qBAAqB;EAC7BC,OAAO;IAAEC,UAAUxB,KAAKc,QAAQC;IAAKU,MAAM;IAAcC,SAASC;IAAYC,UAAU;EAAoB;AAC9G,CAAA,GACA9B,OAAO+B,IAAI;AAGb,IAAA,0BAAehC;",
6
+ "names": ["Plugin", "AppPlugin", "MarkdownEvents", "AppGraphBuilder", "MarkdownExtension", "OperationHandler", "PresenterSettings", "ReactSurface", "meta", "translations", "PresenterPlugin", "Plugin", "define", "meta", "pipe", "AppPlugin", "addAppGraphModule", "activate", "AppGraphBuilder", "addOperationHandlerModule", "OperationHandler", "addSettingsModule", "PresenterSettings", "addSurfaceModule", "ReactSurface", "addModule", "id", "profile", "key", "activatesOn", "MarkdownEvents", "SetupExtensions", "MarkdownExtension", "addTranslationsModule", "translations", "addPluginAssetModule", "asset", "pluginId", "path", "content", "pluginSpec", "mimeType", "make"]
7
7
  }
@@ -7,10 +7,10 @@ import { Settings as SettingsForm } from "@dxos/react-ui-form";
7
7
  import { meta } from "#meta";
8
8
  import { Settings } from "#types";
9
9
  var PresenterSettings = ({ settings, onSettingsChange }) => {
10
- const { t } = useTranslation(meta.id);
10
+ const { t } = useTranslation(meta.profile.key);
11
11
  return /* @__PURE__ */ React.createElement(SettingsForm.Viewport, null, /* @__PURE__ */ React.createElement(SettingsForm.Section, {
12
12
  title: t("settings.title", {
13
- ns: meta.id
13
+ ns: meta.profile.key
14
14
  })
15
15
  }, /* @__PURE__ */ React.createElement(SettingsForm.FieldSet, {
16
16
  readonly: !onSettingsChange,
@@ -22,4 +22,4 @@ var PresenterSettings = ({ settings, onSettingsChange }) => {
22
22
  export {
23
23
  PresenterSettings as default
24
24
  };
25
- //# sourceMappingURL=PresenterSettings-2G4XD4QY.mjs.map
25
+ //# sourceMappingURL=PresenterSettings-4YFP4K5G.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/PresenterSettings/PresenterSettings.tsx"],
4
- "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { useTranslation } from '@dxos/react-ui';\nimport { Settings as SettingsForm } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { Settings } from '#types';\n\nexport type PresenterSettingsProps = AppSurface.SettingsArticleProps<Settings.Settings>;\n\nexport const PresenterSettings = ({ settings, onSettingsChange }: PresenterSettingsProps) => {\n const { t } = useTranslation(meta.id);\n\n return (\n <SettingsForm.Viewport>\n <SettingsForm.Section title={t('settings.title', { ns: meta.id })}>\n <SettingsForm.FieldSet\n readonly={!onSettingsChange}\n schema={Settings.Settings}\n values={settings}\n onValuesChanged={(values) => onSettingsChange?.(() => values)}\n />\n </SettingsForm.Section>\n </SettingsForm.Viewport>\n );\n};\n"],
5
- "mappings": ";;;AAIA,OAAOA,WAAW;AAGlB,SAASC,sBAAsB;AAC/B,SAASC,YAAYC,oBAAoB;AAEzC,SAASC,YAAY;AACrB,SAASF,gBAAgB;AAIlB,IAAMG,oBAAoB,CAAC,EAAEC,UAAUC,iBAAgB,MAA0B;AACtF,QAAM,EAAEC,EAAC,IAAKP,eAAeG,KAAKK,EAAE;AAEpC,SACE,sBAAA,cAACN,aAAaO,UAAQ,MACpB,sBAAA,cAACP,aAAaQ,SAAO;IAACC,OAAOJ,EAAE,kBAAkB;MAAEK,IAAIT,KAAKK;IAAG,CAAA;KAC7D,sBAAA,cAACN,aAAaW,UAAQ;IACpBC,UAAU,CAACR;IACXS,QAAQd,SAASA;IACjBe,QAAQX;IACRY,iBAAiB,CAACD,WAAWV,mBAAmB,MAAMU,MAAAA;;AAKhE;",
6
- "names": ["React", "useTranslation", "Settings", "SettingsForm", "meta", "PresenterSettings", "settings", "onSettingsChange", "t", "id", "Viewport", "Section", "title", "ns", "FieldSet", "readonly", "schema", "values", "onValuesChanged"]
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport React from 'react';\n\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { useTranslation } from '@dxos/react-ui';\nimport { Settings as SettingsForm } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { Settings } from '#types';\n\nexport type PresenterSettingsProps = AppSurface.SettingsArticleProps<Settings.Settings>;\n\nexport const PresenterSettings = ({ settings, onSettingsChange }: PresenterSettingsProps) => {\n const { t } = useTranslation(meta.profile.key);\n\n return (\n <SettingsForm.Viewport>\n <SettingsForm.Section title={t('settings.title', { ns: meta.profile.key })}>\n <SettingsForm.FieldSet\n readonly={!onSettingsChange}\n schema={Settings.Settings}\n values={settings}\n onValuesChanged={(values) => onSettingsChange?.(() => values)}\n />\n </SettingsForm.Section>\n </SettingsForm.Viewport>\n );\n};\n"],
5
+ "mappings": ";;;AAIA,OAAOA,WAAW;AAGlB,SAASC,sBAAsB;AAC/B,SAASC,YAAYC,oBAAoB;AAEzC,SAASC,YAAY;AACrB,SAASF,gBAAgB;AAIlB,IAAMG,oBAAoB,CAAC,EAAEC,UAAUC,iBAAgB,MAA0B;AACtF,QAAM,EAAEC,EAAC,IAAKP,eAAeG,KAAKK,QAAQC,GAAG;AAE7C,SACE,sBAAA,cAACP,aAAaQ,UAAQ,MACpB,sBAAA,cAACR,aAAaS,SAAO;IAACC,OAAOL,EAAE,kBAAkB;MAAEM,IAAIV,KAAKK,QAAQC;IAAI,CAAA;KACtE,sBAAA,cAACP,aAAaY,UAAQ;IACpBC,UAAU,CAACT;IACXU,QAAQf,SAASA;IACjBgB,QAAQZ;IACRa,iBAAiB,CAACD,WAAWX,mBAAmB,MAAMW,MAAAA;;AAKhE;",
6
+ "names": ["React", "useTranslation", "Settings", "SettingsForm", "meta", "PresenterSettings", "settings", "onSettingsChange", "t", "profile", "key", "Viewport", "Section", "title", "ns", "FieldSet", "readonly", "schema", "values", "onValuesChanged"]
7
7
  }
@@ -3,11 +3,10 @@ import "./chunk-J5LGTIGS.mjs";
3
3
  // src/capabilities/app-graph-builder.ts
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as Option from "effect/Option";
6
- import { Capabilities, Capability } from "@dxos/app-framework";
7
- import { AppCapabilities, AppNode, LayoutOperation, getObjectPathFromObject, getSpacePath } from "@dxos/app-toolkit";
6
+ import { Capability } from "@dxos/app-framework";
7
+ import { AppCapabilities, AppNode } from "@dxos/app-toolkit";
8
8
  import { Operation } from "@dxos/compute";
9
9
  import { Collection, Obj } from "@dxos/echo";
10
- import { DeckCapabilities, DeckOperation } from "@dxos/plugin-deck";
11
10
  import { GraphBuilder, NodeMatcher } from "@dxos/plugin-graph";
12
11
  import { Markdown } from "@dxos/plugin-markdown";
13
12
  import { linkedSegment } from "@dxos/react-ui-attention";
@@ -34,7 +33,7 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
34
33
  label: "Presenter",
35
34
  icon: "ph--presentation--regular",
36
35
  data: {
37
- type: meta.id,
36
+ type: meta.profile.key,
38
37
  object
39
38
  }
40
39
  })
@@ -48,34 +47,19 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
48
47
  if (!isPresentable || !db) {
49
48
  return Effect.succeed([]);
50
49
  }
51
- const objectPath = getObjectPathFromObject(object);
52
50
  return Effect.succeed([
53
51
  {
54
52
  id: PresenterOperation.TogglePresentation.meta.key,
55
- // TODO(burdon): Allow function so can generate state when activated.
56
- // So can set explicit fullscreen state coordinated with current presenter state.
57
53
  data: Effect.fnUntraced(function* () {
58
- const deckState = yield* Capabilities.getAtomValue(DeckCapabilities.State);
59
- const deck = deckState.decks[deckState.activeDeck];
60
- const presenterId = `${objectPath}/${linkedSegment("presenter")}`;
61
- if (!deck?.fullscreen) {
62
- yield* Operation.invoke(DeckOperation.Adjust, {
63
- type: "solo--fullscreen",
64
- id: presenterId
65
- });
66
- }
67
- yield* Operation.invoke(LayoutOperation.Open, {
68
- subject: [
69
- presenterId
70
- ],
71
- workspace: getSpacePath(db.spaceId)
54
+ yield* Operation.invoke(PresenterOperation.TogglePresentation, {
55
+ object
72
56
  });
73
57
  }),
74
58
  properties: {
75
59
  label: [
76
60
  "toggle-presentation.label",
77
61
  {
78
- ns: meta.id
62
+ ns: meta.profile.key
79
63
  }
80
64
  ],
81
65
  icon: "ph--presentation--regular",
@@ -94,4 +78,4 @@ var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function
94
78
  export {
95
79
  app_graph_builder_default as default
96
80
  };
97
- //# sourceMappingURL=app-graph-builder-DIEDSRPX.mjs.map
81
+ //# sourceMappingURL=app-graph-builder-JMQVBFG2.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/app-graph-builder.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Option from 'effect/Option';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities, AppNode } from '@dxos/app-toolkit';\nimport { Operation } from '@dxos/compute';\nimport { Collection, Obj } from '@dxos/echo';\nimport { GraphBuilder, type Node, NodeMatcher } from '@dxos/plugin-graph';\nimport { Markdown } from '@dxos/plugin-markdown';\nimport { linkedSegment } from '@dxos/react-ui-attention';\n\nimport { meta } from '#meta';\nimport { PresenterOperation } from '#types';\nimport { PresenterCapabilities } from '#types';\n\n/** Match nodes that can be presented (Collection or Document). */\nconst whenPresentable = (node: Node.Node) =>\n Option.orElse(NodeMatcher.whenEchoType(Collection.Collection)(node), () =>\n NodeMatcher.whenEchoType(Markdown.Document)(node),\n );\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const capabilities = yield* Capability.Service;\n\n const extensions = yield* GraphBuilder.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 const settingsAtom = capabilities.get(PresenterCapabilities.Settings);\n const settings = get(settingsAtom);\n const isPresentable = settings?.presentCollections\n ? Obj.instanceOf(Collection.Collection, object) || Obj.instanceOf(Markdown.Document, object)\n : Obj.instanceOf(Markdown.Document, object);\n if (!isPresentable) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n AppNode.makeCompanion({\n id: linkedSegment('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 settingsAtom = capabilities.get(PresenterCapabilities.Settings);\n const settings = get(settingsAtom);\n const isPresentable = settings?.presentCollections\n ? Obj.instanceOf(Collection.Collection, object) || Obj.instanceOf(Markdown.Document, object)\n : Obj.instanceOf(Markdown.Document, object);\n const db = Obj.getDatabase(object);\n if (!isPresentable || !db) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n {\n id: PresenterOperation.TogglePresentation.meta.key,\n data: Effect.fnUntraced(function* () {\n yield* Operation.invoke(PresenterOperation.TogglePresentation, { object });\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.contributes(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],
5
+ "mappings": ";;;AAIA,YAAYA,YAAY;AACxB,YAAYC,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,iBAAiBC,eAAe;AACzC,SAASC,iBAAiB;AAC1B,SAASC,YAAYC,WAAW;AAChC,SAASC,cAAyBC,mBAAmB;AACrD,SAASC,gBAAgB;AACzB,SAASC,qBAAqB;AAE9B,SAASC,YAAY;AACrB,SAASC,0BAA0B;AACnC,SAASC,6BAA6B;AAGtC,IAAMC,kBAAkB,CAACC,SAChBC,cAAOR,YAAYS,aAAaZ,WAAWA,UAAU,EAAEU,IAAAA,GAAO,MACnEP,YAAYS,aAAaR,SAASS,QAAQ,EAAEH,IAAAA,CAAAA;AAGhD,IAAA,4BAAed,WAAWkB,WACjBC,kBAAW,aAAA;AAChB,QAAMC,eAAe,OAAOpB,WAAWqB;AAEvC,QAAMC,aAAa,OAAOhB,aAAaiB,gBAAgB;IACrDC,IAAI;;IAEJC,OAAOZ;IACPa,WAAW,CAACC,QAAQC,QAAAA;AAClB,YAAMC,eAAeT,aAAaQ,IAAIhB,sBAAsBkB,QAAQ;AACpE,YAAMC,WAAWH,IAAIC,YAAAA;AACrB,YAAMG,gBAAgBD,UAAUE,qBAC5B5B,IAAI6B,WAAW9B,WAAWA,YAAYuB,MAAAA,KAAWtB,IAAI6B,WAAW1B,SAASS,UAAUU,MAAAA,IACnFtB,IAAI6B,WAAW1B,SAASS,UAAUU,MAAAA;AACtC,UAAI,CAACK,eAAe;AAClB,eAAcG,eAAQ,CAAA,CAAE;MAC1B;AAEA,aAAcA,eAAQ;QACpBjC,QAAQkC,cAAc;UACpBZ,IAAIf,cAAc,WAAA;UAClB4B,OAAO;UACPC,MAAM;UACNC,MAAM;YAAEC,MAAM9B,KAAK+B,QAAQC;YAAKf;UAAO;QACzC,CAAA;OACD;IACH;IACAgB,SAAS,CAAChB,QAAQC,QAAAA;AAChB,YAAMC,eAAeT,aAAaQ,IAAIhB,sBAAsBkB,QAAQ;AACpE,YAAMC,WAAWH,IAAIC,YAAAA;AACrB,YAAMG,gBAAgBD,UAAUE,qBAC5B5B,IAAI6B,WAAW9B,WAAWA,YAAYuB,MAAAA,KAAWtB,IAAI6B,WAAW1B,SAASS,UAAUU,MAAAA,IACnFtB,IAAI6B,WAAW1B,SAASS,UAAUU,MAAAA;AACtC,YAAMiB,KAAKvC,IAAIwC,YAAYlB,MAAAA;AAC3B,UAAI,CAACK,iBAAiB,CAACY,IAAI;AACzB,eAAcT,eAAQ,CAAA,CAAE;MAC1B;AAEA,aAAcA,eAAQ;QACpB;UACEX,IAAIb,mBAAmBmC,mBAAmBpC,KAAKgC;UAC/CH,MAAapB,kBAAW,aAAA;AACtB,mBAAOhB,UAAU4C,OAAOpC,mBAAmBmC,oBAAoB;cAAEnB;YAAO,CAAA;UAC1E,CAAA;UACAqB,YAAY;YACVX,OAAO;cAAC;cAA6B;gBAAEY,IAAIvC,KAAK+B,QAAQC;cAAI;;YAC5DJ,MAAM;YACNY,aAAa;YACbC,YAAY;cACVC,OAAO;cACPC,SAAS;YACX;UACF;QACF;OACD;IACH;EACF,CAAA;AAEA,SAAOrD,WAAWsD,YAAYrD,gBAAgBsD,iBAAiBjC,UAAAA;AACjE,CAAA,CAAA;",
6
+ "names": ["Effect", "Option", "Capability", "AppCapabilities", "AppNode", "Operation", "Collection", "Obj", "GraphBuilder", "NodeMatcher", "Markdown", "linkedSegment", "meta", "PresenterOperation", "PresenterCapabilities", "whenPresentable", "node", "orElse", "whenEchoType", "Document", "makeModule", "fnUntraced", "capabilities", "Service", "extensions", "createExtension", "id", "match", "connector", "object", "get", "settingsAtom", "Settings", "settings", "isPresentable", "presentCollections", "instanceOf", "succeed", "makeCompanion", "label", "icon", "data", "type", "profile", "key", "actions", "db", "getDatabase", "TogglePresentation", "invoke", "properties", "ns", "disposition", "keyBinding", "macos", "windows", "contributes", "AppGraphBuilder"]
7
+ }
@@ -2,11 +2,15 @@ import "../chunk-J5LGTIGS.mjs";
2
2
 
3
3
  // src/capabilities/index.ts
4
4
  import { Capability } from "@dxos/app-framework";
5
- var AppGraphBuilder = Capability.lazy("AppGraphBuilder", () => import("../app-graph-builder-DIEDSRPX.mjs"));
6
- var ReactSurface = Capability.lazy("ReactSurface", () => import("../react-surface-SPJGAJIF.mjs"));
7
- var PresenterSettings = Capability.lazy("PresenterSettings", () => import("../settings-R6LRDAAK.mjs"));
5
+ var AppGraphBuilder = Capability.lazy("AppGraphBuilder", () => import("../app-graph-builder-JMQVBFG2.mjs"));
6
+ var MarkdownExtension = Capability.lazy("MarkdownExtension", () => import("../markdown-extension-HGLRVZDF.mjs"));
7
+ var OperationHandler = Capability.lazy("OperationHandler", () => import("../operation-handler-3ZESW5AK.mjs"));
8
+ var ReactSurface = Capability.lazy("ReactSurface", () => import("../react-surface-YGBE3TDK.mjs"));
9
+ var PresenterSettings = Capability.lazy("PresenterSettings", () => import("../settings-DBV7N5HT.mjs"));
8
10
  export {
9
11
  AppGraphBuilder,
12
+ MarkdownExtension,
13
+ OperationHandler,
10
14
  PresenterSettings,
11
15
  ReactSurface
12
16
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/capabilities/index.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\n\nexport const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\nexport const PresenterSettings = Capability.lazy('PresenterSettings', () => import('./settings'));\n"],
5
- "mappings": ";;;AAIA,SAASA,kBAAkB;AAEpB,IAAMC,kBAAkBD,WAAWE,KAAK,mBAAmB,MAAM,OAAO,mCAAA,CAAA;AACxE,IAAMC,eAAeH,WAAWE,KAAK,gBAAgB,MAAM,OAAO,+BAAA,CAAA;AAClE,IAAME,oBAAoBJ,WAAWE,KAAK,qBAAqB,MAAM,OAAO,0BAAA,CAAA;",
6
- "names": ["Capability", "AppGraphBuilder", "lazy", "ReactSurface", "PresenterSettings"]
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\nimport type { OperationHandlerSet } from '@dxos/compute';\n\nexport const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));\nexport const MarkdownExtension = Capability.lazy('MarkdownExtension', () => import('./markdown-extension'));\nexport const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(\n 'OperationHandler',\n () => import('./operation-handler'),\n);\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\nexport const PresenterSettings = Capability.lazy('PresenterSettings', () => import('./settings'));\n"],
5
+ "mappings": ";;;AAIA,SAASA,kBAAkB;AAGpB,IAAMC,kBAAkBD,WAAWE,KAAK,mBAAmB,MAAM,OAAO,mCAAA,CAAA;AACxE,IAAMC,oBAAoBH,WAAWE,KAAK,qBAAqB,MAAM,OAAO,oCAAA,CAAA;AAC5E,IAAME,mBAAmBJ,WAAWE,KACzC,oBACA,MAAM,OAAO,mCAAA,CAAA;AAER,IAAMG,eAAeL,WAAWE,KAAK,gBAAgB,MAAM,OAAO,+BAAA,CAAA;AAClE,IAAMI,oBAAoBN,WAAWE,KAAK,qBAAqB,MAAM,OAAO,0BAAA,CAAA;",
6
+ "names": ["Capability", "AppGraphBuilder", "lazy", "MarkdownExtension", "OperationHandler", "ReactSurface", "PresenterSettings"]
7
7
  }
@@ -0,0 +1,19 @@
1
+ // src/useExitPresenter.ts
2
+ import { useCallback } from "react";
3
+ import { useOperationInvoker } from "@dxos/app-framework/ui";
4
+ import { PresenterOperation } from "#types";
5
+ var useExitPresenter = (object) => {
6
+ const { invokePromise } = useOperationInvoker();
7
+ return useCallback(() => invokePromise(PresenterOperation.TogglePresentation, {
8
+ object,
9
+ state: false
10
+ }), [
11
+ invokePromise,
12
+ object
13
+ ]);
14
+ };
15
+
16
+ export {
17
+ useExitPresenter
18
+ };
19
+ //# sourceMappingURL=chunk-63IF7OXT.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/useExitPresenter.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport { useCallback } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\n\nimport { PresenterOperation } from '#types';\n\n/**\n * Exits presentation for the given object. Delegates to the toggle operation so the\n * fullscreen-revert and re-open run sequentially in a single handler — invoking them\n * separately races, leaving the deck stuck in fullscreen.\n */\nexport const useExitPresenter = (object: any) => {\n const { invokePromise } = useOperationInvoker();\n\n return useCallback(\n () => invokePromise(PresenterOperation.TogglePresentation, { object, state: false }),\n [invokePromise, object],\n );\n};\n"],
5
+ "mappings": ";AAIA,SAASA,mBAAmB;AAE5B,SAASC,2BAA2B;AAEpC,SAASC,0BAA0B;AAO5B,IAAMC,mBAAmB,CAACC,WAAAA;AAC/B,QAAM,EAAEC,cAAa,IAAKJ,oBAAAA;AAE1B,SAAOD,YACL,MAAMK,cAAcH,mBAAmBI,oBAAoB;IAAEF;IAAQG,OAAO;EAAM,CAAA,GAClF;IAACF;IAAeD;GAAO;AAE3B;",
6
+ "names": ["useCallback", "useOperationInvoker", "PresenterOperation", "useExitPresenter", "object", "invokePromise", "TogglePresentation", "state"]
7
+ }
@@ -12,7 +12,7 @@ __export(PresenterCapabilities_exports, {
12
12
  });
13
13
  import { Capability } from "@dxos/app-framework";
14
14
  import { meta } from "#meta";
15
- var Settings = Capability.make(`${meta.id}.capability.settings`);
15
+ var Settings = Capability.make(`${meta.profile.key}.capability.settings`);
16
16
 
17
17
  // src/types/PresenterOperation.ts
18
18
  var PresenterOperation_exports = {};
@@ -20,17 +20,21 @@ __export(PresenterOperation_exports, {
20
20
  TogglePresentation: () => TogglePresentation
21
21
  });
22
22
  import * as Schema from "effect/Schema";
23
+ import { Capability as Capability2 } from "@dxos/app-framework";
23
24
  import { Operation } from "@dxos/compute";
24
25
  import { Collection, Type, DXN } from "@dxos/echo";
25
26
  import { Markdown } from "@dxos/plugin-markdown";
26
27
  import { meta as meta2 } from "#meta";
27
- var makeKey = (name) => DXN.make(`${meta2.id}.operation.${name}`);
28
+ var makeKey = (name) => DXN.make(`${meta2.profile.key}.operation.${name}`);
28
29
  var TogglePresentation = Operation.make({
29
30
  meta: {
30
31
  key: makeKey("togglePresentation"),
31
32
  name: "Toggle Presentation",
32
33
  icon: "ph--presentation--regular"
33
34
  },
35
+ services: [
36
+ Capability2.Service
37
+ ],
34
38
  input: Schema.Struct({
35
39
  object: Schema.Union(Type.getSchema(Markdown.Document), Type.getSchema(Collection.Collection)),
36
40
  state: Schema.optional(Schema.Boolean)
@@ -66,4 +70,4 @@ export {
66
70
  Settings_exports,
67
71
  PresenterContext
68
72
  };
69
- //# sourceMappingURL=chunk-VVALMI52.mjs.map
73
+ //# sourceMappingURL=chunk-H5JLSLAO.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/types/index.ts", "../../../src/types/PresenterCapabilities.ts", "../../../src/types/PresenterOperation.ts", "../../../src/types/Settings.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context, createContext } from 'react';\n\nexport type PresenterContextType = {\n running: boolean;\n start: () => void;\n stop: () => void;\n};\n\nexport const PresenterContext: Context<PresenterContextType> = createContext<PresenterContextType>({\n running: false,\n start: () => {},\n stop: () => {},\n});\n\nexport * as PresenterCapabilities from './PresenterCapabilities';\nexport * as PresenterOperation from './PresenterOperation';\nexport * as Settings from './Settings';\n", "//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { type Atom } from '@effect-atom/atom-react';\n\nimport { Capability } from '@dxos/app-framework';\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.make<Atom.Writable<import('./Settings').Settings>>(\n `${meta.profile.key}.capability.settings`,\n);\n", "//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Operation } from '@dxos/compute';\nimport { Collection, Type, DXN } from '@dxos/echo';\nimport { Markdown } from '@dxos/plugin-markdown';\n\nimport { meta } from '#meta';\n\nconst makeKey = (name: string) => DXN.make(`${meta.profile.key}.operation.${name}`);\n\nexport const TogglePresentation = Operation.make({\n meta: {\n key: makeKey('togglePresentation'),\n name: 'Toggle Presentation',\n icon: 'ph--presentation--regular',\n },\n services: [Capability.Service],\n input: Schema.Struct({\n object: Schema.Union(Type.getSchema(Markdown.Document), Type.getSchema(Collection.Collection)),\n state: Schema.optional(Schema.Boolean),\n }),\n output: Schema.Void,\n});\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nexport const Settings = Schema.mutable(\n Schema.Struct({\n presentCollections: Schema.optional(\n Schema.Boolean.annotations({\n title: 'Present collections (experimental)',\n description: 'Enable presenting collections of documents as a slideshow.',\n }),\n ),\n }),\n);\n\nexport interface Settings extends Schema.Schema.Type<typeof Settings> {}\n"],
5
+ "mappings": ";;;;;AAIA,SAAuBA,qBAAqB;;;ACJ5C;;;;AAQA,SAASC,kBAAkB;AAE3B,SAASC,YAAY;AAId,IAAMC,WAAWF,WAAWG,KACjC,GAAGF,KAAKG,QAAQC,GAAG,sBAAsB;;;ACf3C;;;;AAMA,YAAYC,YAAY;AAExB,SAASC,cAAAA,mBAAkB;AAC3B,SAASC,iBAAiB;AAC1B,SAASC,YAAYC,MAAMC,WAAW;AACtC,SAASC,gBAAgB;AAEzB,SAASC,QAAAA,aAAY;AAErB,IAAMC,UAAU,CAACC,SAAiBJ,IAAIK,KAAK,GAAGH,MAAKI,QAAQC,GAAG,cAAcH,IAAAA,EAAM;AAE3E,IAAMI,qBAAqBX,UAAUQ,KAAK;EAC/CH,MAAM;IACJK,KAAKJ,QAAQ,oBAAA;IACbC,MAAM;IACNK,MAAM;EACR;EACAC,UAAU;IAACd,YAAWe;;EACtBC,OAAcC,cAAO;IACnBC,QAAeC,aAAMhB,KAAKiB,UAAUf,SAASgB,QAAQ,GAAGlB,KAAKiB,UAAUlB,WAAWA,UAAU,CAAA;IAC5FoB,OAAcC,gBAAgBC,cAAO;EACvC,CAAA;EACAC,QAAeC;AACjB,CAAA;;;AC7BA;;kBAAAC;;AAMA,YAAYC,aAAY;AAEjB,IAAMD,YAAkBE,gBACtBC,eAAO;EACZC,oBAA2BC,iBAClBC,gBAAQC,YAAY;IACzBC,OAAO;IACPC,aAAa;EACf,CAAA,CAAA;AAEJ,CAAA,CAAA;;;AHJK,IAAMC,mBAAkDC,cAAoC;EACjGC,SAAS;EACTC,OAAO,MAAA;EAAO;EACdC,MAAM,MAAA;EAAO;AACf,CAAA;",
6
+ "names": ["createContext", "Capability", "meta", "Settings", "make", "profile", "key", "Schema", "Capability", "Operation", "Collection", "Type", "DXN", "Markdown", "meta", "makeKey", "name", "make", "profile", "key", "TogglePresentation", "icon", "services", "Service", "input", "Struct", "object", "Union", "getSchema", "Document", "state", "optional", "Boolean", "output", "Void", "Settings", "Schema", "mutable", "Struct", "presentCollections", "optional", "Boolean", "annotations", "title", "description", "PresenterContext", "createContext", "running", "start", "stop"]
7
+ }
@@ -0,0 +1,47 @@
1
+ // src/meta.ts
2
+ import { Plugin } from "@dxos/app-framework";
3
+
4
+ // dx.config.ts
5
+ import { Config2 } from "@dxos/app-framework/config";
6
+ import { trim } from "@dxos/util";
7
+ var dx_config_default = Config2.make({
8
+ plugin: {
9
+ key: "org.dxos.plugin.presenter",
10
+ name: "Presenter",
11
+ author: "DXOS",
12
+ description: trim`
13
+ Transform existing workspace objects into interactive presentation slideshows without
14
+ duplicating content. Markdown documents are split into slides on horizontal \`---\`
15
+ separators and rendered with Reveal.js, giving authors a familiar authoring surface
16
+ with full Markdown syntax. Collections can optionally be presented slide-by-slide,
17
+ with each member object rendered by its own plugin surface.
18
+
19
+ Activate presentation mode for any supported object via the action menu or the
20
+ Shift+Cmd+P (macOS) / Shift+Alt+P (Windows/Linux) keyboard shortcut. The presenter
21
+ opens in a solo fullscreen layout managed by the Deck plugin, keeping the rest of the
22
+ workspace undisturbed.
23
+
24
+ Navigation controls and a page-number indicator are shown during collection
25
+ slideshows. Pressing Escape exits fullscreen and returns to the originating document
26
+ or collection view. All navigation is keyboard-accessible.
27
+
28
+ Collaboration is inherent: because slides are backed by live ECHO objects, edits made
29
+ by any peer in the workspace are immediately reflected in an open presentation without
30
+ any manual refresh.
31
+ `,
32
+ source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-presenter",
33
+ icon: {
34
+ key: "ph--presentation--regular",
35
+ hue: "indigo"
36
+ },
37
+ spec: "PLUGIN.mdl"
38
+ }
39
+ });
40
+
41
+ // src/meta.ts
42
+ var meta = Plugin.getMetaFromConfig(dx_config_default);
43
+
44
+ export {
45
+ meta
46
+ };
47
+ //# sourceMappingURL=chunk-MSQDHOPV.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/meta.ts", "../../../dx.config.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\n\nimport config from '../dx.config';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n", "//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.presenter',\n name: 'Presenter',\n author: 'DXOS',\n description: trim`\n Transform existing workspace objects into interactive presentation slideshows without\n duplicating content. Markdown documents are split into slides on horizontal \\`---\\`\n separators and rendered with Reveal.js, giving authors a familiar authoring surface\n with full Markdown syntax. Collections can optionally be presented slide-by-slide,\n with each member object rendered by its own plugin surface.\n\n Activate presentation mode for any supported object via the action menu or the\n Shift+Cmd+P (macOS) / Shift+Alt+P (Windows/Linux) keyboard shortcut. The presenter\n opens in a solo fullscreen layout managed by the Deck plugin, keeping the rest of the\n workspace undisturbed.\n\n Navigation controls and a page-number indicator are shown during collection\n slideshows. Pressing Escape exits fullscreen and returns to the originating document\n or collection view. All navigation is keyboard-accessible.\n\n Collaboration is inherent: because slides are backed by live ECHO objects, edits made\n by any peer in the workspace are immediately reflected in an open presentation without\n any manual refresh.\n `,\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-presenter',\n icon: { key: 'ph--presentation--regular', hue: 'indigo' },\n spec: 'PLUGIN.mdl',\n },\n});\n"],
5
+ "mappings": ";AAIA,SAASA,cAAc;;;ACAvB,SAASC,eAAe;AACxB,SAASC,YAAY;AAErB,IAAA,oBAAeD,QAAQE,KAAK;EAC1BC,QAAQ;IACNC,KAAK;IACLC,MAAM;IACNC,QAAQ;IACRC,aAAaN;;;;;;;;;;;;;;;;;;;;IAoBbO,QAAQ;IACRC,MAAM;MAAEL,KAAK;MAA6BM,KAAK;IAAS;IACxDC,MAAM;EACR;AACF,CAAA;;;AD5BO,IAAMC,OAAOC,OAAOC,kBAAkBC,iBAAAA;",
6
+ "names": ["Plugin", "Config2", "trim", "make", "plugin", "key", "name", "author", "description", "source", "icon", "hue", "spec", "meta", "Plugin", "getMetaFromConfig", "config"]
7
+ }