@dxos/plugin-markdown 0.8.2-main.f11618f → 0.8.2-staging.42af850

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 (210) hide show
  1. package/dist/lib/browser/MarkdownContainer-5IEINNQB.mjs +588 -0
  2. package/dist/lib/browser/MarkdownContainer-5IEINNQB.mjs.map +7 -0
  3. package/dist/lib/browser/MarkdownPreview-YW5CS3ID.mjs +87 -0
  4. package/dist/lib/browser/MarkdownPreview-YW5CS3ID.mjs.map +7 -0
  5. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs +32 -0
  6. package/dist/lib/browser/anchor-sort-VS4OZVPP.mjs.map +7 -0
  7. package/dist/lib/browser/{app-graph-serializer-OCXP7PCK.mjs → app-graph-serializer-V6RLEHVY.mjs} +5 -6
  8. package/dist/lib/browser/app-graph-serializer-V6RLEHVY.mjs.map +7 -0
  9. package/dist/lib/browser/{artifact-definition-XTVOUMMI.mjs → artifact-definition-5NAODQLG.mjs} +65 -17
  10. package/dist/lib/browser/artifact-definition-5NAODQLG.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-QV6ZIXAD.mjs → chunk-77NGW7EO.mjs} +6 -7
  12. package/dist/lib/browser/chunk-77NGW7EO.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-ACAID3XF.mjs +20 -0
  14. package/dist/lib/browser/chunk-ACAID3XF.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-LJ2UFBJ2.mjs → chunk-C5RABVIX.mjs} +3 -4
  16. package/dist/lib/browser/chunk-C5RABVIX.mjs.map +7 -0
  17. package/dist/lib/browser/chunk-ECSM56YC.mjs +80 -0
  18. package/dist/lib/browser/chunk-ECSM56YC.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-NAGMSX77.mjs → chunk-QVJETNGS.mjs} +2 -2
  20. package/dist/lib/{node-esm/chunk-ETXPC5VP.mjs.map → browser/chunk-QVJETNGS.mjs.map} +1 -1
  21. package/dist/lib/browser/index.mjs +31 -19
  22. package/dist/lib/browser/index.mjs.map +3 -3
  23. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs +65 -0
  24. package/dist/lib/browser/intent-resolver-4GDYST4Y.mjs.map +7 -0
  25. package/dist/lib/browser/meta.json +1 -1
  26. package/dist/lib/browser/{react-surface-LBCMSLJ5.mjs → react-surface-QE4SKXBT.mjs} +80 -66
  27. package/dist/lib/browser/react-surface-QE4SKXBT.mjs.map +7 -0
  28. package/dist/lib/browser/{settings-EQSDBX6O.mjs → settings-W5CK4PXP.mjs} +2 -2
  29. package/dist/lib/browser/{state-AIN4J7N5.mjs → state-KI6PJ6DT.mjs} +3 -3
  30. package/dist/lib/browser/state-KI6PJ6DT.mjs.map +7 -0
  31. package/dist/lib/browser/types/index.mjs +1 -1
  32. package/dist/lib/node/MarkdownContainer-LSNNPNRB.cjs +601 -0
  33. package/dist/lib/node/MarkdownContainer-LSNNPNRB.cjs.map +7 -0
  34. package/dist/lib/node/MarkdownPreview-G34HSQEB.cjs +110 -0
  35. package/dist/lib/node/MarkdownPreview-G34HSQEB.cjs.map +7 -0
  36. package/dist/lib/node/{thread-MXEGV6HS.cjs → anchor-sort-NHVF23EU.cjs} +15 -20
  37. package/dist/lib/node/anchor-sort-NHVF23EU.cjs.map +7 -0
  38. package/dist/lib/node/{app-graph-serializer-KBDLASRP.cjs → app-graph-serializer-CLALIYN3.cjs} +10 -11
  39. package/dist/lib/node/app-graph-serializer-CLALIYN3.cjs.map +7 -0
  40. package/dist/lib/node/{artifact-definition-ADEN2KD6.cjs → artifact-definition-VEAHK7BX.cjs} +68 -21
  41. package/dist/lib/node/artifact-definition-VEAHK7BX.cjs.map +7 -0
  42. package/dist/lib/node/{chunk-QRE5L6ZC.cjs → chunk-C4HR7UXE.cjs} +15 -15
  43. package/dist/lib/node/chunk-C4HR7UXE.cjs.map +7 -0
  44. package/dist/lib/node/{chunk-WGMVEPB3.cjs → chunk-G7RBJX22.cjs} +8 -9
  45. package/dist/lib/node/chunk-G7RBJX22.cjs.map +7 -0
  46. package/dist/lib/node/{chunk-DZXTXSXX.cjs → chunk-IFYSBQE5.cjs} +5 -5
  47. package/dist/lib/node/{chunk-DZXTXSXX.cjs.map → chunk-IFYSBQE5.cjs.map} +1 -1
  48. package/dist/lib/node/{chunk-YHL4JSA6.cjs → chunk-RQS4KBMG.cjs} +38 -42
  49. package/dist/lib/node/chunk-RQS4KBMG.cjs.map +7 -0
  50. package/dist/lib/node/{chunk-JO4SBK36.cjs → chunk-ZDTL47I7.cjs} +6 -7
  51. package/dist/lib/node/chunk-ZDTL47I7.cjs.map +7 -0
  52. package/dist/lib/node/index.cjs +42 -30
  53. package/dist/lib/node/index.cjs.map +3 -3
  54. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs +78 -0
  55. package/dist/lib/node/intent-resolver-AUZVK3NZ.cjs.map +7 -0
  56. package/dist/lib/node/meta.json +1 -1
  57. package/dist/lib/node/react-surface-WJZTEBYO.cjs +213 -0
  58. package/dist/lib/node/react-surface-WJZTEBYO.cjs.map +7 -0
  59. package/dist/lib/node/{settings-2JXASSLU.cjs → settings-IRKU3WPM.cjs} +6 -6
  60. package/dist/lib/node/{state-PC7IVXFP.cjs → state-KKDRAG7X.cjs} +7 -7
  61. package/dist/lib/node/state-KKDRAG7X.cjs.map +7 -0
  62. package/dist/lib/node/types/index.cjs +7 -7
  63. package/dist/lib/node/types/index.cjs.map +1 -1
  64. package/dist/lib/node-esm/MarkdownContainer-UZSLXMWO.mjs +589 -0
  65. package/dist/lib/node-esm/MarkdownContainer-UZSLXMWO.mjs.map +7 -0
  66. package/dist/lib/node-esm/MarkdownPreview-TCV7BI32.mjs +88 -0
  67. package/dist/lib/node-esm/MarkdownPreview-TCV7BI32.mjs.map +7 -0
  68. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs +33 -0
  69. package/dist/lib/node-esm/anchor-sort-G2HLCYFK.mjs.map +7 -0
  70. package/dist/lib/node-esm/{app-graph-serializer-67CO7ST3.mjs → app-graph-serializer-C3RNTQGM.mjs} +5 -6
  71. package/dist/lib/node-esm/app-graph-serializer-C3RNTQGM.mjs.map +7 -0
  72. package/dist/lib/node-esm/{artifact-definition-KTS5M2FW.mjs → artifact-definition-7TIJW2CO.mjs} +65 -17
  73. package/dist/lib/node-esm/artifact-definition-7TIJW2CO.mjs.map +7 -0
  74. package/dist/lib/node-esm/{chunk-4U2F4EB7.mjs → chunk-6RPARLIK.mjs} +6 -7
  75. package/dist/lib/node-esm/chunk-6RPARLIK.mjs.map +7 -0
  76. package/dist/lib/node-esm/{chunk-PALFXZBY.mjs → chunk-EIUTPXGL.mjs} +10 -10
  77. package/dist/lib/node-esm/chunk-EIUTPXGL.mjs.map +7 -0
  78. package/dist/lib/node-esm/{chunk-ETXPC5VP.mjs → chunk-JXXDCSMW.mjs} +2 -2
  79. package/dist/lib/{browser/chunk-NAGMSX77.mjs.map → node-esm/chunk-JXXDCSMW.mjs.map} +1 -1
  80. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs +81 -0
  81. package/dist/lib/node-esm/chunk-NCMPVEXO.mjs.map +7 -0
  82. package/dist/lib/node-esm/{chunk-VQA6BQGT.mjs → chunk-TCFJNUAE.mjs} +3 -4
  83. package/dist/lib/node-esm/chunk-TCFJNUAE.mjs.map +7 -0
  84. package/dist/lib/node-esm/index.mjs +31 -19
  85. package/dist/lib/node-esm/index.mjs.map +3 -3
  86. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs +66 -0
  87. package/dist/lib/node-esm/intent-resolver-FTNXUNI2.mjs.map +7 -0
  88. package/dist/lib/node-esm/meta.json +1 -1
  89. package/dist/lib/node-esm/{react-surface-737EXAWT.mjs → react-surface-XNM3YDFB.mjs} +80 -66
  90. package/dist/lib/node-esm/react-surface-XNM3YDFB.mjs.map +7 -0
  91. package/dist/lib/node-esm/{settings-67RVIH3N.mjs → settings-MK7D7LHQ.mjs} +2 -2
  92. package/dist/lib/node-esm/{state-PNOPM4TS.mjs → state-LLGVRYKL.mjs} +3 -3
  93. package/dist/lib/node-esm/state-LLGVRYKL.mjs.map +7 -0
  94. package/dist/lib/node-esm/types/index.mjs +1 -1
  95. package/dist/types/src/MarkdownPlugin.d.ts.map +1 -1
  96. package/dist/types/src/capabilities/anchor-sort.d.ts +6 -0
  97. package/dist/types/src/capabilities/anchor-sort.d.ts.map +1 -0
  98. package/dist/types/src/capabilities/app-graph-serializer.d.ts +2 -2
  99. package/dist/types/src/capabilities/app-graph-serializer.d.ts.map +1 -1
  100. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  101. package/dist/types/src/capabilities/index.d.ts +7 -7
  102. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  103. package/dist/types/src/capabilities/intent-resolver.d.ts +2 -2
  104. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/state.d.ts +2 -2
  107. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  108. package/dist/types/src/components/MarkdownContainer.d.ts +5 -3
  109. package/dist/types/src/components/MarkdownContainer.d.ts.map +1 -1
  110. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts +3 -18
  111. package/dist/types/src/components/MarkdownEditor/MarkdownEditor.d.ts.map +1 -1
  112. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts +2 -2
  113. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.d.ts.map +1 -1
  114. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts +4 -172
  115. package/dist/types/src/components/MarkdownPreview/MarkdownPreview.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/MarkdownSettings/MarkdownSettings.d.ts.map +1 -1
  117. package/dist/types/src/components/Suggestions.stories.d.ts.map +1 -1
  118. package/dist/types/src/components/Toolbar.stories.d.ts.map +1 -1
  119. package/dist/types/src/components/index.d.ts +2 -2
  120. package/dist/types/src/components/index.d.ts.map +1 -1
  121. package/dist/types/src/extensions.d.ts +8 -5
  122. package/dist/types/src/extensions.d.ts.map +1 -1
  123. package/dist/types/src/hooks/useSelectCurrentThread.d.ts.map +1 -1
  124. package/dist/types/src/translations.d.ts +2 -46
  125. package/dist/types/src/translations.d.ts.map +1 -1
  126. package/dist/types/src/types/schema.d.ts +21 -525
  127. package/dist/types/src/types/schema.d.ts.map +1 -1
  128. package/dist/types/src/types/types.d.ts +40 -200
  129. package/dist/types/src/types/types.d.ts.map +1 -1
  130. package/dist/types/src/util.d.ts.map +1 -1
  131. package/dist/types/tsconfig.tsbuildinfo +1 -1
  132. package/package.json +48 -39
  133. package/src/MarkdownPlugin.tsx +19 -9
  134. package/src/capabilities/anchor-sort.ts +30 -0
  135. package/src/capabilities/app-graph-serializer.ts +4 -5
  136. package/src/capabilities/artifact-definition.ts +48 -10
  137. package/src/capabilities/index.ts +1 -1
  138. package/src/capabilities/intent-resolver.ts +29 -34
  139. package/src/capabilities/react-surface.tsx +14 -6
  140. package/src/capabilities/state.ts +3 -3
  141. package/src/components/MarkdownContainer.tsx +19 -7
  142. package/src/components/MarkdownEditor/MarkdownEditor.stories.tsx +1 -1
  143. package/src/components/MarkdownEditor/MarkdownEditor.tsx +29 -71
  144. package/src/components/MarkdownPreview/MarkdownPreview.stories.tsx +9 -4
  145. package/src/components/MarkdownPreview/MarkdownPreview.tsx +8 -8
  146. package/src/components/Suggestions.stories.tsx +53 -21
  147. package/src/components/Toolbar.stories.tsx +16 -16
  148. package/src/extensions.tsx +45 -16
  149. package/src/hooks/useSelectCurrentThread.tsx +2 -2
  150. package/src/translations.ts +1 -3
  151. package/src/types/schema.ts +19 -17
  152. package/src/types/types.ts +23 -21
  153. package/src/util.tsx +4 -4
  154. package/dist/lib/browser/MarkdownContainer-5XV7K2NX.mjs +0 -567
  155. package/dist/lib/browser/MarkdownContainer-5XV7K2NX.mjs.map +0 -7
  156. package/dist/lib/browser/MarkdownPreview-DX5U5LCX.mjs +0 -81
  157. package/dist/lib/browser/MarkdownPreview-DX5U5LCX.mjs.map +0 -7
  158. package/dist/lib/browser/app-graph-serializer-OCXP7PCK.mjs.map +0 -7
  159. package/dist/lib/browser/artifact-definition-XTVOUMMI.mjs.map +0 -7
  160. package/dist/lib/browser/chunk-5QXYEKSX.mjs +0 -20
  161. package/dist/lib/browser/chunk-5QXYEKSX.mjs.map +0 -7
  162. package/dist/lib/browser/chunk-GVOEHF7E.mjs +0 -84
  163. package/dist/lib/browser/chunk-GVOEHF7E.mjs.map +0 -7
  164. package/dist/lib/browser/chunk-LJ2UFBJ2.mjs.map +0 -7
  165. package/dist/lib/browser/chunk-QV6ZIXAD.mjs.map +0 -7
  166. package/dist/lib/browser/intent-resolver-H37L3DBD.mjs +0 -86
  167. package/dist/lib/browser/intent-resolver-H37L3DBD.mjs.map +0 -7
  168. package/dist/lib/browser/react-surface-LBCMSLJ5.mjs.map +0 -7
  169. package/dist/lib/browser/state-AIN4J7N5.mjs.map +0 -7
  170. package/dist/lib/browser/thread-MFKBUVCB.mjs +0 -37
  171. package/dist/lib/browser/thread-MFKBUVCB.mjs.map +0 -7
  172. package/dist/lib/node/MarkdownContainer-5EQTBXV3.cjs +0 -580
  173. package/dist/lib/node/MarkdownContainer-5EQTBXV3.cjs.map +0 -7
  174. package/dist/lib/node/MarkdownPreview-W7QIN2KJ.cjs +0 -104
  175. package/dist/lib/node/MarkdownPreview-W7QIN2KJ.cjs.map +0 -7
  176. package/dist/lib/node/app-graph-serializer-KBDLASRP.cjs.map +0 -7
  177. package/dist/lib/node/artifact-definition-ADEN2KD6.cjs.map +0 -7
  178. package/dist/lib/node/chunk-JO4SBK36.cjs.map +0 -7
  179. package/dist/lib/node/chunk-QRE5L6ZC.cjs.map +0 -7
  180. package/dist/lib/node/chunk-WGMVEPB3.cjs.map +0 -7
  181. package/dist/lib/node/chunk-YHL4JSA6.cjs.map +0 -7
  182. package/dist/lib/node/intent-resolver-NX5QNRYF.cjs +0 -99
  183. package/dist/lib/node/intent-resolver-NX5QNRYF.cjs.map +0 -7
  184. package/dist/lib/node/react-surface-DJIZSVMN.cjs +0 -199
  185. package/dist/lib/node/react-surface-DJIZSVMN.cjs.map +0 -7
  186. package/dist/lib/node/state-PC7IVXFP.cjs.map +0 -7
  187. package/dist/lib/node/thread-MXEGV6HS.cjs.map +0 -7
  188. package/dist/lib/node-esm/MarkdownContainer-LONZOJJX.mjs +0 -568
  189. package/dist/lib/node-esm/MarkdownContainer-LONZOJJX.mjs.map +0 -7
  190. package/dist/lib/node-esm/MarkdownPreview-T3OW2EN4.mjs +0 -82
  191. package/dist/lib/node-esm/MarkdownPreview-T3OW2EN4.mjs.map +0 -7
  192. package/dist/lib/node-esm/app-graph-serializer-67CO7ST3.mjs.map +0 -7
  193. package/dist/lib/node-esm/artifact-definition-KTS5M2FW.mjs.map +0 -7
  194. package/dist/lib/node-esm/chunk-4U2F4EB7.mjs.map +0 -7
  195. package/dist/lib/node-esm/chunk-NUZHKZSZ.mjs +0 -85
  196. package/dist/lib/node-esm/chunk-NUZHKZSZ.mjs.map +0 -7
  197. package/dist/lib/node-esm/chunk-PALFXZBY.mjs.map +0 -7
  198. package/dist/lib/node-esm/chunk-VQA6BQGT.mjs.map +0 -7
  199. package/dist/lib/node-esm/intent-resolver-XES4ZCA6.mjs +0 -87
  200. package/dist/lib/node-esm/intent-resolver-XES4ZCA6.mjs.map +0 -7
  201. package/dist/lib/node-esm/react-surface-737EXAWT.mjs.map +0 -7
  202. package/dist/lib/node-esm/state-PNOPM4TS.mjs.map +0 -7
  203. package/dist/lib/node-esm/thread-5U4KSBED.mjs +0 -38
  204. package/dist/lib/node-esm/thread-5U4KSBED.mjs.map +0 -7
  205. package/dist/types/src/capabilities/thread.d.ts +0 -6
  206. package/dist/types/src/capabilities/thread.d.ts.map +0 -1
  207. package/src/capabilities/thread.ts +0 -35
  208. /package/dist/lib/browser/{settings-EQSDBX6O.mjs.map → settings-W5CK4PXP.mjs.map} +0 -0
  209. /package/dist/lib/node/{settings-2JXASSLU.cjs.map → settings-IRKU3WPM.cjs.map} +0 -0
  210. /package/dist/lib/node-esm/{settings-67RVIH3N.mjs.map → settings-MK7D7LHQ.mjs.map} +0 -0
