@dxos/plugin-file 0.0.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 (187) hide show
  1. package/LICENSE +105 -0
  2. package/PLUGIN.mdl +372 -0
  3. package/dist/lib/neutral/FileArticle-YU6NN3KN.mjs +80 -0
  4. package/dist/lib/neutral/FileArticle-YU6NN3KN.mjs.map +7 -0
  5. package/dist/lib/neutral/FilePlugin.mjs +58 -0
  6. package/dist/lib/neutral/FilePlugin.mjs.map +7 -0
  7. package/dist/lib/neutral/FilePlugin.node.mjs +23 -0
  8. package/dist/lib/neutral/FilePlugin.node.mjs.map +7 -0
  9. package/dist/lib/neutral/capabilities/index.mjs +23 -0
  10. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  11. package/dist/lib/neutral/chunk-DKGTSUUH.mjs +8 -0
  12. package/dist/lib/neutral/chunk-DKGTSUUH.mjs.map +7 -0
  13. package/dist/lib/neutral/chunk-GMYSEHV4.mjs +40 -0
  14. package/dist/lib/neutral/chunk-GMYSEHV4.mjs.map +7 -0
  15. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  16. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +7 -0
  17. package/dist/lib/neutral/chunk-LBZ4MCLI.mjs +45 -0
  18. package/dist/lib/neutral/chunk-LBZ4MCLI.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-YODPX62X.mjs +136 -0
  20. package/dist/lib/neutral/chunk-YODPX62X.mjs.map +7 -0
  21. package/dist/lib/neutral/chunk-ZUXUTRAJ.mjs +80 -0
  22. package/dist/lib/neutral/chunk-ZUXUTRAJ.mjs.map +7 -0
  23. package/dist/lib/neutral/components/index.mjs +74 -0
  24. package/dist/lib/neutral/components/index.mjs.map +7 -0
  25. package/dist/lib/neutral/containers/index.mjs +59 -0
  26. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  27. package/dist/lib/neutral/create-IUUG7RI6.mjs +17 -0
  28. package/dist/lib/neutral/create-IUUG7RI6.mjs.map +7 -0
  29. package/dist/lib/neutral/create-object-V667G4ZL.mjs +30 -0
  30. package/dist/lib/neutral/create-object-V667G4ZL.mjs.map +7 -0
  31. package/dist/lib/neutral/file-uploader-BCJH6TUL.mjs +41 -0
  32. package/dist/lib/neutral/file-uploader-BCJH6TUL.mjs.map +7 -0
  33. package/dist/lib/neutral/index.mjs +32 -0
  34. package/dist/lib/neutral/index.mjs.map +7 -0
  35. package/dist/lib/neutral/inline-backend-FGGGDYRB.mjs +37 -0
  36. package/dist/lib/neutral/inline-backend-FGGGDYRB.mjs.map +7 -0
  37. package/dist/lib/neutral/markdown-extension-RA5YNMTW.mjs +230 -0
  38. package/dist/lib/neutral/markdown-extension-RA5YNMTW.mjs.map +7 -0
  39. package/dist/lib/neutral/meta.json +1 -0
  40. package/dist/lib/neutral/meta.mjs +8 -0
  41. package/dist/lib/neutral/meta.mjs.map +7 -0
  42. package/dist/lib/neutral/operation-handler-CPDANWGH.mjs +13 -0
  43. package/dist/lib/neutral/operation-handler-CPDANWGH.mjs.map +7 -0
  44. package/dist/lib/neutral/operations/index.mjs +8 -0
  45. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  46. package/dist/lib/neutral/plugin.mjs +16 -0
  47. package/dist/lib/neutral/plugin.mjs.map +7 -0
  48. package/dist/lib/neutral/react-surface-5BXKSHD2.mjs +60 -0
  49. package/dist/lib/neutral/react-surface-5BXKSHD2.mjs.map +7 -0
  50. package/dist/lib/neutral/read-HG6CSWKR.mjs +28 -0
  51. package/dist/lib/neutral/read-HG6CSWKR.mjs.map +7 -0
  52. package/dist/lib/neutral/settings-RR3RESL2.mjs +28 -0
  53. package/dist/lib/neutral/settings-RR3RESL2.mjs.map +7 -0
  54. package/dist/lib/neutral/skill-definition-YHBGWBUS.mjs +15 -0
  55. package/dist/lib/neutral/skill-definition-YHBGWBUS.mjs.map +7 -0
  56. package/dist/lib/neutral/skills/index.mjs +11 -0
  57. package/dist/lib/neutral/skills/index.mjs.map +7 -0
  58. package/dist/lib/neutral/translations.mjs +36 -0
  59. package/dist/lib/neutral/translations.mjs.map +7 -0
  60. package/dist/lib/neutral/types/index.mjs +22 -0
  61. package/dist/lib/neutral/types/index.mjs.map +7 -0
  62. package/dist/types/dx.config.d.ts +28 -0
  63. package/dist/types/dx.config.d.ts.map +1 -0
  64. package/dist/types/src/FilePlugin.d.ts +4 -0
  65. package/dist/types/src/FilePlugin.d.ts.map +1 -0
  66. package/dist/types/src/FilePlugin.node.d.ts +4 -0
  67. package/dist/types/src/FilePlugin.node.d.ts.map +1 -0
  68. package/dist/types/src/FilePlugin.test.d.ts +2 -0
  69. package/dist/types/src/FilePlugin.test.d.ts.map +1 -0
  70. package/dist/types/src/capabilities/create-object.d.ts +5 -0
  71. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/file-uploader.d.ts +5 -0
  73. package/dist/types/src/capabilities/file-uploader.d.ts.map +1 -0
  74. package/dist/types/src/capabilities/index.d.ts +11 -0
  75. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  76. package/dist/types/src/capabilities/inline-backend.d.ts +11 -0
  77. package/dist/types/src/capabilities/inline-backend.d.ts.map +1 -0
  78. package/dist/types/src/capabilities/markdown-extension.d.ts +5 -0
  79. package/dist/types/src/capabilities/markdown-extension.d.ts.map +1 -0
  80. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  81. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  83. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/settings.d.ts +5 -0
  85. package/dist/types/src/capabilities/settings.d.ts.map +1 -0
  86. package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
  87. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
  88. package/dist/types/src/components/FileInput/FileInput.d.ts +8 -0
  89. package/dist/types/src/components/FileInput/FileInput.d.ts.map +1 -0
  90. package/dist/types/src/components/FileInput/index.d.ts +2 -0
  91. package/dist/types/src/components/FileInput/index.d.ts.map +1 -0
  92. package/dist/types/src/components/FilePreview/FilePreview.d.ts +12 -0
  93. package/dist/types/src/components/FilePreview/FilePreview.d.ts.map +1 -0
  94. package/dist/types/src/components/FilePreview/index.d.ts +2 -0
  95. package/dist/types/src/components/FilePreview/index.d.ts.map +1 -0
  96. package/dist/types/src/components/index.d.ts +3 -0
  97. package/dist/types/src/components/index.d.ts.map +1 -0
  98. package/dist/types/src/containers/FileArticle/FileArticle.d.ts +7 -0
  99. package/dist/types/src/containers/FileArticle/FileArticle.d.ts.map +1 -0
  100. package/dist/types/src/containers/FileArticle/index.d.ts +2 -0
  101. package/dist/types/src/containers/FileArticle/index.d.ts.map +1 -0
  102. package/dist/types/src/containers/FileSettings/FileSettings.d.ts +6 -0
  103. package/dist/types/src/containers/FileSettings/FileSettings.d.ts.map +1 -0
  104. package/dist/types/src/containers/FileSettings/index.d.ts +2 -0
  105. package/dist/types/src/containers/FileSettings/index.d.ts.map +1 -0
  106. package/dist/types/src/containers/index.d.ts +4 -0
  107. package/dist/types/src/containers/index.d.ts.map +1 -0
  108. package/dist/types/src/extensions/image.d.ts +12 -0
  109. package/dist/types/src/extensions/image.d.ts.map +1 -0
  110. package/dist/types/src/extensions/index.d.ts +2 -0
  111. package/dist/types/src/extensions/index.d.ts.map +1 -0
  112. package/dist/types/src/index.d.ts +4 -0
  113. package/dist/types/src/index.d.ts.map +1 -0
  114. package/dist/types/src/meta.d.ts +33 -0
  115. package/dist/types/src/meta.d.ts.map +1 -0
  116. package/dist/types/src/operations/create.d.ts +25 -0
  117. package/dist/types/src/operations/create.d.ts.map +1 -0
  118. package/dist/types/src/operations/create.test.d.ts +2 -0
  119. package/dist/types/src/operations/create.test.d.ts.map +1 -0
  120. package/dist/types/src/operations/index.d.ts +3 -0
  121. package/dist/types/src/operations/index.d.ts.map +1 -0
  122. package/dist/types/src/operations/read.d.ts +5 -0
  123. package/dist/types/src/operations/read.d.ts.map +1 -0
  124. package/dist/types/src/plugin.d.ts +4 -0
  125. package/dist/types/src/plugin.d.ts.map +1 -0
  126. package/dist/types/src/skills/file-skill.d.ts +5 -0
  127. package/dist/types/src/skills/file-skill.d.ts.map +1 -0
  128. package/dist/types/src/skills/index.d.ts +2 -0
  129. package/dist/types/src/skills/index.d.ts.map +1 -0
  130. package/dist/types/src/translations.d.ts +40 -0
  131. package/dist/types/src/translations.d.ts.map +1 -0
  132. package/dist/types/src/types/FileCapabilities.d.ts +41 -0
  133. package/dist/types/src/types/FileCapabilities.d.ts.map +1 -0
  134. package/dist/types/src/types/FileOperation.d.ts +42 -0
  135. package/dist/types/src/types/FileOperation.d.ts.map +1 -0
  136. package/dist/types/src/types/Settings.d.ts +8 -0
  137. package/dist/types/src/types/Settings.d.ts.map +1 -0
  138. package/dist/types/src/types/index.d.ts +7 -0
  139. package/dist/types/src/types/index.d.ts.map +1 -0
  140. package/dist/types/src/types/limits.d.ts +4 -0
  141. package/dist/types/src/types/limits.d.ts.map +1 -0
  142. package/dist/types/src/types/types.d.ts +9 -0
  143. package/dist/types/src/types/types.d.ts.map +1 -0
  144. package/dist/types/tsconfig.tsbuildinfo +1 -0
  145. package/dx.config.ts +35 -0
  146. package/package.json +139 -0
  147. package/src/FilePlugin.node.ts +19 -0
  148. package/src/FilePlugin.test.ts +26 -0
  149. package/src/FilePlugin.tsx +56 -0
  150. package/src/capabilities/create-object.ts +30 -0
  151. package/src/capabilities/file-uploader.ts +35 -0
  152. package/src/capabilities/index.ts +18 -0
  153. package/src/capabilities/inline-backend.ts +41 -0
  154. package/src/capabilities/markdown-extension.ts +38 -0
  155. package/src/capabilities/operation-handler.ts +16 -0
  156. package/src/capabilities/react-surface.tsx +61 -0
  157. package/src/capabilities/settings.ts +31 -0
  158. package/src/capabilities/skill-definition.ts +14 -0
  159. package/src/components/FileInput/FileInput.tsx +48 -0
  160. package/src/components/FileInput/index.ts +5 -0
  161. package/src/components/FilePreview/FilePreview.tsx +55 -0
  162. package/src/components/FilePreview/index.ts +5 -0
  163. package/src/components/index.ts +6 -0
  164. package/src/containers/FileArticle/FileArticle.tsx +84 -0
  165. package/src/containers/FileArticle/index.ts +5 -0
  166. package/src/containers/FileSettings/FileSettings.tsx +67 -0
  167. package/src/containers/FileSettings/index.ts +5 -0
  168. package/src/containers/index.ts +9 -0
  169. package/src/extensions/image.tsx +232 -0
  170. package/src/extensions/index.ts +5 -0
  171. package/src/index.ts +7 -0
  172. package/src/meta.ts +9 -0
  173. package/src/operations/create.test.ts +53 -0
  174. package/src/operations/create.ts +87 -0
  175. package/src/operations/index.ts +10 -0
  176. package/src/operations/read.ts +35 -0
  177. package/src/plugin.ts +11 -0
  178. package/src/skills/file-skill.ts +38 -0
  179. package/src/skills/index.ts +5 -0
  180. package/src/translations.ts +37 -0
  181. package/src/types/FileCapabilities.ts +58 -0
  182. package/src/types/FileOperation.ts +44 -0
  183. package/src/types/Settings.ts +23 -0
  184. package/src/types/index.ts +12 -0
  185. package/src/types/limits.ts +21 -0
  186. package/src/types/types.ts +21 -0
  187. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,59 @@
