@dxos/plugin-thread 0.6.13-main.ed424a1 → 0.6.13

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 (95) hide show
  1. package/dist/lib/browser/{ThreadArticle-53PBPWLD.mjs → ThreadArticle-O64ZECMF.mjs} +3 -3
  2. package/dist/lib/browser/{ThreadMain-FZAZVPHO.mjs → ThreadMain-ZDCRC6RG.mjs} +3 -3
  3. package/dist/lib/browser/chunk-5IBJO53M.mjs +21 -0
  4. package/dist/lib/browser/chunk-5IBJO53M.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-JFQZ5W2I.mjs → chunk-GKPZHUT3.mjs} +2 -2
  6. package/dist/lib/browser/{chunk-JFQZ5W2I.mjs.map → chunk-GKPZHUT3.mjs.map} +1 -1
  7. package/dist/lib/browser/{chunk-DIFHKCVY.mjs → chunk-P7ZE5N5M.mjs} +11 -13
  8. package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +393 -411
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/meta.mjs +1 -1
  13. package/dist/lib/browser/types.mjs +2 -2
  14. package/dist/lib/node/{ThreadArticle-UORKW5YD.cjs → ThreadArticle-DO56JXBU.cjs} +7 -7
  15. package/dist/lib/node/{ThreadMain-FVSLLIWS.cjs → ThreadMain-XJX75GHG.cjs} +7 -7
  16. package/dist/lib/node/{chunk-FK2N2QH7.cjs → chunk-5PZNPPQF.cjs} +63 -65
  17. package/dist/lib/node/chunk-5PZNPPQF.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-JIJ7Z6NO.cjs → chunk-BWBONZGU.cjs} +22 -7
  19. package/dist/lib/node/chunk-BWBONZGU.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-FOZUQZF4.cjs → chunk-D5GOVXHS.cjs} +6 -6
  21. package/dist/lib/node/{chunk-FOZUQZF4.cjs.map → chunk-D5GOVXHS.cjs.map} +1 -1
  22. package/dist/lib/node/index.cjs +441 -455
  23. package/dist/lib/node/index.cjs.map +4 -4
  24. package/dist/lib/node/meta.cjs +4 -4
  25. package/dist/lib/node/meta.cjs.map +1 -1
  26. package/dist/lib/node/meta.json +1 -1
  27. package/dist/lib/node/types.cjs +3 -3
  28. package/dist/lib/node/types.cjs.map +1 -1
  29. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  30. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  31. package/dist/types/src/components/CommentContainer.d.ts +1 -1
  32. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  33. package/dist/types/src/components/CommentsContainer.d.ts +5 -1
  34. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  35. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  36. package/dist/types/src/components/index.d.ts +3 -4
  37. package/dist/types/src/components/index.d.ts.map +1 -1
  38. package/dist/types/src/components/testing.d.ts +0 -2
  39. package/dist/types/src/components/testing.d.ts.map +1 -1
  40. package/dist/types/src/components/types.d.ts +2 -2
  41. package/dist/types/src/components/types.d.ts.map +1 -1
  42. package/dist/types/src/meta.d.ts +9 -3
  43. package/dist/types/src/meta.d.ts.map +1 -1
  44. package/dist/types/src/types.d.ts +1 -6
  45. package/dist/types/src/types.d.ts.map +1 -1
  46. package/dist/types/src/types.test.d.ts +2 -0
  47. package/dist/types/src/types.test.d.ts.map +1 -0
  48. package/package.json +37 -40
  49. package/src/ThreadPlugin.tsx +310 -120
  50. package/src/components/ChatContainer.tsx +8 -7
  51. package/src/components/CommentContainer.tsx +19 -18
  52. package/src/components/Comments.stories.tsx +2 -2
  53. package/src/components/CommentsContainer.tsx +31 -18
  54. package/src/components/MessageContainer.tsx +3 -3
  55. package/src/components/index.ts +2 -3
  56. package/src/components/types.ts +2 -2
  57. package/src/meta.tsx +20 -0
  58. package/src/types.test.ts +13 -0
  59. package/src/types.ts +3 -8
  60. package/dist/lib/browser/chunk-5G3KL6TC.mjs +0 -16
  61. package/dist/lib/browser/chunk-5G3KL6TC.mjs.map +0 -7
  62. package/dist/lib/browser/chunk-DIFHKCVY.mjs.map +0 -7
  63. package/dist/lib/node/chunk-FK2N2QH7.cjs.map +0 -7
  64. package/dist/lib/node/chunk-JIJ7Z6NO.cjs.map +0 -7
  65. package/dist/lib/node-esm/ThreadArticle-E4MLJZIM.mjs +0 -19
  66. package/dist/lib/node-esm/ThreadArticle-E4MLJZIM.mjs.map +0 -7
  67. package/dist/lib/node-esm/ThreadMain-Y6JU6S7A.mjs +0 -27
  68. package/dist/lib/node-esm/ThreadMain-Y6JU6S7A.mjs.map +0 -7
  69. package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs +0 -18
  70. package/dist/lib/node-esm/chunk-DC5ZA6H5.mjs.map +0 -7
  71. package/dist/lib/node-esm/chunk-SJEUDBZV.mjs +0 -413
  72. package/dist/lib/node-esm/chunk-SJEUDBZV.mjs.map +0 -7
  73. package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs +0 -21
  74. package/dist/lib/node-esm/chunk-ZXIPFXSA.mjs.map +0 -7
  75. package/dist/lib/node-esm/index.mjs +0 -1121
  76. package/dist/lib/node-esm/index.mjs.map +0 -7
  77. package/dist/lib/node-esm/meta.json +0 -1
  78. package/dist/lib/node-esm/meta.mjs +0 -12
  79. package/dist/lib/node-esm/meta.mjs.map +0 -7
  80. package/dist/lib/node-esm/types.mjs +0 -9
  81. package/dist/lib/node-esm/types.mjs.map +0 -7
  82. package/dist/types/src/components/ThreadComplementary.d.ts +0 -10
  83. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  84. package/dist/types/src/extensions/index.d.ts +0 -2
  85. package/dist/types/src/extensions/index.d.ts.map +0 -1
  86. package/dist/types/src/extensions/threads.d.ts +0 -9
  87. package/dist/types/src/extensions/threads.d.ts.map +0 -1
  88. package/src/components/ThreadComplementary.tsx +0 -113
  89. package/src/extensions/index.ts +0 -5
  90. package/src/extensions/threads.ts +0 -117
  91. package/src/meta.ts +0 -15
  92. /package/dist/lib/browser/{ThreadArticle-53PBPWLD.mjs.map → ThreadArticle-O64ZECMF.mjs.map} +0 -0
  93. /package/dist/lib/browser/{ThreadMain-FZAZVPHO.mjs.map → ThreadMain-ZDCRC6RG.mjs.map} +0 -0
  94. /package/dist/lib/node/{ThreadArticle-UORKW5YD.cjs.map → ThreadArticle-DO56JXBU.cjs.map} +0 -0
  95. /package/dist/lib/node/{ThreadMain-FVSLLIWS.cjs.map → ThreadMain-XJX75GHG.cjs.map} +0 -0