@@ -5,8 +5,10 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
+ import { Match, Option, pipe, Schema } from 'effect';
8
9
  import React, { type FC, useEffect, useMemo, useState } from 'react';
9
10
 
11
+ import { Message } from '@dxos/ai';
10
12
  import {
11
13
  Capabilities,
12
14
  CollaborationActions,
@@ -18,8 +20,8 @@ import {
18
20
  useIntentDispatcher,
19
21
  } from '@dxos/app-framework';
20
22
  import { withPluginManager } from '@dxos/app-framework/testing';
21
- import { Message } from '@dxos/artifact';
22
- import { S, AST, create, type Expando, EchoObject } from '@dxos/echo-schema';
23
+ import { Type } from '@dxos/echo';
24
+ import { create, createQueueDxn, type Expando } from '@dxos/echo-schema';
23
25
  import { invariant } from '@dxos/invariant';
24
26
  import { DXN } from '@dxos/keys';
25
27
  import { live, makeRef, refFromDXN } from '@dxos/live-object';
@@ -29,9 +31,9 @@ import { SpacePlugin } from '@dxos/plugin-space';
29
31
  import { StorybookLayoutPlugin } from '@dxos/plugin-storybook-layout';
30
32
  import { ThemePlugin } from '@dxos/plugin-theme';
31
33
  import { faker } from '@dxos/random';
32
- import { createQueueDxn, useQueue, useSpace } from '@dxos/react-client/echo';
34
+ import { createDocAccessor, fullyQualifiedId, toCursorRange, useQueue, useSpace } from '@dxos/react-client/echo';
33
35
  import { IconButton, Toolbar } from '@dxos/react-ui';
34
- import { command, useTextEditor } from '@dxos/react-ui-editor';
36
+ import { command, type EditorSelection, type Range, useTextEditor } from '@dxos/react-ui-editor';
35
37
  import { StackItem } from '@dxos/react-ui-stack';
36
38
  import { defaultTx } from '@dxos/react-ui-theme';
37
39
  import { withLayout } from '@dxos/storybook-utils';
@@ -45,50 +47,66 @@ import { createDocument, DocumentType, type MarkdownSettingsProps } from '../typ
45
47
 
46
48
  faker.seed(1);
47
49
 
48
- const TestItem = S.Struct({
49
- title: S.String.annotations({
50
- [AST.TitleAnnotationId]: 'Title',
51
- [AST.DescriptionAnnotationId]: 'Product title',
50
+ const TestItem = Schema.Struct({
51
+ title: Schema.String.annotations({
52
+ title: 'Title',
53
+ description: 'Product title',
52
54
  }),
53
- description: S.String.annotations({
54
- [AST.TitleAnnotationId]: 'Description',
55
- [AST.DescriptionAnnotationId]: 'Product description',
55
+ description: Schema.String.annotations({
56
+ title: 'Description',
57
+ description: 'Product description',
56
58
  }),
57
- }).pipe(EchoObject({ typename: 'dxos.org/type/Test', version: '0.1.0' }));
59
+ }).pipe(
60
+ Type.Obj({
61
+ typename: 'dxos.org/type/Test',
62
+ version: '0.1.0',
63
+ }),
64
+ );
58
65
 
59
66
  const TestChat: FC<{ doc: DocumentType; content: string }> = ({ doc, content }) => {
60
67
  const { dispatchPromise: dispatch } = useIntentDispatcher();
61
68
  const { parentRef } = useTextEditor({ initialValue: content });
69
+ const { editorState } = useCapability(MarkdownCapabilities.State);
62
70
 
63
71
  const space = useSpace();
64
72
  const queueDxn = useMemo(() => space && createQueueDxn(space.id), [space]);
65
73
  const queue = useQueue<Message>(queueDxn);
66
74
 
67
- const handleInsert = () => {
75
+ const handleInsert = async () => {
68
76
  invariant(space);
69
77
  invariant(queue);
70
78
  queue.append([create(Message, { role: 'assistant', content: [{ type: 'text', text: 'Hello' }] })]);
71
- const message = queue.items[queue.items.length - 1];
79
+ const message = queue.objects.at(-1);
80
+ invariant(message);
81
+
82
+ const text = await doc.content.load();
83
+ const accessor = createDocAccessor(text, ['content']);
84
+ const cursor = pipe(
85
+ editorState.getState(fullyQualifiedId(doc))?.selection,
86
+ Option.fromNullable,
87
+ Option.map(selectionToRange),
88
+ Option.map((range) => toCursorRange(accessor, range.from, range.to)),
89
+ Option.getOrUndefined,
90
+ );
72
91
 
73
92
  // {
74
93
  // const ref = refFromDXN(new DXN(DXN.kind.QUEUE, [...queue.dxn.parts, message.id]));
75
-
76
94
  // const message = deref(ref);
77
95
  // }
78
96
 
79
97
  void dispatch(
80
98
  createIntent(CollaborationActions.InsertContent, {
81
- spaceId: space.id,
82
- target: makeRef(doc as any as Expando), // TODO(burdon): Comomon base type.
99
+ target: doc as any as Expando, // TODO(burdon): Common base type.
83
100
  object: refFromDXN(new DXN(DXN.kind.QUEUE, [...queue.dxn.parts, message.id])),
101
+ at: cursor,
84
102
  label: 'Proposal',
85
103
  }),
86
104
  );
87
105
  };
88
106
 
89
107
  return (
90
- <StackItem.Content toolbar classNames='w-full'>
91
- <Toolbar.Root classNames='border-be border-separator'>
108
+ <StackItem.Content toolbar>
109
+ <Toolbar.Root>
92
110
  <IconButton icon='ph--plus--regular' disabled={!queue} label='Insert' onClick={handleInsert} />
93
111
  </Toolbar.Root>
94
112
  <div ref={parentRef} className='p-4' />
@@ -100,6 +118,7 @@ const DefaultStory = ({ document, chat }: { document: string; chat: string }) =>
100
118
  const space = useSpace();
101
119
  const [doc, setDoc] = useState<DocumentType>();
102
120
  const settings = useCapability(Capabilities.SettingsStore).getStore<MarkdownSettingsProps>(MARKDOWN_PLUGIN)!.value;
121
+ const { editorState } = useCapability(MarkdownCapabilities.State);
103
122
 
104
123
  useEffect(() => {
105
124
  if (!space) {
@@ -128,7 +147,7 @@ const DefaultStory = ({ document, chat }: { document: string; chat: string }) =>
128
147
 
129
148
  return (
130
149
  <>
131
- <MarkdownContainer id={doc.id} object={doc} settings={settings} />
150
+ <MarkdownContainer id={doc.id} object={doc} settings={settings} editorStateStore={editorState} />
132
151
  <TestChat doc={doc} content={chat} />
133
152
  </>
134
153
  );
@@ -156,7 +175,7 @@ const meta: Meta<typeof DefaultStory> = {
156
175
  ],
157
176
  capabilities: [contributes(MarkdownCapabilities.Extensions, [() => command()])],
158
177
  }),
159
- withLayout({ tooltips: true, fullscreen: true, classNames: 'grid grid-cols-2' }),
178
+ withLayout({ fullscreen: true, classNames: 'grid grid-cols-2' }),
160
179
  ],
161
180
  parameters: {
162
181
  translations,
@@ -182,3 +201,16 @@ export const Default: Story = {
182
201
  ].join('\n'),
183
202
  },
184
203
  };
204
+
205
+ // TODO(wittjosiah): Factor out.
206
+ const selectionToRange = Match.type<EditorSelection>().pipe(
207
+ Match.when(
208
+ ({ head, anchor }) => (head ? head > anchor : false),
209
+ ({ head, anchor }) => ({ from: anchor, to: head! }) as Range,
210
+ ),
211
+ Match.when(
212
+ ({ head, anchor }) => (head ? head < anchor : false),
213
+ ({ head, anchor }) => ({ from: head!, to: anchor }) as Range,
214
+ ),
215
+ Match.orElse(({ anchor }) => ({ from: anchor, to: anchor }) as Range),
216
+ );
@@ -5,8 +5,9 @@
5
5
  import '@dxos-theme';
6
6
 
7
7
  import { type Meta } from '@storybook/react';
8
- import React, { type FC, useState } from 'react';
8
+ import React, { type FC, useCallback, useState } from 'react';
9
9
 
10
+ import { invariant } from '@dxos/invariant';
10
11
  import { PublicKey } from '@dxos/keys';
11
12
  import { live } from '@dxos/live-object';
12
13
  import { faker } from '@dxos/random';
@@ -14,7 +15,6 @@ import { createDocAccessor, createObject } from '@dxos/react-client/echo';
14
15
  import { useThemeContext } from '@dxos/react-ui';
15
16
  import {
16
17
  EditorToolbar,
17
- type EditorAction,
18
18
  type Comment,
19
19
  comments,
20
20
  createBasicExtensions,
@@ -22,23 +22,23 @@ import {
22
22
  createMarkdownExtensions,
23
23
  createThemeExtensions,
24
24
  decorateMarkdown,
25
- editorContent,
25
+ editorSlots,
26
26
  formattingKeymap,
27
27
  translations,
28
- useActionHandler,
29
28
  useComments,
30
29
  useFormattingState,
31
30
  useTextEditor,
32
31
  useEditorToolbarState,
32
+ type EditorViewMode,
33
33
  } from '@dxos/react-ui-editor';
34
- import { TextType } from '@dxos/schema';
34
+ import { DataType } from '@dxos/schema';
35
35
  import { withLayout, withTheme } from '@dxos/storybook-utils';
36
36
 
37
37
  faker.seed(101);
38
38
 
39
39
  const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
40
40
  const { themeMode } = useThemeContext();
41
- const [text] = useState(createObject(live(TextType, { content })));
41
+ const [text] = useState(createObject(live(DataType.Text, { content })));
42
42
  const toolbarState = useEditorToolbarState({ viewMode: 'preview' });
43
43
  const formattingObserver = useFormattingState(toolbarState);
44
44
  const { parentRef, view } = useTextEditor(() => {
@@ -49,7 +49,7 @@ const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
49
49
  formattingObserver,
50
50
  createBasicExtensions({ readOnly: toolbarState.viewMode === 'readonly' }),
51
51
  createMarkdownExtensions({ themeMode }),
52
- createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: { editor: { className: editorContent } } }),
52
+ createThemeExtensions({ themeMode, syntaxHighlighting: true, slots: editorSlots }),
53
53
  createDataExtensions({ id: text.id, text: createDocAccessor(text, ['content']) }),
54
54
  comments({
55
55
  onCreate: ({ cursor }) => {
@@ -64,21 +64,21 @@ const DefaultStory: FC<{ content?: string }> = ({ content = '' }) => {
64
64
  };
65
65
  }, [text, formattingObserver, toolbarState.viewMode, themeMode]);
66
66
 
67
- const handleToolbarAction = useActionHandler(view);
68
- const handleAction = (action: EditorAction) => {
69
- if (action.type === 'view-mode') {
70
- toolbarState.viewMode = action.properties.data;
71
- } else {
72
- handleToolbarAction?.(action);
73
- }
67
+ const handleViewModeChange = (viewMode: EditorViewMode) => {
68
+ toolbarState.viewMode = viewMode;
74
69
  };
75
70
 
71
+ const getView = useCallback(() => {
72
+ invariant(view);
73
+ return view;
74
+ }, [view]);
75
+
76
76
  const [_comments, setComments] = useState<Comment[]>([]);
77
77
  useComments(view, text.id, _comments);
78
78
 
79
79
  return (
80
80
  <div role='none' className='flex flex-col'>
81
- <EditorToolbar onAction={handleAction} state={toolbarState ?? {}} />
81
+ <EditorToolbar state={toolbarState ?? {}} getView={getView} viewMode={handleViewModeChange} />
82
82
  <div className='flex grow overflow-hidden' ref={parentRef} />
83
83
  </div>
84
84
  );
@@ -98,7 +98,7 @@ const meta: Meta<typeof EditorToolbar> = {
98
98
  title: 'plugins/plugin-markdown/Toolbar',
99
99
  component: EditorToolbar,
100
100
  render: DefaultStory as any,
101
- decorators: [withTheme, withLayout({ tooltips: true, fullscreen: true })],
101
+ decorators: [withTheme, withLayout({ fullscreen: true })],
102
102
  parameters: {
103
103
  translations,
104
104
  },
@@ -13,9 +13,10 @@ import {
13
13
  useIntentDispatcher,
14
14
  } from '@dxos/app-framework';
15
15
  import { invariant } from '@dxos/invariant';
16
- import { createDocAccessor, fullyQualifiedId, getSpace, type Query } from '@dxos/react-client/echo';
16
+ import { createDocAccessor, fullyQualifiedId, getSpace, type QueryResult } from '@dxos/react-client/echo';
17
17
  import { useIdentity } from '@dxos/react-client/halo';
18
18
  import { Icon, ThemeProvider } from '@dxos/react-ui';
19
+ import { type SelectionManager } from '@dxos/react-ui-attention';
19
20
  import {
20
21
  type AutocompleteResult,
21
22
  type EditorStateStore,
@@ -33,9 +34,12 @@ import {
33
34
  selectionState,
34
35
  typewriter,
35
36
  type RenderCallback,
37
+ EditorView,
38
+ documentId,
39
+ Cursor,
36
40
  } from '@dxos/react-ui-editor';
37
41
  import { defaultTx } from '@dxos/react-ui-theme';
38
- import { type TextType } from '@dxos/schema';
42
+ import { type DataType } from '@dxos/schema';
39
43
  import { isNotFalsy } from '@dxos/util';
40
44
 
41
45
  import { MarkdownCapabilities } from './capabilities';
@@ -45,10 +49,11 @@ import { setFallbackName } from './util';
45
49
  type ExtensionsOptions = {
46
50
  document?: DocumentType;
47
51
  id?: string;
48
- text?: TextType;
52
+ text?: DataType.Text;
49
53
  dispatch?: PromiseIntentDispatcher;
50
- query?: Query<DocumentType>;
54
+ query?: QueryResult<DocumentType>;
51
55
  settings: MarkdownSettingsProps;
56
+ selectionManager?: SelectionManager;
52
57
  viewMode?: EditorViewMode;
53
58
  editorStateStore?: EditorStateStore;
54
59
  };
@@ -59,6 +64,7 @@ export const useExtensions = ({
59
64
  id,
60
65
  text,
61
66
  settings,
67
+ selectionManager,
62
68
  viewMode,
63
69
  editorStateStore,
64
70
  }: ExtensionsOptions): Extension[] => {
@@ -68,7 +74,7 @@ export const useExtensions = ({
68
74
 
69
75
  // TODO(wittjosiah): Autocomplete is not working and this query is causing performance issues.
70
76
  // TODO(burdon): Unsubscribe.
71
- // const query = space?.db.query(Filter.schema(DocumentType));
77
+ // const query = space?.db.query(Filter.type(DocumentType));
72
78
  // query?.subscribe();
73
79
  const baseExtensions = useMemo(
74
80
  () =>
@@ -77,6 +83,7 @@ export const useExtensions = ({
77
83
  id,
78
84
  text,
79
85
  settings,
86
+ selectionManager,
80
87
  viewMode,
81
88
  dispatch,
82
89
  // query,
@@ -93,6 +100,7 @@ export const useExtensions = ({
93
100
  settings.numberedHeadings,
94
101
  settings.debug,
95
102
  settings.typewriter,
103
+ selectionManager,
96
104
  ],
97
105
  );
98
106
 
@@ -101,18 +109,20 @@ export const useExtensions = ({
101
109
  //
102
110
  // External extensions from other plugins.
103
111
  //
104
- const pluginExtensions = useMemo<Extension[] | undefined>(
105
- () =>
106
- extensionProviders.flat().reduce((acc: Extension[], provider) => {
107
- const extension = typeof provider === 'function' ? provider({ document }) : provider;
108
- if (extension) {
109
- acc.push(extension);
110
- }
112
+ const pluginExtensions = useMemo<Extension[]>(() => {
113
+ if (!document) {
114
+ return [];
115
+ }
111
116
 
112
- return acc;
113
- }, []),
114
- [extensionProviders, document],
115
- );
117
+ return extensionProviders.flat().reduce((acc: Extension[], provider) => {
118
+ const extension = typeof provider === 'function' ? provider({ document }) : provider;
119
+ if (extension) {
120
+ acc.push(extension);
121
+ }
122
+
123
+ return acc;
124
+ }, []);
125
+ }, [extensionProviders, document]);
116
126
 
117
127
  //
118
128
  // Basic plugins.
@@ -156,10 +166,12 @@ const createBaseExtensions = ({
156
166
  id,
157
167
  dispatch,
158
168
  settings,
169
+ selectionManager,
159
170
  query,
160
171
  viewMode,
161
172
  }: ExtensionsOptions): Extension[] => {
162
173
  const extensions: Extension[] = [
174
+ selectionManager && selectionChange(selectionManager),
163
175
  settings.editorInputMode && InputModeExtensions[settings.editorInputMode],
164
176
  settings.folding && folding(),
165
177
  ].filter(isNotFalsy);
@@ -230,6 +242,23 @@ const createBaseExtensions = ({
230
242
  return extensions;
231
243
  };
232
244
 
245
+ export const selectionChange = (selectionManager: SelectionManager) => {
246
+ return EditorView.updateListener.of((update) => {
247
+ if (update.selectionSet) {
248
+ const id = update.state.facet(documentId);
249
+ const cursorConverter = update.state.facet(Cursor.converter);
250
+ const selection = update.state.selection;
251
+ const ranges = selection.ranges
252
+ .map((range) => ({
253
+ from: cursorConverter.toCursor(range.from),
254
+ to: cursorConverter.toCursor(range.to),
255
+ }))
256
+ .filter(({ from, to }) => to > from);
257
+ selectionManager.updateMultiRange(id, ranges);
258
+ }
259
+ });
260
+ };
261
+
233
262
  // TODO(burdon): Factor out styles.
234
263
  const style = {
235
264
  hover: 'rounded-sm text-primary-500 hover:text-primary-600 dark:text-primary-500 hover:dark:text-primary-400',
@@ -3,10 +3,10 @@
3
3
  //
4
4
 
5
5
  import { EditorView } from '@codemirror/view';
6
+ import { Schema } from 'effect';
6
7
  import { useMemo } from 'react';
7
8
 
8
9
  import { createResolver, LayoutAction, useIntentResolver } from '@dxos/app-framework';
9
- import { S } from '@dxos/echo-schema';
10
10
  import { invariant } from '@dxos/invariant';
11
11
  import { Cursor, setSelection } from '@dxos/react-ui-editor';
12
12
 
@@ -22,7 +22,7 @@ export const useSelectCurrentThread = (editorView: EditorView | undefined, docum
22
22
  intent: LayoutAction.UpdateLayout,
23
23
  position: 'hoist',
24
24
  filter: (data): data is { part: 'current'; subject: string; options: { cursor: string } } => {
25
- if (!S.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
25
+ if (!Schema.is(LayoutAction.ScrollIntoView.fields.input)(data)) {
26
26
  return false;
27
27
  }
28
28
 
@@ -2,15 +2,13 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { getSchemaTypename } from '@dxos/echo-schema';
6
-
7
5
  import { MARKDOWN_PLUGIN } from './meta';
8
6
  import { DocumentType } from './types';
9
7
 
10
8
  export default [
11
9
  {
12
10
  'en-US': {
13
- [getSchemaTypename(DocumentType)!]: {
11
+ [DocumentType.typename]: {
14
12
  'typename label': 'Document',
15
13
  'object name placeholder': 'New document',
16
14
  },
@@ -2,28 +2,30 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { EchoObject, Expando, LabelAnnotationId, Ref, S } from '@dxos/echo-schema';
6
- import { makeRef, live } from '@dxos/live-object';
7
- import { ThreadType } from '@dxos/plugin-space/types';
8
- import { TextType } from '@dxos/schema';
5
+ import { Schema } from 'effect';
9
6
 
10
- export const DocumentSchema = S.Struct({
11
- name: S.optional(S.String),
12
- fallbackName: S.optional(S.String),
13
- content: Ref(TextType),
14
- threads: S.mutable(S.Array(Ref(ThreadType))),
15
- assistantChatQueue: S.optional(Ref(Expando)),
16
- }).annotations({
17
- // TODO(dmaretskyi): `S.Struct(...).pipe(defaultLabel(['name', 'fallbackName']))` for type-safe annotations.
18
- [LabelAnnotationId]: ['name', 'fallbackName'],
19
- });
7
+ import { Type, Ref } from '@dxos/echo';
8
+ import { LabelAnnotation } from '@dxos/echo-schema';
9
+ import { live } from '@dxos/live-object';
10
+ import { DataType } from '@dxos/schema';
20
11
 
21
- export const DocumentType = DocumentSchema.pipe(EchoObject({ typename: 'dxos.org/type/Document', version: '0.1.0' }));
22
- export type DocumentType = S.Schema.Type<typeof DocumentType>;
12
+ export const DocumentSchema = Schema.Struct({
13
+ name: Schema.optional(Schema.String),
14
+ fallbackName: Schema.optional(Schema.String),
15
+ content: Type.Ref(DataType.Text),
16
+ }).pipe(LabelAnnotation.set(['name', 'fallbackName']));
17
+
18
+ export const DocumentType = DocumentSchema.pipe(
19
+ Type.Obj({
20
+ typename: 'dxos.org/type/Document',
21
+ version: '0.1.0',
22
+ }),
23
+ );
24
+ export type DocumentType = Schema.Schema.Type<typeof DocumentType>;
23
25
 
24
26
  // TODO(burdon): Replace when defaults are supported.
25
27
  export const createDocument = ({ name, content }: { name: string; content: string }) =>
26
- live(DocumentType, { name, content: makeRef(live(TextType, { content })), threads: [] });
28
+ live(DocumentType, { name, content: Ref.make(live(DataType.Text, { content })) });
27
29
 
28
30
  /**
29
31
  * Checks if an object conforms to the interface needed to render an editor.
@@ -2,7 +2,9 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { S } from '@dxos/echo-schema';
5
+ import { Schema } from 'effect';
6
+
7
+ import { Type } from '@dxos/echo';
6
8
  // TODO(wittjosiah): This pulls in UI code into the types entrypoint.
7
9
  import { type Extension, EditorInputMode, EditorViewMode } from '@dxos/react-ui-editor';
8
10
 
@@ -12,23 +14,23 @@ import { MARKDOWN_PLUGIN } from '../meta';
12
14
  const MARKDOWN_ACTION = `${MARKDOWN_PLUGIN}/action`;
13
15
 
14
16
  export namespace MarkdownAction {
15
- export class Create extends S.TaggedClass<Create>()(MARKDOWN_ACTION, {
16
- input: S.Struct({
17
- spaceId: S.String,
18
- name: S.optional(S.String),
19
- content: S.optional(S.String),
17
+ export class Create extends Schema.TaggedClass<Create>()(MARKDOWN_ACTION, {
18
+ input: Schema.Struct({
19
+ spaceId: Type.SpaceId,
20
+ name: Schema.optional(Schema.String),
21
+ content: Schema.optional(Schema.String),
20
22
  }),
21
- output: S.Struct({
23
+ output: Schema.Struct({
22
24
  object: DocumentType,
23
25
  }),
24
26
  }) {}
25
27
 
26
- export class SetViewMode extends S.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
27
- input: S.Struct({
28
- id: S.String,
28
+ export class SetViewMode extends Schema.TaggedClass<SetViewMode>()(`${MARKDOWN_ACTION}/set-view-mode`, {
29
+ input: Schema.Struct({
30
+ id: Schema.String,
29
31
  viewMode: EditorViewMode,
30
32
  }),
31
- output: S.Void,
33
+ output: Schema.Void,
32
34
  }) {}
33
35
  }
34
36
 
@@ -48,18 +50,18 @@ export type MarkdownPluginState = {
48
50
  viewMode: Record<string, EditorViewMode>;
49
51
  };
50
52
 
51
- export const MarkdownSettingsSchema = S.mutable(
52
- S.Struct({
53
+ export const MarkdownSettingsSchema = Schema.mutable(
54
+ Schema.Struct({
53
55
  defaultViewMode: EditorViewMode,
54
- editorInputMode: S.optional(EditorInputMode),
55
- experimental: S.optional(S.Boolean),
56
- debug: S.optional(S.Boolean),
57
- toolbar: S.optional(S.Boolean),
58
- typewriter: S.optional(S.String),
56
+ editorInputMode: Schema.optional(EditorInputMode),
57
+ experimental: Schema.optional(Schema.Boolean),
58
+ debug: Schema.optional(Schema.Boolean),
59
+ toolbar: Schema.optional(Schema.Boolean),
60
+ typewriter: Schema.optional(Schema.String),
59
61
  // TODO(burdon): Per document settings.
60
- numberedHeadings: S.optional(S.Boolean),
61
- folding: S.optional(S.Boolean),
62
+ numberedHeadings: Schema.optional(Schema.Boolean),
63
+ folding: Schema.optional(Schema.Boolean),
62
64
  }),
63
65
  );
64
66
 
65
- export type MarkdownSettingsProps = S.Schema.Type<typeof MarkdownSettingsSchema>;
67
+ export type MarkdownSettingsProps = Schema.Schema.Type<typeof MarkdownSettingsSchema>;
package/src/util.tsx CHANGED
@@ -4,13 +4,13 @@
4
4
 
5
5
  import { debounce } from '@dxos/async';
6
6
  import { type TypedObjectSerializer } from '@dxos/plugin-space/types';
7
- import { live, createObject, isEchoObject, loadObjectReferences, makeRef } from '@dxos/react-client/echo';
8
- import { TextType } from '@dxos/schema';
7
+ import { live, createObject, isEchoObject, loadObjectReferences, Ref } from '@dxos/react-client/echo';
8
+ import { DataType } from '@dxos/schema';
9
9
 
10
10
  import { DocumentType, type MarkdownProperties } from './types';
11
11
 
12
12
  export const isMarkdownProperties = (data: unknown): data is MarkdownProperties =>
13
- isEchoObject(data)
13
+ (isEchoObject(data) as boolean)
14
14
  ? true
15
15
  : data && typeof data === 'object'
16
16
  ? 'title' in data && typeof data.title === 'string'
@@ -42,7 +42,7 @@ export const serializer: TypedObjectSerializer<DocumentType> = {
42
42
  deserialize: async ({ content: serialized }) => {
43
43
  const { name, fallbackName, content } = JSON.parse(serialized);
44
44
  return createObject(
45
- live(DocumentType, { name, fallbackName, content: makeRef(live(TextType, { content })), threads: [] }),
45
+ live(DocumentType, { name, fallbackName, content: Ref.make(live(DataType.Text, { content })) }),
46
46
  );
47
47
  },
48
48
  };