1
+ import "../chunk-J5LGTIGS.mjs";
2
+
3
+ // src/containers/index.ts
4
+ import { lazy } from "react";
5
+
6
+ // src/containers/FileSettings/FileSettings.tsx
7
+ import React, { useCallback } from "react";
8
+ import { useCapabilities } from "@dxos/app-framework/ui";
9
+ import { Select, useTranslation } from "@dxos/react-ui";
10
+ import { Form } from "@dxos/react-ui-form";
11
+ import { meta } from "#meta";
12
+ import { FileCapabilities, Settings } from "#types";
13
+ var FileSettings = ({ settings, onSettingsChange }) => {
14
+ const { t } = useTranslation(meta.profile.key);
15
+ const backends = useCapabilities(FileCapabilities.Backend);
16
+ const requestedId = settings.backend ?? Settings.DEFAULT_BACKEND_ID;
17
+ const active = backends.find((b) => b.id === requestedId) ?? backends.find((b) => b.id === Settings.DEFAULT_BACKEND_ID);
18
+ const activeId = active?.id ?? Settings.DEFAULT_BACKEND_ID;
19
+ const handleChange = useCallback((value) => onSettingsChange?.((current) => ({
20
+ ...current,
21
+ backend: value
22
+ })), [
23
+ onSettingsChange
24
+ ]);
25
+ return /* @__PURE__ */ React.createElement(Form.Root, {
26
+ schema: Settings.Settings,
27
+ values: settings,
28
+ variant: "settings",
29
+ readonly: !onSettingsChange,
30
+ onValuesChanged: (values) => onSettingsChange?.((current) => ({
31
+ ...current,
32
+ ...values
33
+ }))
34
+ }, /* @__PURE__ */ React.createElement(Form.Viewport, {
35
+ scroll: true
36
+ }, /* @__PURE__ */ React.createElement(Form.Content, null, /* @__PURE__ */ React.createElement(Form.Section, {
37
+ title: meta.profile.name ?? meta.profile.key
38
+ }, /* @__PURE__ */ React.createElement(Form.Row, {
39
+ label: t("settings.backend.label"),
40
+ description: active?.description ?? t("settings.backend.description")
41
+ }, /* @__PURE__ */ React.createElement(Select.Root, {
42
+ value: activeId,
43
+ onValueChange: handleChange,
44
+ disabled: !onSettingsChange
45
+ }, /* @__PURE__ */ React.createElement(Select.TriggerButton, {
46
+ placeholder: t("settings.backend.placeholder")
47
+ }), /* @__PURE__ */ React.createElement(Select.Portal, null, /* @__PURE__ */ React.createElement(Select.Content, null, /* @__PURE__ */ React.createElement(Select.Viewport, null, backends.map((backend) => /* @__PURE__ */ React.createElement(Select.Option, {
48
+ key: backend.id,
49
+ value: backend.id
50
+ }, backend.name))), /* @__PURE__ */ React.createElement(Select.Arrow, null)))))))));
51
+ };
52
+
53
+ // src/containers/index.ts
54
+ var FileArticle = lazy(() => import("../FileArticle-YU6NN3KN.mjs"));
55
+ export {
56
+ FileArticle,
57
+ FileSettings
58
+ };
59
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/containers/index.ts", "../../../../src/containers/FileSettings/FileSettings.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type ComponentType, lazy } from 'react';\n\nexport const FileArticle: ComponentType<any> = lazy(() => import('./FileArticle'));\n\nexport * from './FileSettings';\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback } from 'react';\n\nimport { useCapabilities } from '@dxos/app-framework/ui';\nimport { type AppSurface } from '@dxos/app-toolkit/ui';\nimport { Select, useTranslation } from '@dxos/react-ui';\nimport { Form } from '@dxos/react-ui-form';\n\nimport { meta } from '#meta';\nimport { FileCapabilities, Settings } from '#types';\n\nexport type FileSettingsProps = AppSurface.SettingsProps<Settings.Settings>;\n\nexport const FileSettings = ({ settings, onSettingsChange }: FileSettingsProps) => {\n const { t } = useTranslation(meta.profile.key);\n const backends = useCapabilities(FileCapabilities.Backend);\n const requestedId = settings.backend ?? Settings.DEFAULT_BACKEND_ID;\n const active =\n backends.find((b) => b.id === requestedId) ?? backends.find((b) => b.id === Settings.DEFAULT_BACKEND_ID);\n // Use the resolved backend id so the Select never shows a missing/stale value.\n const activeId = active?.id ?? Settings.DEFAULT_BACKEND_ID;\n\n const handleChange = useCallback(\n (value: string) => onSettingsChange?.((current) => ({ ...current, backend: value })),\n [onSettingsChange],\n );\n\n return (\n <Form.Root\n schema={Settings.Settings}\n values={settings}\n variant='settings'\n readonly={!onSettingsChange}\n onValuesChanged={(values) => onSettingsChange?.((current) => ({ ...current, ...values }))}\n >\n <Form.Viewport scroll>\n <Form.Content>\n <Form.Section title={meta.profile.name ?? meta.profile.key}>\n <Form.Row\n label={t('settings.backend.label')}\n description={active?.description ?? t('settings.backend.description')}\n >\n <Select.Root value={activeId} onValueChange={handleChange} disabled={!onSettingsChange}>\n <Select.TriggerButton placeholder={t('settings.backend.placeholder')} />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {backends.map((backend) => (\n <Select.Option key={backend.id} value={backend.id}>\n {backend.name}\n </Select.Option>\n ))}\n </Select.Viewport>\n <Select.Arrow />\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Form.Row>\n </Form.Section>\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n"],
5
+ "mappings": ";;;AAIA,SAA6BA,YAAY;;;ACAzC,OAAOC,SAASC,mBAAmB;AAEnC,SAASC,uBAAuB;AAEhC,SAASC,QAAQC,sBAAsB;AACvC,SAASC,YAAY;AAErB,SAASC,YAAY;AACrB,SAASC,kBAAkBC,gBAAgB;AAIpC,IAAMC,eAAe,CAAC,EAAEC,UAAUC,iBAAgB,MAAqB;AAC5E,QAAM,EAAEC,EAAC,IAAKR,eAAeE,KAAKO,QAAQC,GAAG;AAC7C,QAAMC,WAAWb,gBAAgBK,iBAAiBS,OAAO;AACzD,QAAMC,cAAcP,SAASQ,WAAWV,SAASW;AACjD,QAAMC,SACJL,SAASM,KAAK,CAACC,MAAMA,EAAEC,OAAON,WAAAA,KAAgBF,SAASM,KAAK,CAACC,MAAMA,EAAEC,OAAOf,SAASW,kBAAkB;AAEzG,QAAMK,WAAWJ,QAAQG,MAAMf,SAASW;AAExC,QAAMM,eAAexB,YACnB,CAACyB,UAAkBf,mBAAmB,CAACgB,aAAa;IAAE,GAAGA;IAAST,SAASQ;EAAM,EAAA,GACjF;IAACf;GAAiB;AAGpB,SACE,sBAAA,cAACN,KAAKuB,MAAI;IACRC,QAAQrB,SAASA;IACjBsB,QAAQpB;IACRqB,SAAQ;IACRC,UAAU,CAACrB;IACXsB,iBAAiB,CAACH,WAAWnB,mBAAmB,CAACgB,aAAa;MAAE,GAAGA;MAAS,GAAGG;IAAO,EAAA;KAEtF,sBAAA,cAACzB,KAAK6B,UAAQ;IAACC,QAAAA;KACb,sBAAA,cAAC9B,KAAK+B,SAAO,MACX,sBAAA,cAAC/B,KAAKgC,SAAO;IAACC,OAAOhC,KAAKO,QAAQ0B,QAAQjC,KAAKO,QAAQC;KACrD,sBAAA,cAACT,KAAKmC,KAAG;IACPC,OAAO7B,EAAE,wBAAA;IACT8B,aAAatB,QAAQsB,eAAe9B,EAAE,8BAAA;KAEtC,sBAAA,cAACT,OAAOyB,MAAI;IAACF,OAAOF;IAAUmB,eAAelB;IAAcmB,UAAU,CAACjC;KACpE,sBAAA,cAACR,OAAO0C,eAAa;IAACC,aAAalC,EAAE,8BAAA;MACrC,sBAAA,cAACT,OAAO4C,QAAM,MACZ,sBAAA,cAAC5C,OAAOiC,SAAO,MACb,sBAAA,cAACjC,OAAO+B,UAAQ,MACbnB,SAASiC,IAAI,CAAC9B,YACb,sBAAA,cAACf,OAAO8C,QAAM;IAACnC,KAAKI,QAAQK;IAAIG,OAAOR,QAAQK;KAC5CL,QAAQqB,IAAI,CAAA,CAAA,GAInB,sBAAA,cAACpC,OAAO+C,OAAK,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AAUjC;;;AD5DO,IAAMC,cAAkCC,KAAK,MAAM,OAAO,6BAAA,CAAA;",
6
+ "names": ["lazy", "React", "useCallback", "useCapabilities", "Select", "useTranslation", "Form", "meta", "FileCapabilities", "Settings", "FileSettings", "settings", "onSettingsChange", "t", "profile", "key", "backends", "Backend", "requestedId", "backend", "DEFAULT_BACKEND_ID", "active", "find", "b", "id", "activeId", "handleChange", "value", "current", "Root", "schema", "values", "variant", "readonly", "onValuesChanged", "Viewport", "scroll", "Content", "Section", "title", "name", "Row", "label", "description", "onValueChange", "disabled", "TriggerButton", "placeholder", "Portal", "map", "Option", "Arrow", "FileArticle", "lazy"]
7
+ }
@@ -0,0 +1,17 @@
1
+ import {
2
+ FileTooLargeError,
3
+ NoBackendError,
4
+ UnsupportedFileTypeError,
5
+ create_default,
6
+ resolveActiveBackend
7
+ } from "./chunk-ZUXUTRAJ.mjs";
8
+ import "./chunk-YODPX62X.mjs";
9
+ import "./chunk-J5LGTIGS.mjs";
10
+ export {
11
+ FileTooLargeError,
12
+ NoBackendError,
13
+ UnsupportedFileTypeError,
14
+ create_default as default,
15
+ resolveActiveBackend
16
+ };
17
+ //# sourceMappingURL=create-IUUG7RI6.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ import "./chunk-J5LGTIGS.mjs";
2
+
3
+ // src/capabilities/create-object.ts
4
+ import * as Effect from "effect/Effect";
5
+ import { Capability } from "@dxos/app-framework";
6
+ import { Operation } from "@dxos/compute";
7
+ import { Type } from "@dxos/echo";
8
+ import { SpaceCapabilities, SpaceOperation } from "@dxos/plugin-space";
9
+ import { File, FileAction, FileOperation } from "#types";
10
+ var create_object_default = Capability.makeModule(Effect.fnUntraced(function* () {
11
+ return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {
12
+ id: Type.getTypename(File.File),
13
+ inputSchema: FileAction.CreateFileSchema,
14
+ createObject: (props, options) => Effect.gen(function* () {
15
+ const { object } = yield* Operation.invoke(FileOperation.Create, {
16
+ ...props,
17
+ db: options.db
18
+ });
19
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
20
+ object,
21
+ target: options.target,
22
+ targetNodeId: options.targetNodeId
23
+ });
24
+ })
25
+ });
26
+ }));
27
+ export {
28
+ create_object_default as default
29
+ };
30
+ //# sourceMappingURL=create-object-V667G4ZL.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/create-object.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Operation } from '@dxos/compute';\nimport { Type } from '@dxos/echo';\nimport { SpaceCapabilities, SpaceOperation } from '@dxos/plugin-space';\n\nimport { File, FileAction, FileOperation } from '#types';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {\n id: Type.getTypename(File.File),\n inputSchema: FileAction.CreateFileSchema,\n createObject: (props, options) =>\n Effect.gen(function* () {\n const { object } = yield* Operation.invoke(FileOperation.Create, { ...props, db: options.db });\n return yield* Operation.invoke(SpaceOperation.AddObject, {\n object,\n target: options.target,\n targetNodeId: options.targetNodeId,\n });\n }),\n });\n }),\n);\n"],
5
+ "mappings": ";;;AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,iBAAiB;AAC1B,SAASC,YAAY;AACrB,SAASC,mBAAmBC,sBAAsB;AAElD,SAASC,MAAMC,YAAYC,qBAAqB;AAEhD,IAAA,wBAAeP,WAAWQ,WACjBC,kBAAW,aAAA;AAChB,SAAOT,WAAWU,YAAYP,kBAAkBQ,mBAAmB;IACjEC,IAAIV,KAAKW,YAAYR,KAAKA,IAAI;IAC9BS,aAAaR,WAAWS;IACxBC,cAAc,CAACC,OAAOC,YACbC,WAAI,aAAA;AACT,YAAM,EAAEC,OAAM,IAAK,OAAOnB,UAAUoB,OAAOd,cAAce,QAAQ;QAAE,GAAGL;QAAOM,IAAIL,QAAQK;MAAG,CAAA;AAC5F,aAAO,OAAOtB,UAAUoB,OAAOjB,eAAeoB,WAAW;QACvDJ;QACAK,QAAQP,QAAQO;QAChBC,cAAcR,QAAQQ;MACxB,CAAA;IACF,CAAA;EACJ,CAAA;AACF,CAAA,CAAA;",
6
+ "names": ["Effect", "Capability", "Operation", "Type", "SpaceCapabilities", "SpaceOperation", "File", "FileAction", "FileOperation", "makeModule", "fnUntraced", "contributes", "CreateObjectEntry", "id", "getTypename", "inputSchema", "CreateFileSchema", "createObject", "props", "options", "gen", "object", "invoke", "Create", "db", "AddObject", "target", "targetNodeId"]
7
+ }
@@ -0,0 +1,41 @@
1
+ import "./chunk-J5LGTIGS.mjs";
2
+
3
+ // src/capabilities/file-uploader.ts
4
+ import * as Effect from "effect/Effect";
5
+ import { Capabilities, Capability } from "@dxos/app-framework";
6
+ import { AppCapabilities } from "@dxos/app-toolkit";
7
+ import { EffectEx } from "@dxos/effect";
8
+ import { SpaceOperation } from "@dxos/plugin-space";
9
+ import { FileOperation } from "#types";
10
+ var file_uploader_default = Capability.makeModule(Effect.fnUntraced(function* () {
11
+ const capabilities = yield* Capability.Service;
12
+ return Capability.contributes(AppCapabilities.FileUploader, (db, file) => {
13
+ const { invoke } = capabilities.get(Capabilities.OperationInvoker);
14
+ const program = Effect.gen(function* () {
15
+ const { object } = yield* invoke(FileOperation.Create, {
16
+ db,
17
+ file
18
+ });
19
+ yield* invoke(SpaceOperation.AddObject, {
20
+ target: db,
21
+ object
22
+ });
23
+ const external = object.data._tag === "external" ? object.data : void 0;
24
+ return {
25
+ name: object.name ?? file.name,
26
+ type: object.type,
27
+ ...external?.url ? {
28
+ url: external.url
29
+ } : {},
30
+ ...external?.cid ? {
31
+ cid: external.cid
32
+ } : {}
33
+ };
34
+ });
35
+ return EffectEx.runAndForwardErrors(program);
36
+ });
37
+ }));
38
+ export {
39
+ file_uploader_default as default
40
+ };
41
+ //# sourceMappingURL=file-uploader-BCJH6TUL.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/file-uploader.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\nimport { EffectEx } from '@dxos/effect';\nimport { SpaceOperation } from '@dxos/plugin-space';\n\nimport { FileOperation } from '#types';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const capabilities = yield* Capability.Service;\n\n return Capability.contributes(AppCapabilities.FileUploader, (db, file) => {\n const { invoke } = capabilities.get(Capabilities.OperationInvoker);\n const program = Effect.gen(function* () {\n const { object } = yield* invoke(FileOperation.Create, { db, file });\n yield* invoke(SpaceOperation.AddObject, { target: db, object });\n const external = object.data._tag === 'external' ? object.data : undefined;\n return {\n name: object.name ?? file.name,\n type: object.type,\n ...(external?.url ? { url: external.url } : {}),\n ...(external?.cid ? { cid: external.cid } : {}),\n };\n });\n\n return EffectEx.runAndForwardErrors(program);\n });\n }),\n);\n"],
5
+ "mappings": ";;;AAIA,YAAYA,YAAY;AAExB,SAASC,cAAcC,kBAAkB;AACzC,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,sBAAsB;AAE/B,SAASC,qBAAqB;AAE9B,IAAA,wBAAeJ,WAAWK,WACjBC,kBAAW,aAAA;AAChB,QAAMC,eAAe,OAAOP,WAAWQ;AAEvC,SAAOR,WAAWS,YAAYR,gBAAgBS,cAAc,CAACC,IAAIC,SAAAA;AAC/D,UAAM,EAAEC,OAAM,IAAKN,aAAaO,IAAIf,aAAagB,gBAAgB;AACjE,UAAMC,UAAiBC,WAAI,aAAA;AACzB,YAAM,EAAEC,OAAM,IAAK,OAAOL,OAAOT,cAAce,QAAQ;QAAER;QAAIC;MAAK,CAAA;AAClE,aAAOC,OAAOV,eAAeiB,WAAW;QAAEC,QAAQV;QAAIO;MAAO,CAAA;AAC7D,YAAMI,WAAWJ,OAAOK,KAAKC,SAAS,aAAaN,OAAOK,OAAOE;AACjE,aAAO;QACLC,MAAMR,OAAOQ,QAAQd,KAAKc;QAC1BC,MAAMT,OAAOS;QACb,GAAIL,UAAUM,MAAM;UAAEA,KAAKN,SAASM;QAAI,IAAI,CAAC;QAC7C,GAAIN,UAAUO,MAAM;UAAEA,KAAKP,SAASO;QAAI,IAAI,CAAC;MAC/C;IACF,CAAA;AAEA,WAAO3B,SAAS4B,oBAAoBd,OAAAA;EACtC,CAAA;AACF,CAAA,CAAA;",
6
+ "names": ["Effect", "Capabilities", "Capability", "AppCapabilities", "EffectEx", "SpaceOperation", "FileOperation", "makeModule", "fnUntraced", "capabilities", "Service", "contributes", "FileUploader", "db", "file", "invoke", "get", "OperationInvoker", "program", "gen", "object", "Create", "AddObject", "target", "external", "data", "_tag", "undefined", "name", "type", "url", "cid", "runAndForwardErrors"]
7
+ }
@@ -0,0 +1,32 @@
1
+ import {
2
+ SKILL_KEY,
3
+ file_skill_default
4
+ } from "./chunk-GMYSEHV4.mjs";
5
+ import {
6
+ ACCEPTED_MIME,
7
+ File,
8
+ FileAction,
9
+ FileCapabilities_exports,
10
+ FileOperation_exports,
11
+ MAX_FILE_SIZE,
12
+ Settings_exports,
13
+ isAcceptedMimeType
14
+ } from "./chunk-YODPX62X.mjs";
15
+ import {
16
+ meta
17
+ } from "./chunk-LBZ4MCLI.mjs";
18
+ import "./chunk-J5LGTIGS.mjs";
19
+ export {
20
+ ACCEPTED_MIME,
21
+ File,
22
+ FileAction,
23
+ FileCapabilities_exports as FileCapabilities,
24
+ FileOperation_exports as FileOperation,
25
+ file_skill_default as FileSkill,
26
+ MAX_FILE_SIZE,
27
+ SKILL_KEY,
28
+ Settings_exports as Settings,
29
+ isAcceptedMimeType,
30
+ meta
31
+ };
32
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }
@@ -0,0 +1,37 @@
1
+ import {
2
+ FileTooLargeError,
3
+ UnsupportedFileTypeError
4
+ } from "./chunk-ZUXUTRAJ.mjs";
5
+ import "./chunk-YODPX62X.mjs";
6
+ import "./chunk-J5LGTIGS.mjs";
7
+
8
+ // src/capabilities/inline-backend.ts
9
+ import * as Effect from "effect/Effect";
10
+ import { Capability } from "@dxos/app-framework";
11
+ import { File, FileCapabilities, MAX_FILE_SIZE, Settings, isAcceptedMimeType } from "#types";
12
+ var inlineBackend = {
13
+ id: Settings.DEFAULT_BACKEND_ID,
14
+ name: "Inline (ECHO)",
15
+ description: "Store the file bytes directly inside the ECHO document. Capped at 4MB; images, videos, and PDFs only.",
16
+ upload: async (file) => {
17
+ if (!isAcceptedMimeType(file.type)) {
18
+ throw new UnsupportedFileTypeError(file.type);
19
+ }
20
+ if (file.size > MAX_FILE_SIZE) {
21
+ throw new FileTooLargeError(file.size);
22
+ }
23
+ const bytes = new Uint8Array(await file.arrayBuffer());
24
+ return {
25
+ name: file.name,
26
+ type: file.type,
27
+ size: bytes.byteLength,
28
+ data: File.inlineData(bytes)
29
+ };
30
+ }
31
+ };
32
+ var inline_backend_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(FileCapabilities.Backend, inlineBackend)));
33
+ export {
34
+ inline_backend_default as default,
35
+ inlineBackend
36
+ };
37
+ //# sourceMappingURL=inline-backend-FGGGDYRB.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/inline-backend.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\n\nimport { File, FileCapabilities, MAX_FILE_SIZE, Settings, isAcceptedMimeType } from '#types';\n\nimport { FileTooLargeError, UnsupportedFileTypeError } from '../operations/create';\n\n/**\n * Inline backend: file bytes are stored on the ECHO object itself.\n * Exported standalone for direct testing.\n */\nexport const inlineBackend: FileCapabilities.Backend = {\n id: Settings.DEFAULT_BACKEND_ID,\n name: 'Inline (ECHO)',\n description: 'Store the file bytes directly inside the ECHO document. Capped at 4MB; images, videos, and PDFs only.',\n upload: async (file) => {\n if (!isAcceptedMimeType(file.type)) {\n throw new UnsupportedFileTypeError(file.type);\n }\n // Check size before reading into memory to avoid allocating a large buffer.\n if (file.size > MAX_FILE_SIZE) {\n throw new FileTooLargeError(file.size);\n }\n const bytes = new Uint8Array(await file.arrayBuffer());\n return {\n name: file.name,\n type: file.type,\n size: bytes.byteLength,\n data: File.inlineData(bytes),\n };\n },\n};\n\nexport default Capability.makeModule(() =>\n Effect.succeed(Capability.contributes(FileCapabilities.Backend, inlineBackend)),\n);\n"],
5
+ "mappings": ";;;;;;;;AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAE3B,SAASC,MAAMC,kBAAkBC,eAAeC,UAAUC,0BAA0B;AAQ7E,IAAMC,gBAA0C;EACrDC,IAAIC,SAASC;EACbC,MAAM;EACNC,aAAa;EACbC,QAAQ,OAAOC,SAAAA;AACb,QAAI,CAACC,mBAAmBD,KAAKE,IAAI,GAAG;AAClC,YAAM,IAAIC,yBAAyBH,KAAKE,IAAI;IAC9C;AAEA,QAAIF,KAAKI,OAAOC,eAAe;AAC7B,YAAM,IAAIC,kBAAkBN,KAAKI,IAAI;IACvC;AACA,UAAMG,QAAQ,IAAIC,WAAW,MAAMR,KAAKS,YAAW,CAAA;AACnD,WAAO;MACLZ,MAAMG,KAAKH;MACXK,MAAMF,KAAKE;MACXE,MAAMG,MAAMG;MACZC,MAAMC,KAAKC,WAAWN,KAAAA;IACxB;EACF;AACF;AAEA,IAAA,yBAAeO,WAAWC,WAAW,MAC5BC,eAAQF,WAAWG,YAAYC,iBAAiBC,SAAS1B,aAAAA,CAAAA,CAAAA;",
6
+ "names": ["Effect", "Capability", "File", "FileCapabilities", "MAX_FILE_SIZE", "Settings", "isAcceptedMimeType", "inlineBackend", "id", "Settings", "DEFAULT_BACKEND_ID", "name", "description", "upload", "file", "isAcceptedMimeType", "type", "UnsupportedFileTypeError", "size", "MAX_FILE_SIZE", "FileTooLargeError", "bytes", "Uint8Array", "arrayBuffer", "byteLength", "data", "File", "inlineData", "Capability", "makeModule", "succeed", "contributes", "FileCapabilities", "Backend"]
7
+ }
@@ -0,0 +1,230 @@
1
+ import "./chunk-J5LGTIGS.mjs";
2
+
3
+ // src/capabilities/markdown-extension.ts
4
+ import * as Effect from "effect/Effect";
5
+ import { Capability } from "@dxos/app-framework";
6
+ import { MarkdownCapabilities } from "@dxos/plugin-markdown/types";
7
+ import { getSpace } from "@dxos/react-client/echo";
8
+ import { FileCapabilities } from "#types";
9
+
10
+ // src/extensions/image.tsx
11
+ import { syntaxTree } from "@codemirror/language";
12
+ import { StateField } from "@codemirror/state";
13
+ import { Decoration, EditorView, WidgetType } from "@codemirror/view";
14
+ import React from "react";
15
+ import { createRoot } from "react-dom/client";
16
+ import { Filter, Obj } from "@dxos/echo";
17
+ import { EID } from "@dxos/keys";
18
+ import { Status, ThemeProvider } from "@dxos/react-ui";
19
+ import { defaultTx } from "@dxos/react-ui";
20
+ import { focusField } from "@dxos/ui-editor";
21
+ import { File } from "#types";
22
+ var WAIT_UNTIL_LOADER = 1500;
23
+ var image = (options) => {
24
+ const blobUrlCache = {};
25
+ const preloaded = /* @__PURE__ */ new Set();
26
+ const preload = (url) => {
27
+ if (!preloaded.has(url)) {
28
+ const img = document.createElement("img");
29
+ img.src = url;
30
+ preloaded.add(url);
31
+ }
32
+ };
33
+ return [
34
+ StateField.define({
35
+ create: (state) => Decoration.set(buildDecorations({
36
+ from: 0,
37
+ to: state.doc.length,
38
+ state,
39
+ blobUrlCache,
40
+ preload,
41
+ options
42
+ })),
43
+ update: (value, tr) => {
44
+ if (!tr.docChanged && !tr.selection) {
45
+ return value;
46
+ }
47
+ const cursor = tr.state.selection.main.head;
48
+ const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
49
+ let from = Math.min(cursor, oldCursor);
50
+ let to = Math.max(cursor, oldCursor);
51
+ tr.changes.iterChangedRanges((_fromA, _toA, fromB, toB) => {
52
+ from = Math.min(from, fromB);
53
+ to = Math.max(to, toB);
54
+ });
55
+ from = tr.state.doc.lineAt(from).from;
56
+ to = tr.state.doc.lineAt(to).to;
57
+ return value.map(tr.changes).update({
58
+ filterFrom: from,
59
+ filterTo: to,
60
+ filter: () => false,
61
+ add: buildDecorations({
62
+ from,
63
+ to,
64
+ state: tr.state,
65
+ blobUrlCache,
66
+ preload,
67
+ options
68
+ })
69
+ });
70
+ },
71
+ provide: (field) => EditorView.decorations.from(field)
72
+ })
73
+ ];
74
+ };
75
+ var buildDecorations = ({ state, from, to, blobUrlCache, preload, options: { space, resolvers } }) => {
76
+ const decorations = [];
77
+ const cursor = state.selection.main.head;
78
+ syntaxTree(state).iterate({
79
+ enter: (node) => {
80
+ if (node.name !== "Image") {
81
+ return;
82
+ }
83
+ const urlNode = node.node.getChild("URL");
84
+ if (!urlNode) {
85
+ return;
86
+ }
87
+ const hide = state.readOnly || cursor < node.from || cursor > node.to;
88
+ const urlText = state.sliceDoc(urlNode.from, urlNode.to);
89
+ if (!EID.isEID(urlText)) {
90
+ return;
91
+ }
92
+ let echoUri;
93
+ let echoSpaceId;
94
+ try {
95
+ const parsed = EID.parse(urlText);
96
+ echoUri = EID.getEntityId(parsed);
97
+ echoSpaceId = EID.getSpaceId(parsed);
98
+ } catch {
99
+ return;
100
+ }
101
+ if (!echoUri) {
102
+ return;
103
+ }
104
+ if (echoSpaceId && echoSpaceId !== space.id) {
105
+ return;
106
+ }
107
+ const cacheKey = urlText;
108
+ const blobUrlPromise = (async () => {
109
+ const matched = await space.db.query(Filter.id(echoUri)).first();
110
+ if (!matched || !Obj.instanceOf(File.File, matched)) {
111
+ return void 0;
112
+ }
113
+ let url;
114
+ const { data } = matched;
115
+ if (data._tag === "inline") {
116
+ url = URL.createObjectURL(new Blob([
117
+ data.bytes
118
+ ], {
119
+ type: matched.type
120
+ }));
121
+ } else if (/^(?:https?|data|blob):/i.test(data.url)) {
122
+ url = data.url;
123
+ } else {
124
+ const resolver = resolvers.find((r) => r.test(data.url));
125
+ url = await resolver?.resolve(data.url, matched, space);
126
+ }
127
+ if (!url) {
128
+ return void 0;
129
+ }
130
+ blobUrlCache[cacheKey] = url;
131
+ preload(url);
132
+ return url;
133
+ })();
134
+ decorations.push(Decoration.replace({
135
+ block: true,
136
+ widget: new DxnImageWidget(urlText, blobUrlCache[cacheKey] ?? blobUrlPromise)
137
+ }).range(hide ? node.from : node.to, node.to));
138
+ },
139
+ from,
140
+ to
141
+ });
142
+ return decorations;
143
+ };
144
+ var createImg = (view, url) => {
145
+ const img = document.createElement("img");
146
+ img.setAttribute("src", url);
147
+ img.setAttribute("class", "cm-image-with-loader");
148
+ if (view.state.field(focusField)) {
149
+ img.onload = () => img.classList.add("cm-loaded-image");
150
+ } else {
151
+ img.classList.add("cm-loaded-image");
152
+ }
153
+ return img;
154
+ };
155
+ var DxnImageWidget = class extends WidgetType {
156
+ _dxnUrl;
157
+ _url;
158
+ constructor(_dxnUrl, _url) {
159
+ super(), this._dxnUrl = _dxnUrl, this._url = _url;
160
+ }
161
+ eq(other) {
162
+ return this._dxnUrl === other._dxnUrl;
163
+ }
164
+ toDOM(view) {
165
+ if (typeof this._url === "string") {
166
+ return createImg(view, this._url);
167
+ }
168
+ const widget = document.createElement("div");
169
+ widget.className = "cm-image-wrapper";
170
+ const loader = document.createElement("div");
171
+ loader.className = "mx-auto transition-opacity";
172
+ let loaderAdded = false;
173
+ const timeout = setTimeout(() => {
174
+ const root = createRoot(loader);
175
+ root.render(/* @__PURE__ */ React.createElement(ThemeProvider, {
176
+ tx: defaultTx
177
+ }, /* @__PURE__ */ React.createElement(Status, {
178
+ indeterminate: true
179
+ })));
180
+ widget.appendChild(loader);
181
+ loaderAdded = true;
182
+ }, WAIT_UNTIL_LOADER);
183
+ void Promise.resolve(this._url).then((url) => {
184
+ clearTimeout(timeout);
185
+ if (loaderAdded) {
186
+ widget.removeChild(loader);
187
+ }
188
+ if (url) {
189
+ widget.appendChild(createImg(view, url));
190
+ }
191
+ }).catch(() => {
192
+ clearTimeout(timeout);
193
+ if (loaderAdded) {
194
+ widget.removeChild(loader);
195
+ }
196
+ });
197
+ return widget;
198
+ }
199
+ };
200
+
201
+ // src/capabilities/markdown-extension.ts
202
+ var markdown_extension_default = Capability.makeModule(Effect.fnUntraced(function* () {
203
+ const capabilities = yield* Capability.Service;
204
+ const provider = ({ document: document2, viewMode }) => {
205
+ if (viewMode === "source") {
206
+ return void 0;
207
+ }
208
+ if (document2) {
209
+ const space = getSpace(document2);
210
+ if (!space) {
211
+ return void 0;
212
+ }
213
+ const resolvers = capabilities.getAll(FileCapabilities.UrlResolver);
214
+ return [
215
+ image({
216
+ space,
217
+ resolvers
218
+ })
219
+ ];
220
+ }
221
+ return void 0;
222
+ };
223
+ return Capability.contributes(MarkdownCapabilities.ExtensionProvider, [
224
+ provider
225
+ ]);
226
+ }));
227
+ export {
228
+ markdown_extension_default as default
229
+ };
230
+ //# sourceMappingURL=markdown-extension-RA5YNMTW.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/markdown-extension.ts", "../../../src/extensions/image.tsx"],
4
+ "sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { MarkdownCapabilities, type MarkdownExtensionProvider } from '@dxos/plugin-markdown/types';\nimport { getSpace } from '@dxos/react-client/echo';\n\nimport { FileCapabilities } from '#types';\n\nimport { image } from '../extensions';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const capabilities = yield* Capability.Service;\n\n const provider: MarkdownExtensionProvider = ({ document, viewMode }) => {\n if (viewMode === 'source') {\n return undefined;\n }\n\n if (document) {\n const space = getSpace(document);\n if (!space) {\n return undefined;\n }\n const resolvers = capabilities.getAll(FileCapabilities.UrlResolver);\n return [image({ space, resolvers })];\n }\n\n return undefined;\n };\n\n return Capability.contributes(MarkdownCapabilities.ExtensionProvider, [provider]);\n }),\n);\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport { type EditorState, type Extension, type Range, StateField } from '@codemirror/state';\nimport { Decoration, EditorView, WidgetType } from '@codemirror/view';\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { Filter, Obj } from '@dxos/echo';\nimport { EID } from '@dxos/keys';\nimport { type Space } from '@dxos/react-client/echo';\nimport { Status, ThemeProvider } from '@dxos/react-ui';\nimport { defaultTx } from '@dxos/react-ui';\nimport { focusField } from '@dxos/ui-editor';\nimport { type MaybePromise } from '@dxos/util';\n\nimport { File, FileCapabilities } from '#types';\n\nconst WAIT_UNTIL_LOADER = 1500;\n\nexport type ImageOptions = {\n space: Space;\n resolvers: readonly FileCapabilities.UrlResolver[];\n};\n\n/**\n * Decorate `![](echo:...)` references that resolve to File objects with inline image previews.\n */\nexport const image = (options: ImageOptions): Extension[] => {\n const blobUrlCache: Record<string, string> = {};\n const preloaded = new Set<string>();\n\n const preload = (url: string) => {\n if (!preloaded.has(url)) {\n const img = document.createElement('img');\n img.src = url;\n preloaded.add(url);\n }\n };\n\n return [\n StateField.define({\n create: (state) =>\n Decoration.set(buildDecorations({ from: 0, to: state.doc.length, state, blobUrlCache, preload, options })),\n update: (value, tr) => {\n if (!tr.docChanged && !tr.selection) {\n return value;\n }\n\n const cursor = tr.state.selection.main.head;\n const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);\n let from = Math.min(cursor, oldCursor);\n let to = Math.max(cursor, oldCursor);\n tr.changes.iterChangedRanges((_fromA, _toA, fromB, toB) => {\n from = Math.min(from, fromB);\n to = Math.max(to, toB);\n });\n\n from = tr.state.doc.lineAt(from).from;\n to = tr.state.doc.lineAt(to).to;\n\n return value.map(tr.changes).update({\n filterFrom: from,\n filterTo: to,\n filter: () => false,\n add: buildDecorations({ from, to, state: tr.state, blobUrlCache, preload, options }),\n });\n },\n provide: (field) => EditorView.decorations.from(field),\n }),\n ];\n};\n\nconst buildDecorations = ({\n state,\n from,\n to,\n blobUrlCache,\n preload,\n options: { space, resolvers },\n}: {\n state: EditorState;\n from: number;\n to: number;\n blobUrlCache: Record<string, string>;\n preload: (url: string) => void;\n options: ImageOptions;\n}) => {\n const decorations: Range<Decoration>[] = [];\n const cursor = state.selection.main.head;\n syntaxTree(state).iterate({\n enter: (node) => {\n if (node.name !== 'Image') {\n return;\n }\n\n const urlNode = node.node.getChild('URL');\n if (!urlNode) {\n return;\n }\n\n const hide = state.readOnly || cursor < node.from || cursor > node.to;\n const urlText = state.sliceDoc(urlNode.from, urlNode.to);\n if (!EID.isEID(urlText)) {\n return;\n }\n\n let echoUri: string | undefined;\n let echoSpaceId: string | undefined;\n try {\n const parsed = EID.parse(urlText);\n echoUri = EID.getEntityId(parsed);\n echoSpaceId = EID.getSpaceId(parsed);\n } catch {\n return;\n }\n if (!echoUri) {\n return;\n }\n\n // Skip references to objects in other spaces.\n if (echoSpaceId && echoSpaceId !== space.id) {\n return;\n }\n\n const cacheKey = urlText;\n const blobUrlPromise = (async () => {\n const matched = await space.db.query(Filter.id(echoUri!)).first();\n if (!matched || !Obj.instanceOf(File.File, matched)) {\n return undefined;\n }\n\n let url: string | undefined;\n const { data } = matched;\n if (data._tag === 'inline') {\n url = URL.createObjectURL(new Blob([data.bytes as BlobPart], { type: matched.type }));\n } else if (/^(?:https?|data|blob):/i.test(data.url)) {\n url = data.url;\n } else {\n const resolver = resolvers.find((r) => r.test(data.url));\n url = await resolver?.resolve(data.url, matched, space);\n }\n if (!url) {\n return undefined;\n }\n blobUrlCache[cacheKey] = url;\n preload(url);\n return url;\n })();\n\n decorations.push(\n Decoration.replace({\n block: true,\n widget: new DxnImageWidget(urlText, blobUrlCache[cacheKey] ?? blobUrlPromise),\n }).range(hide ? node.from : node.to, node.to),\n );\n },\n from,\n to,\n });\n\n return decorations;\n};\n\nconst createImg = (view: EditorView, url: string) => {\n const img = document.createElement('img');\n img.setAttribute('src', url);\n img.setAttribute('class', 'cm-image-with-loader');\n if (view.state.field(focusField)) {\n img.onload = () => img.classList.add('cm-loaded-image');\n } else {\n img.classList.add('cm-loaded-image');\n }\n return img;\n};\n\nclass DxnImageWidget extends WidgetType {\n constructor(\n readonly _dxnUrl: string,\n readonly _url: MaybePromise<string | undefined>,\n ) {\n super();\n }\n\n override eq(other: this) {\n return this._dxnUrl === other._dxnUrl;\n }\n\n override toDOM(view: EditorView) {\n if (typeof this._url === 'string') {\n return createImg(view, this._url);\n }\n\n const widget = document.createElement('div');\n widget.className = 'cm-image-wrapper';\n const loader = document.createElement('div');\n loader.className = 'mx-auto transition-opacity';\n let loaderAdded = false;\n\n const timeout = setTimeout(() => {\n const root = createRoot(loader);\n root.render(\n <ThemeProvider tx={defaultTx}>\n <Status indeterminate />\n </ThemeProvider>,\n );\n widget.appendChild(loader);\n loaderAdded = true;\n }, WAIT_UNTIL_LOADER);\n\n void Promise.resolve(this._url)\n .then((url) => {\n clearTimeout(timeout);\n if (loaderAdded) {\n widget.removeChild(loader);\n }\n if (url) {\n widget.appendChild(createImg(view, url));\n }\n })\n .catch(() => {\n clearTimeout(timeout);\n if (loaderAdded) {\n widget.removeChild(loader);\n }\n });\n\n return widget;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Effect", "Capability", "MarkdownCapabilities", "getSpace", "FileCapabilities", "syntaxTree", "StateField", "Decoration", "EditorView", "WidgetType", "React", "createRoot", "Filter", "Obj", "EID", "Status", "ThemeProvider", "defaultTx", "focusField", "File", "WAIT_UNTIL_LOADER", "image", "options", "blobUrlCache", "preloaded", "Set", "preload", "url", "has", "img", "document", "createElement", "src", "add", "define", "create", "state", "set", "buildDecorations", "from", "to", "doc", "length", "update", "value", "tr", "docChanged", "selection", "cursor", "main", "head", "oldCursor", "changes", "mapPos", "startState", "Math", "min", "max", "iterChangedRanges", "_fromA", "_toA", "fromB", "toB", "lineAt", "map", "filterFrom", "filterTo", "filter", "provide", "field", "decorations", "space", "resolvers", "iterate", "enter", "node", "name", "urlNode", "getChild", "hide", "readOnly", "urlText", "sliceDoc", "isEID", "echoUri", "echoSpaceId", "parsed", "parse", "getEntityId", "getSpaceId", "id", "cacheKey", "blobUrlPromise", "matched", "db", "query", "first", "instanceOf", "undefined", "data", "_tag", "URL", "createObjectURL", "Blob", "bytes", "type", "test", "resolver", "find", "r", "resolve", "push", "replace", "block", "widget", "DxnImageWidget", "range", "createImg", "view", "setAttribute", "onload", "classList", "_dxnUrl", "_url", "eq", "other", "toDOM", "className", "loader", "loaderAdded", "timeout", "setTimeout", "root", "render", "tx", "indeterminate", "appendChild", "Promise", "then", "clearTimeout", "removeChild", "catch", "Capability", "makeModule", "fnUntraced", "capabilities", "Service", "provider", "document", "viewMode", "undefined", "space", "getSpace", "resolvers", "getAll", "FileCapabilities", "UrlResolver", "image", "contributes", "MarkdownCapabilities", "ExtensionProvider"]
7
+ }