@@ -1,1121 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- ThreadAction
4
- } from "./chunk-ZXIPFXSA.mjs";
5
- import {
6
- ChatContainer,
7
- ChatHeading,
8
- MessageContainer,
9
- command,
10
- getMessageMetadata,
11
- useAnalyticsCallback,
12
- useOnEditAnalytics,
13
- useStatus
14
- } from "./chunk-SJEUDBZV.mjs";
15
- import {
16
- THREAD_ITEM,
17
- THREAD_PLUGIN,
18
- meta_default
19
- } from "./chunk-DC5ZA6H5.mjs";
20
-
21
- // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
22
- import React6 from "react";
23
- import { NavigationAction, isLayoutParts, parseIntentPlugin, parseNavigationPlugin, parseMetadataResolverPlugin, resolvePlugin } from "@dxos/app-framework";
24
- import { LocalStorageStore } from "@dxos/local-storage";
25
- import { log } from "@dxos/log";
26
- import { parseClientPlugin } from "@dxos/plugin-client";
27
- import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
28
- import { ObservabilityAction } from "@dxos/plugin-observability/meta";
29
- import { SpaceAction } from "@dxos/plugin-space";
30
- import { ThreadType as ThreadType2, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
31
- import { create as create2, getTypename } from "@dxos/react-client/echo";
32
- import { getSpace as getSpace3, fullyQualifiedId as fullyQualifiedId5, loadObjectReferences, parseFullyQualifiedId } from "@dxos/react-client/echo";
33
- import { translations as threadTranslations } from "@dxos/react-ui-thread";
34
-
35
- // packages/plugins/plugin-thread/src/components/index.ts
36
- import React5 from "react";
37
-
38
- // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
39
- import { CheckCircle, X } from "@phosphor-icons/react";
40
- import React, { useCallback, useMemo, useRef, useState } from "react";
41
- import { create } from "@dxos/echo-schema";
42
- import { MessageType } from "@dxos/plugin-space/types";
43
- import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
44
- import { useIdentity } from "@dxos/react-client/halo";
45
- import { Button, Tag, Tooltip, useThemeContext, useTranslation } from "@dxos/react-ui";
46
- import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
47
- import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
48
- import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
49
- import { nonNullable } from "@dxos/util";
50
- var sizeClass = getSize(4);
51
- var ToggleResolvedButton = ({ isResolved, onResolve }) => {
52
- const { t } = useTranslation(THREAD_PLUGIN);
53
- const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
54
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
55
- asChild: true
56
- }, /* @__PURE__ */ React.createElement(Button, {
57
- variant: "ghost",
58
- "data-testid": "thread.toggle-resolved",
59
- onClick: onResolve,
60
- classNames: [
61
- "min-bs-0 p-1",
62
- !isResolved && hoverableControlItem
63
- ]
64
- }, /* @__PURE__ */ React.createElement("span", {
65
- className: "sr-only"
66
- }, label), isResolved ? /* @__PURE__ */ React.createElement(CheckCircle, {
67
- className: sizeClass,
68
- weight: "fill"
69
- }) : /* @__PURE__ */ React.createElement(CheckCircle, {
70
- className: sizeClass
71
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
72
- classNames: "z-[21]"
73
- }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
74
- };
75
- var DeleteThreadButton = ({ onDelete }) => {
76
- const { t } = useTranslation(THREAD_PLUGIN);
77
- const label = t("delete thread label");
78
- return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
79
- asChild: true
80
- }, /* @__PURE__ */ React.createElement(Button, {
81
- variant: "ghost",
82
- "data-testid": "thread.delete",
83
- onClick: onDelete,
84
- classNames: [
85
- "min-bs-0 p-1",
86
- hoverableControlItem
87
- ]
88
- }, /* @__PURE__ */ React.createElement("span", {
89
- className: "sr-only"
90
- }, label), /* @__PURE__ */ React.createElement(X, {
91
- className: sizeClass
92
- }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
93
- classNames: "z-[21]"
94
- }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
95
- };
96
- var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
97
- const identity = useIdentity();
98
- const space = getSpace(thread);
99
- const members = useMembers(space?.key);
100
- const activity = useStatus(space, fullyQualifiedId(thread));
101
- const { t } = useTranslation(THREAD_PLUGIN);
102
- const threadScrollRef = useRef(null);
103
- const { themeMode } = useThemeContext();
104
- const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
105
- const [_count, _setCount] = useState(0);
106
- const rerenderEditor = () => _setCount((count) => count + 1);
107
- const messageRef = useRef("");
108
- const extensions = useMemo(() => [
109
- createBasicExtensions({
110
- placeholder: t("message placeholder")
111
- }),
112
- createThemeExtensions({
113
- themeMode
114
- }),
115
- listener({
116
- onChange: (text) => messageRef.current = text
117
- }),
118
- command
119
- ], [
120
- _count
121
- ]);
122
- const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
123
- behavior,
124
- block: "end"
125
- }), 10);
126
- const handleCreate = useCallback(() => {
127
- if (!messageRef.current) {
128
- return false;
129
- }
130
- thread.messages.push(create(MessageType, {
131
- sender: {
132
- identityKey: identity.identityKey.toHex()
133
- },
134
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135
- text: messageRef.current,
136
- context
137
- }));
138
- onComment?.(thread);
139
- messageRef.current = "";
140
- scrollToEnd("instant");
141
- rerenderEditor();
142
- return true;
143
- }, [
144
- thread,
145
- identity
146
- ]);
147
- return /* @__PURE__ */ React.createElement(Thread, {
148
- onClickCapture: onAttend,
149
- onFocusCapture: onAttend,
150
- current,
151
- id: fullyQualifiedId(thread)
152
- }, /* @__PURE__ */ React.createElement("div", {
153
- role: "none",
154
- className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
155
- }, detached ? /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
156
- asChild: true
157
- }, /* @__PURE__ */ React.createElement(ThreadHeading, {
158
- detached: true
159
- }, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
160
- classNames: "z-[21]",
161
- side: "top"
162
- }, t("detached thread label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React.createElement(ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ React.createElement("div", {
163
- className: "flex flex-row items-center pli-1"
164
- }, thread.status === "staged" && /* @__PURE__ */ React.createElement(Tag, {
165
- palette: "neutral"
166
- }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React.createElement(ToggleResolvedButton, {
167
- isResolved: thread?.status === "resolved",
168
- onResolve
169
- }), onThreadDelete && /* @__PURE__ */ React.createElement(DeleteThreadButton, {
170
- onDelete: onThreadDelete
171
- }))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
172
- key: message.id,
173
- message,
174
- members,
175
- onDelete: (id) => onMessageDelete?.(id)
176
- })), /* @__PURE__ */ React.createElement(MessageTextbox, {
177
- extensions,
178
- onSend: handleCreate,
179
- ...textboxMetadata
180
- }), /* @__PURE__ */ React.createElement(ThreadFooter, {
181
- activity
182
- }, t("activity message")), /* @__PURE__ */ React.createElement("div", {
183
- role: "none",
184
- className: "bs-px -mbs-px",
185
- ref: threadScrollRef
186
- }));
187
- };
188
-
189
- // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
190
- import { ChatText } from "@phosphor-icons/react";
191
- import React2, { useEffect } from "react";
192
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
193
- import { useTranslation as useTranslation2, Trans } from "@dxos/react-ui";
194
- import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
195
- var CommentsContainer = ({ threads: threads2, detached = [], currentId, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
196
- const { t } = useTranslation2(THREAD_PLUGIN);
197
- const filteredThreads = showResolvedThreads ? threads2 : threads2.filter((thread) => !(thread?.status === "resolved"));
198
- useEffect(() => {
199
- if (currentId) {
200
- document.getElementById(currentId)?.scrollIntoView({
201
- behavior: "smooth",
202
- block: "end"
203
- });
204
- }
205
- }, [
206
- currentId
207
- ]);
208
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
209
- const threadId = fullyQualifiedId2(thread);
210
- return /* @__PURE__ */ React2.createElement(CommentContainer, {
211
- key: threadId,
212
- thread,
213
- current: currentId === threadId,
214
- detached: detached.includes(threadId),
215
- ...onThreadAttend && {
216
- onAttend: () => onThreadAttend(thread)
217
- },
218
- ...onThreadDelete && {
219
- onThreadDelete: () => onThreadDelete(thread)
220
- },
221
- ...onMessageDelete && {
222
- onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
223
- },
224
- ...onThreadToggleResolved && {
225
- onResolve: () => onThreadToggleResolved(thread)
226
- },
227
- ...props
228
- });
229
- }) : /* @__PURE__ */ React2.createElement("div", {
230
- role: "alert",
231
- className: mx2(descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
232
- }, /* @__PURE__ */ React2.createElement("h2", {
233
- className: "mbe-2 font-medium text-baseText"
234
- }, t("no comments title")), /* @__PURE__ */ React2.createElement("p", null, /* @__PURE__ */ React2.createElement(Trans, {
235
- t,
236
- i18nKey: "no comments message",
237
- components: {
238
- commentIcon: /* @__PURE__ */ React2.createElement(ChatText, {
239
- className: "inline-block"
240
- })
241
- }
242
- }))));
243
- };
244
-
245
- // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
246
- import React3, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
247
- import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
248
- import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
249
- import { ScrollArea } from "@dxos/react-ui";
250
- import { useAttended } from "@dxos/react-ui-attention";
251
- import { nonNullable as nonNullable2 } from "@dxos/util";
252
- var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
253
- var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads }) => {
254
- const dispatch = useIntentDispatcher();
255
- const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
256
- const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
257
- threadsIntegrators
258
- ]);
259
- const createSort = useMemo2(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
260
- threadProvides,
261
- subject
262
- ]);
263
- const sort = useMemo2(() => createSort?.(subject), [
264
- createSort,
265
- subject
266
- ]);
267
- const threads2 = useMemo2(() => {
268
- return subject.threads.concat(drafts ?? []).filter(nonNullable2);
269
- }, [
270
- JSON.stringify(subject.threads),
271
- JSON.stringify(drafts)
272
- ]);
273
- const detachedIds = useMemo2(() => {
274
- return threads2.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
275
- }, [
276
- threads2
277
- ]);
278
- useEffect2(() => {
279
- if (!sort) {
280
- return;
281
- }
282
- threads2.sort((a, b) => sort(a?.anchor, b?.anchor));
283
- }, [
284
- sort,
285
- threads2
286
- ]);
287
- const attended = useAttended();
288
- const qualifiedSubjectId = fullyQualifiedId3(subject);
289
- return /* @__PURE__ */ React3.createElement("div", {
290
- role: "none",
291
- className: "contents"
292
- }, /* @__PURE__ */ React3.createElement(ScrollArea.Root, {
293
- classNames: "row-span-2"
294
- }, /* @__PURE__ */ React3.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React3.createElement(CommentsContainer, {
295
- threads: threads2,
296
- detached: detachedIds,
297
- currentId: attended.includes(qualifiedSubjectId) ? current : void 0,
298
- showResolvedThreads,
299
- onThreadAttend: (thread) => {
300
- const threadId = fullyQualifiedId3(thread);
301
- if (current !== threadId) {
302
- current = threadId;
303
- void dispatch?.([
304
- {
305
- action: LayoutAction.SCROLL_INTO_VIEW,
306
- data: {
307
- id: fullyQualifiedId3(subject),
308
- thread: threadId,
309
- cursor: thread.anchor
310
- }
311
- }
312
- ]);
313
- }
314
- },
315
- onThreadDelete: (thread) => {
316
- return dispatch({
317
- plugin: THREAD_PLUGIN,
318
- action: ThreadAction.DELETE,
319
- data: {
320
- subject,
321
- thread
322
- }
323
- });
324
- },
325
- onMessageDelete: (thread, messageId) => dispatch({
326
- plugin: THREAD_PLUGIN,
327
- action: ThreadAction.DELETE_MESSAGE,
328
- data: {
329
- subject,
330
- thread,
331
- messageId
332
- }
333
- }),
334
- onThreadToggleResolved: (thread) => dispatch({
335
- plugin: THREAD_PLUGIN,
336
- action: ThreadAction.TOGGLE_RESOLVED,
337
- data: {
338
- thread
339
- }
340
- }),
341
- onComment: (thread) => {
342
- void dispatch({
343
- action: ThreadAction.ON_MESSAGE_ADD,
344
- data: {
345
- thread,
346
- subject
347
- }
348
- });
349
- }
350
- }), /* @__PURE__ */ React3.createElement("div", {
351
- role: "none",
352
- className: "bs-10"
353
- }), /* @__PURE__ */ React3.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React3.createElement(ScrollArea.Thumb, null)))));
354
- };
355
-
356
- // packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
357
- import React4 from "react";
358
- import { SettingsValue } from "@dxos/plugin-settings";
359
- import { Input, useTranslation as useTranslation3 } from "@dxos/react-ui";
360
- var ThreadSettings = ({ settings }) => {
361
- const { t } = useTranslation3(THREAD_PLUGIN);
362
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(SettingsValue, {
363
- label: t("settings standalone label")
364
- }, /* @__PURE__ */ React4.createElement(Input.Switch, {
365
- checked: settings.standalone,
366
- onCheckedChange: (checked) => settings.standalone = !!checked
367
- })));
368
- };
369
-
370
- // packages/plugins/plugin-thread/src/components/index.ts
371
- var ThreadMain = React5.lazy(() => import("./ThreadMain-Y6JU6S7A.mjs"));
372
- var ThreadArticle = React5.lazy(() => import("./ThreadArticle-E4MLJZIM.mjs"));
373
-
374
- // packages/plugins/plugin-thread/src/extensions/threads.ts
375
- import { EditorView } from "@codemirror/view";
376
- import { computed, effect } from "@preact/signals-core";
377
- import { ThreadType } from "@dxos/plugin-space/types";
378
- import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
379
- import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
380
- import { nonNullable as nonNullable3 } from "@dxos/util";
381
- var getName = (doc, anchor) => {
382
- if (doc.content) {
383
- const [start, end] = anchor.split(":");
384
- return getTextInRange(createDocAccessor(doc.content, [
385
- "content"
386
- ]), start, end);
387
- }
388
- };
389
- var threads = (state, doc, dispatch) => {
390
- const space = doc && getSpace2(doc);
391
- if (!doc || !space || !dispatch) {
392
- return [
393
- comments()
394
- ];
395
- }
396
- const threads2 = computed(() => [
397
- ...doc.threads.filter(nonNullable3),
398
- ...state.drafts[fullyQualifiedId4(doc)] ?? []
399
- ].filter((thread) => !(thread?.status === "resolved")));
400
- return [
401
- EditorView.updateListener.of((update) => {
402
- if (update.docChanged) {
403
- doc.threads.forEach((thread) => {
404
- if (thread?.anchor) {
405
- const name = getName(doc, thread.anchor);
406
- if (name && name !== thread.name) {
407
- thread.name = name;
408
- }
409
- }
410
- });
411
- }
412
- }),
413
- createExternalCommentSync(fullyQualifiedId4(doc), (sink) => effect(() => sink()), () => threads2.value.filter((thread) => thread?.anchor).map((thread) => ({
414
- id: fullyQualifiedId4(thread),
415
- cursor: thread.anchor
416
- }))),
417
- comments({
418
- id: fullyQualifiedId4(doc),
419
- onCreate: ({ cursor }) => {
420
- const name = getName(doc, cursor);
421
- void dispatch({
422
- action: ThreadAction.CREATE,
423
- data: {
424
- cursor,
425
- name,
426
- subject: doc
427
- }
428
- });
429
- },
430
- onDelete: ({ id }) => {
431
- const draft = state.drafts[fullyQualifiedId4(doc)];
432
- if (draft) {
433
- const index = draft.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
434
- if (index !== -1) {
435
- draft.splice(index, 1);
436
- }
437
- }
438
- const thread = doc.threads.find((thread2) => thread2?.id === id);
439
- if (thread) {
440
- thread.anchor = void 0;
441
- }
442
- },
443
- onUpdate: ({ id, cursor }) => {
444
- const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
445
- if (thread instanceof ThreadType && thread.anchor) {
446
- thread.name = getName(doc, thread.anchor);
447
- thread.anchor = cursor;
448
- }
449
- },
450
- onSelect: ({ selection: { current, closest } }) => {
451
- void dispatch({
452
- action: ThreadAction.SELECT,
453
- data: {
454
- current: current ?? closest,
455
- skipOpen: true
456
- }
457
- });
458
- }
459
- })
460
- ];
461
- };
462
-
463
- // packages/plugins/plugin-thread/src/translations.ts
464
- var translations_default = [
465
- {
466
- "en-US": {
467
- [THREAD_PLUGIN]: {
468
- "plugin name": "Threads",
469
- "channel name placeholder": "New channel",
470
- "channel title label": "Title",
471
- "delete channel label": "Delete channel",
472
- "create channel label": "Create channel",
473
- "message placeholder": "Reply\u2026",
474
- "settings standalone label": "Enable channel creation (experimental)",
475
- "activity message": "Processing\u2026",
476
- "anonymous label": "Anonymous",
477
- "delete message block label": "Delete message block",
478
- "detached thread label": "Referenced content was removed",
479
- "delete thread label": "Delete thread",
480
- "thread deleted label": "You deleted a thread.",
481
- "message deleted label": "You deleted a message.",
482
- "comments heading": "Comments",
483
- "chat heading": "Chat",
484
- "draft button": "DRAFT",
485
- "no comments title": "No comments (yet)",
486
- "no comments message": "To start a comment thread, select a range of text in a document and click the <commentIcon></commentIcon> Create comment button in the toolbar.",
487
- "toggle show resolved": "Show resolved",
488
- "unnamed object threads label": "Threads",
489
- "mark as resolved label": "Mark as resolved",
490
- "mark as unresolved label": "Mark as unresolved",
491
- "save message label": "Save",
492
- "edit message label": "Edit",
493
- "delete message label": "Delete message"
494
- }
495
- }
496
- }
497
- ];
498
-
499
- // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
500
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
501
- var initialViewState = {
502
- showResolvedThreads: false
503
- };
504
- var ThreadPlugin = () => {
505
- const settings = new LocalStorageStore(THREAD_PLUGIN);
506
- const state = create2({
507
- drafts: {}
508
- });
509
- const viewStore = create2({});
510
- const getViewState = (subjectId) => {
511
- if (!viewStore[subjectId]) {
512
- viewStore[subjectId] = {
513
- ...initialViewState
514
- };
515
- }
516
- return viewStore[subjectId];
517
- };
518
- let navigationPlugin;
519
- let intentPlugin;
520
- const unsubscribeCallbacks = [];
521
- return {
522
- meta: meta_default,
523
- ready: async (plugins) => {
524
- settings.prop({
525
- key: "standalone",
526
- type: LocalStorageStore.bool({
527
- allowUndefined: true
528
- })
529
- });
530
- navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
531
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
532
- },
533
- unload: async () => {
534
- unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
535
- },
536
- provides: {
537
- settings: settings.values,
538
- metadata: {
539
- records: {
540
- [ChannelType.typename]: {
541
- placeholder: [
542
- "channel title placeholder",
543
- {
544
- ns: THREAD_PLUGIN
545
- }
546
- ],
547
- icon: "ph--chat--regular",
548
- // TODO(wittjosiah): Move out of metadata.
549
- loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
550
- },
551
- [ThreadType2.typename]: {
552
- // TODO(wittjosiah): Move out of metadata.
553
- loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
554
- },
555
- [MessageType2.typename]: {
556
- // TODO(wittjosiah): Move out of metadata.
557
- loadReferences: (message) => []
558
- },
559
- [THREAD_ITEM]: {
560
- parse: (item, type) => {
561
- switch (type) {
562
- case "node":
563
- return {
564
- id: item.id,
565
- label: item.title,
566
- data: item
567
- };
568
- case "object":
569
- return item;
570
- case "view-object":
571
- return {
572
- id: `${item.id}-view`,
573
- object: item
574
- };
575
- }
576
- }
577
- }
578
- }
579
- },
580
- translations: [
581
- ...translations_default,
582
- ...threadTranslations
583
- ],
584
- echo: {
585
- schema: [
586
- ChannelType,
587
- ThreadType2,
588
- MessageType2
589
- ]
590
- },
591
- graph: {
592
- builder: (plugins) => {
593
- const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
594
- const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
595
- const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
596
- if (!client || !dispatch || !metadataResolver) {
597
- return [];
598
- }
599
- return [
600
- createExtension({
601
- id: `${THREAD_PLUGIN}/comments-for-subject`,
602
- resolver: ({ id }) => {
603
- if (!id.endsWith("~comments")) {
604
- return;
605
- }
606
- const [subjectId] = id.split("~");
607
- const [spaceId, objectId] = parseFullyQualifiedId(subjectId);
608
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
609
- const object = toSignal((onChange) => {
610
- const timeout = setTimeout(async () => {
611
- await space?.db.loadObjectById(objectId);
612
- onChange();
613
- });
614
- return () => clearTimeout(timeout);
615
- }, () => space?.db.getObjectById(objectId), subjectId);
616
- if (!object || !subjectId) {
617
- return;
618
- }
619
- const meta = metadataResolver(getTypename(object) ?? "");
620
- const label = meta.label?.(object) || object.name || meta.placeholder || [
621
- "unnamed object threads label",
622
- {
623
- ns: THREAD_PLUGIN
624
- }
625
- ];
626
- const viewState = getViewState(subjectId);
627
- return {
628
- id,
629
- type: "orphan-comments-for-subject",
630
- data: null,
631
- properties: {
632
- icon: "ph--chat-text--regular",
633
- label,
634
- showResolvedThreads: viewState.showResolvedThreads,
635
- object
636
- }
637
- };
638
- },
639
- actions: ({ node }) => {
640
- const dataId = node.id.split("~").at(0);
641
- if (!node.id.endsWith("~comments") || !dataId) {
642
- return;
643
- }
644
- const [spaceId, objectId] = dataId.split(":");
645
- const viewState = getViewState(dataId);
646
- const toggle = () => {
647
- const newToggleState = !viewState.showResolvedThreads;
648
- viewState.showResolvedThreads = newToggleState;
649
- void dispatch({
650
- action: ObservabilityAction.SEND_EVENT,
651
- data: {
652
- name: "threads.toggle-show-resolved",
653
- properties: {
654
- spaceId,
655
- threadId: objectId,
656
- showResolved: newToggleState
657
- }
658
- }
659
- });
660
- };
661
- return [
662
- {
663
- id: `${THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
664
- data: toggle,
665
- properties: {
666
- label: [
667
- "toggle show resolved",
668
- {
669
- ns: THREAD_PLUGIN
670
- }
671
- ],
672
- menuItemType: "toggle",
673
- isChecked: viewState.showResolvedThreads,
674
- testId: "threadPlugin.toggleShowResolved",
675
- icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
676
- }
677
- }
678
- ];
679
- }
680
- }),
681
- createExtension({
682
- id: ThreadAction.CREATE,
683
- filter: (node) => !!settings.values.standalone && isActionGroup(node) && node.id.startsWith(SpaceAction.ADD_OBJECT),
684
- actions: ({ node }) => {
685
- const id = node.id.split("/").at(-1);
686
- const [spaceId, objectId] = id?.split(":") ?? [];
687
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
688
- const object = objectId && space?.db.getObjectById(objectId);
689
- const target = objectId ? object : space;
690
- if (!target) {
691
- return;
692
- }
693
- return [
694
- {
695
- id: `${THREAD_PLUGIN}/create/${node.id}`,
696
- data: async () => {
697
- await dispatch([
698
- {
699
- plugin: THREAD_PLUGIN,
700
- action: ThreadAction.CREATE
701
- },
702
- {
703
- action: SpaceAction.ADD_OBJECT,
704
- data: {
705
- target
706
- }
707
- },
708
- {
709
- action: NavigationAction.OPEN
710
- }
711
- ]);
712
- },
713
- properties: {
714
- label: [
715
- "create channel label",
716
- {
717
- ns: THREAD_PLUGIN
718
- }
719
- ],
720
- icon: "ph--chat--regular",
721
- testId: "threadPlugin.createObject"
722
- }
723
- }
724
- ];
725
- }
726
- })
727
- ];
728
- }
729
- },
730
- surface: {
731
- component: ({ data, role }) => {
732
- switch (role) {
733
- case "main": {
734
- return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React6.createElement(ThreadMain, {
735
- thread: data.active.threads[0]
736
- }) : null;
737
- }
738
- case "settings": {
739
- return data.plugin === meta_default.id ? /* @__PURE__ */ React6.createElement(ThreadSettings, {
740
- settings: settings.values
741
- }) : null;
742
- }
743
- case "article": {
744
- const location = navigationPlugin?.provides.location;
745
- if (data.object instanceof ChannelType && data.object.threads[0]) {
746
- const channel = data.object;
747
- if (isLayoutParts(location?.active) && location.active.main) {
748
- const layoutEntries = location.active.main;
749
- const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
750
- if (currentPosition > 0) {
751
- const objectToTheLeft = layoutEntries[currentPosition - 1];
752
- const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
753
- return /* @__PURE__ */ React6.createElement(ThreadArticle, {
754
- thread: data.object.threads[0],
755
- context
756
- });
757
- }
758
- }
759
- return /* @__PURE__ */ React6.createElement(ThreadArticle, {
760
- thread: data.object.threads[0]
761
- });
762
- }
763
- if (data.subject instanceof ThreadType2) {
764
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ChatHeading, {
765
- attendableId: data.subject.id
766
- }), /* @__PURE__ */ React6.createElement(ChatContainer, {
767
- thread: data.subject
768
- }));
769
- }
770
- break;
771
- }
772
- case "complementary--comments": {
773
- if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
774
- const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
775
- return /* @__PURE__ */ React6.createElement(ThreadComplementary, {
776
- role,
777
- subject: data.subject,
778
- drafts: state.drafts[fullyQualifiedId5(data.subject)],
779
- current: state.current,
780
- showResolvedThreads
781
- });
782
- }
783
- break;
784
- }
785
- }
786
- return null;
787
- }
788
- },
789
- intent: {
790
- resolver: async (intent) => {
791
- switch (intent.action) {
792
- case ThreadAction.CREATE: {
793
- if (intent.data && intent.data.cursor !== void 0) {
794
- const { cursor, name, subject } = intent.data;
795
- if (subject?.threads === void 0) {
796
- try {
797
- subject.threads = [];
798
- } catch (err) {
799
- log.error("Subject does not support threads array", subject?.typename, {
800
- F: __dxlog_file,
801
- L: 327,
802
- S: void 0,
803
- C: (f, a) => f(...a)
804
- });
805
- return;
806
- }
807
- }
808
- const subjectId = fullyQualifiedId5(subject);
809
- const thread = create2(ThreadType2, {
810
- name,
811
- anchor: cursor,
812
- messages: [],
813
- status: "staged"
814
- });
815
- const draft = state.drafts[subjectId];
816
- if (draft) {
817
- draft.push(thread);
818
- } else {
819
- state.drafts[subjectId] = [
820
- thread
821
- ];
822
- }
823
- return {
824
- data: thread,
825
- intents: [
826
- [
827
- {
828
- action: ThreadAction.SELECT,
829
- data: {
830
- current: fullyQualifiedId5(thread)
831
- }
832
- }
833
- ],
834
- [
835
- {
836
- action: NavigationAction.OPEN,
837
- data: {
838
- activeParts: {
839
- complementary: "comments"
840
- }
841
- }
842
- }
843
- ]
844
- ]
845
- };
846
- } else {
847
- return {
848
- data: create2(ChannelType, {
849
- threads: [
850
- create2(ThreadType2, {
851
- messages: []
852
- })
853
- ]
854
- })
855
- };
856
- }
857
- }
858
- case ThreadAction.SELECT: {
859
- state.current = intent.data?.current;
860
- return {
861
- data: true,
862
- intents: !intent.data?.skipOpen ? [
863
- [
864
- {
865
- action: NavigationAction.OPEN,
866
- data: {
867
- activeParts: {
868
- complementary: "comments"
869
- }
870
- }
871
- }
872
- ]
873
- ] : []
874
- };
875
- }
876
- case ThreadAction.TOGGLE_RESOLVED: {
877
- const { thread } = intent.data ?? {};
878
- if (!(thread instanceof ThreadType2)) {
879
- return;
880
- }
881
- if (thread.status === "active" || thread.status === void 0) {
882
- thread.status = "resolved";
883
- } else if (thread.status === "resolved") {
884
- thread.status = "active";
885
- }
886
- const space = getSpace3(thread);
887
- const spaceId = space?.id;
888
- return {
889
- data: true,
890
- intents: [
891
- [
892
- {
893
- action: ObservabilityAction.SEND_EVENT,
894
- data: {
895
- name: "threads.toggle-resolved",
896
- properties: {
897
- threadId: thread.id,
898
- spaceId
899
- }
900
- }
901
- }
902
- ]
903
- ]
904
- };
905
- }
906
- case ThreadAction.DELETE: {
907
- const { subject, thread } = intent.data ?? {};
908
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
909
- return;
910
- }
911
- const subjectId = fullyQualifiedId5(subject);
912
- const draft = state.drafts[subjectId];
913
- if (draft) {
914
- const index = draft.findIndex((t) => t.id === thread.id);
915
- if (index !== -1) {
916
- draft.splice(index, 1);
917
- return {
918
- data: true
919
- };
920
- }
921
- }
922
- const space = getSpace3(thread);
923
- if (!space || !subject.threads) {
924
- return;
925
- }
926
- if (!intent.undo) {
927
- const index = subject.threads.findIndex((t) => t?.id === thread.id);
928
- const cursor = subject.threads[index]?.anchor;
929
- if (index !== -1) {
930
- subject.threads?.splice(index, 1);
931
- }
932
- space.db.remove(thread);
933
- return {
934
- undoable: {
935
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["thread deleted label"],
936
- data: {
937
- cursor
938
- }
939
- },
940
- intents: [
941
- [
942
- {
943
- action: ObservabilityAction.SEND_EVENT,
944
- data: {
945
- name: "threads.delete",
946
- properties: {
947
- threadId: thread.id,
948
- spaceId: space.id
949
- }
950
- }
951
- }
952
- ]
953
- ]
954
- };
955
- } else if (intent.undo) {
956
- const savedThread = space.db.add(thread);
957
- subject.threads.push(savedThread);
958
- return {
959
- data: true,
960
- intents: [
961
- [
962
- {
963
- action: ObservabilityAction.SEND_EVENT,
964
- data: {
965
- name: "threads.undo-delete",
966
- properties: {
967
- threadId: thread.id,
968
- spaceId: space.id
969
- }
970
- }
971
- }
972
- ]
973
- ]
974
- };
975
- }
976
- break;
977
- }
978
- case ThreadAction.ON_MESSAGE_ADD: {
979
- const { thread, subject } = intent.data ?? {};
980
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
981
- return;
982
- }
983
- const subjectId = fullyQualifiedId5(subject);
984
- const space = getSpace3(subject);
985
- const intents = [];
986
- const analyticsProperties = {
987
- threadId: thread.id,
988
- spaceId: space?.id
989
- };
990
- if (state.drafts[subjectId]?.find((t) => t === thread)) {
991
- thread.status = "active";
992
- subject.threads ? subject.threads.push(thread) : subject.threads = [
993
- thread
994
- ];
995
- state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
996
- intents.push({
997
- action: ObservabilityAction.SEND_EVENT,
998
- data: {
999
- name: "threads.thread-created",
1000
- properties: analyticsProperties
1001
- }
1002
- });
1003
- }
1004
- intents.push({
1005
- action: ObservabilityAction.SEND_EVENT,
1006
- data: {
1007
- name: "threads.message-added",
1008
- properties: {
1009
- ...analyticsProperties,
1010
- threadLength: thread.messages.length
1011
- }
1012
- }
1013
- });
1014
- return {
1015
- data: thread,
1016
- intents: [
1017
- intents
1018
- ]
1019
- };
1020
- }
1021
- case ThreadAction.DELETE_MESSAGE: {
1022
- const { subject, thread, messageId } = intent.data ?? {};
1023
- const space = getSpace3(subject);
1024
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
1025
- return;
1026
- }
1027
- if (!intent.undo) {
1028
- const message = thread.messages.find((m) => m?.id === messageId);
1029
- const messageIndex = thread.messages.findIndex((m) => m?.id === messageId);
1030
- if (messageIndex === -1 || !message) {
1031
- return void 0;
1032
- }
1033
- if (messageIndex === 0 && thread.messages.length === 1) {
1034
- return {
1035
- intents: [
1036
- [
1037
- {
1038
- action: ThreadAction.DELETE,
1039
- data: {
1040
- subject,
1041
- thread
1042
- }
1043
- }
1044
- ]
1045
- ]
1046
- };
1047
- } else {
1048
- thread.messages.splice(messageIndex, 1);
1049
- }
1050
- return {
1051
- undoable: {
1052
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["message deleted label"],
1053
- data: {
1054
- message,
1055
- messageIndex
1056
- }
1057
- },
1058
- intents: [
1059
- [
1060
- {
1061
- action: ObservabilityAction.SEND_EVENT,
1062
- data: {
1063
- name: "threads.message.delete",
1064
- properties: {
1065
- threadId: thread.id,
1066
- spaceId: space?.id
1067
- }
1068
- }
1069
- }
1070
- ]
1071
- ]
1072
- };
1073
- } else if (intent.undo) {
1074
- const message = intent.data?.message;
1075
- const messageIndex = intent.data?.messageIndex;
1076
- if (!(message instanceof MessageType2) || !(typeof messageIndex === "number")) {
1077
- return;
1078
- }
1079
- thread.messages.splice(messageIndex, 0, message);
1080
- return {
1081
- data: true,
1082
- intents: [
1083
- [
1084
- {
1085
- action: ObservabilityAction.SEND_EVENT,
1086
- data: {
1087
- name: "threads.message.undo-delete",
1088
- properties: {
1089
- threadId: thread.id,
1090
- spaceId: space?.id
1091
- }
1092
- }
1093
- }
1094
- ]
1095
- ]
1096
- };
1097
- }
1098
- }
1099
- }
1100
- }
1101
- },
1102
- markdown: {
1103
- extensions: ({ document: doc }) => {
1104
- return threads(state, doc, intentPlugin?.provides.intent.dispatch);
1105
- }
1106
- }
1107
- }
1108
- };
1109
- };
1110
-
1111
- // packages/plugins/plugin-thread/src/index.ts
1112
- var src_default = ThreadPlugin;
1113
- export {
1114
- ThreadAction,
1115
- ThreadPlugin,
1116
- src_default as default,
1117
- useAnalyticsCallback,
1118
- useOnEditAnalytics,
1119
- useStatus
1120
- };
1121
- //# sourceMappingURL=index.mjs.map