@dxos/plugin-thread 0.7.4 → 0.7.5-main.9d26e3a

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 (72) hide show
  1. package/dist/lib/browser/{ThreadArticle-6IXTL7CH.mjs → ThreadArticle-EWLTNU6Z.mjs} +2 -2
  2. package/dist/lib/browser/{ThreadMain-4IAS67KE.mjs → ThreadMain-ABEDFWHC.mjs} +2 -2
  3. package/dist/lib/browser/chunk-6KTMQPL4.mjs +77 -0
  4. package/dist/lib/browser/chunk-6KTMQPL4.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-52HWDLBR.mjs → chunk-OD2IZKRP.mjs} +23 -45
  6. package/dist/lib/browser/chunk-OD2IZKRP.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +323 -480
  8. package/dist/lib/browser/index.mjs.map +3 -3
  9. package/dist/lib/browser/meta.json +1 -1
  10. package/dist/lib/browser/types.mjs +1 -1
  11. package/dist/lib/node/{ThreadArticle-I7ADXDW3.cjs → ThreadArticle-ZCNMFBAO.cjs} +6 -6
  12. package/dist/lib/node/{ThreadMain-MRNJC3TI.cjs → ThreadMain-5AYGCXXP.cjs} +6 -6
  13. package/dist/lib/node/{chunk-YCDM2SZM.cjs → chunk-2CB5AVBL.cjs} +27 -50
  14. package/dist/lib/node/chunk-2CB5AVBL.cjs.map +7 -0
  15. package/dist/lib/node/chunk-VW2P26MZ.cjs +96 -0
  16. package/dist/lib/node/chunk-VW2P26MZ.cjs.map +7 -0
  17. package/dist/lib/node/index.cjs +336 -491
  18. package/dist/lib/node/index.cjs.map +3 -3
  19. package/dist/lib/node/meta.json +1 -1
  20. package/dist/lib/node/types.cjs +2 -2
  21. package/dist/lib/node/types.cjs.map +1 -1
  22. package/dist/lib/node-esm/{ThreadArticle-CJHYMF2W.mjs → ThreadArticle-F37HYTOU.mjs} +2 -2
  23. package/dist/lib/node-esm/{ThreadMain-VISGW4IF.mjs → ThreadMain-OL6ZHNZY.mjs} +2 -2
  24. package/dist/lib/node-esm/{chunk-JG7MXH6O.mjs → chunk-AQ74G3GY.mjs} +23 -45
  25. package/dist/lib/node-esm/chunk-AQ74G3GY.mjs.map +7 -0
  26. package/dist/lib/node-esm/chunk-RMYATBXM.mjs +78 -0
  27. package/dist/lib/node-esm/chunk-RMYATBXM.mjs.map +7 -0
  28. package/dist/lib/node-esm/index.mjs +323 -480
  29. package/dist/lib/node-esm/index.mjs.map +3 -3
  30. package/dist/lib/node-esm/meta.json +1 -1
  31. package/dist/lib/node-esm/types.mjs +1 -1
  32. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  33. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  35. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  36. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  37. package/dist/types/src/components/ThreadComplementary.d.ts +1 -2
  38. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  39. package/dist/types/src/components/testing.d.ts +50 -66
  40. package/dist/types/src/components/testing.d.ts.map +1 -1
  41. package/dist/types/src/extensions/threads.d.ts +2 -2
  42. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  43. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  44. package/dist/types/src/types.d.ts +76 -8
  45. package/dist/types/src/types.d.ts.map +1 -1
  46. package/dist/types/tsconfig.tsbuildinfo +1 -0
  47. package/package.json +30 -30
  48. package/src/ThreadPlugin.tsx +215 -361
  49. package/src/components/Chat.stories.tsx +10 -8
  50. package/src/components/ChatContainer.tsx +13 -11
  51. package/src/components/CommentContainer.tsx +14 -11
  52. package/src/components/MessageContainer.tsx +7 -5
  53. package/src/components/ThreadComplementary.tsx +18 -32
  54. package/src/components/testing.ts +26 -22
  55. package/src/extensions/threads.ts +16 -25
  56. package/src/hooks/analytics.ts +6 -10
  57. package/src/types.ts +60 -9
  58. package/dist/lib/browser/chunk-52HWDLBR.mjs.map +0 -7
  59. package/dist/lib/browser/chunk-XUHNZID5.mjs +0 -20
  60. package/dist/lib/browser/chunk-XUHNZID5.mjs.map +0 -7
  61. package/dist/lib/node/chunk-XFO6D2LG.cjs +0 -39
  62. package/dist/lib/node/chunk-XFO6D2LG.cjs.map +0 -7
  63. package/dist/lib/node/chunk-YCDM2SZM.cjs.map +0 -7
  64. package/dist/lib/node-esm/chunk-I5MU54RT.mjs +0 -21
  65. package/dist/lib/node-esm/chunk-I5MU54RT.mjs.map +0 -7
  66. package/dist/lib/node-esm/chunk-JG7MXH6O.mjs.map +0 -7
  67. /package/dist/lib/browser/{ThreadArticle-6IXTL7CH.mjs.map → ThreadArticle-EWLTNU6Z.mjs.map} +0 -0
  68. /package/dist/lib/browser/{ThreadMain-4IAS67KE.mjs.map → ThreadMain-ABEDFWHC.mjs.map} +0 -0
  69. /package/dist/lib/node/{ThreadArticle-I7ADXDW3.cjs.map → ThreadArticle-ZCNMFBAO.cjs.map} +0 -0
  70. /package/dist/lib/node/{ThreadMain-MRNJC3TI.cjs.map → ThreadMain-5AYGCXXP.cjs.map} +0 -0
  71. /package/dist/lib/node-esm/{ThreadArticle-CJHYMF2W.mjs.map → ThreadArticle-F37HYTOU.mjs.map} +0 -0
  72. /package/dist/lib/node-esm/{ThreadMain-VISGW4IF.mjs.map → ThreadMain-OL6ZHNZY.mjs.map} +0 -0
@@ -1,17 +1,15 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
  import {
3
3
  ThreadAction
4
- } from "./chunk-I5MU54RT.mjs";
4
+ } from "./chunk-RMYATBXM.mjs";
5
5
  import {
6
- ChatContainer,
7
- ChatHeading,
8
6
  MessageContainer,
9
7
  command,
10
8
  getMessageMetadata,
11
9
  useAnalyticsCallback,
12
10
  useOnEditAnalytics,
13
11
  useStatus
14
- } from "./chunk-JG7MXH6O.mjs";
12
+ } from "./chunk-AQ74G3GY.mjs";
15
13
  import {
16
14
  THREAD_ITEM,
17
15
  THREAD_PLUGIN,
@@ -20,15 +18,16 @@ import {
20
18
 
21
19
  // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
22
20
  import React5 from "react";
23
- import { isLayoutParts, LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseMetadataResolverPlugin, parseNavigationPlugin, resolvePlugin } from "@dxos/app-framework";
21
+ import { createIntent as createIntent3, createResolver, createSurface, isLayoutParts, LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseMetadataResolverPlugin, parseNavigationPlugin, resolvePlugin } from "@dxos/app-framework";
22
+ import { Ref as Ref2 } from "@dxos/echo-schema";
24
23
  import { LocalStorageStore } from "@dxos/local-storage";
25
24
  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 { memoizeQuery, SpaceAction } from "@dxos/plugin-space";
25
+ import { parseClientPlugin } from "@dxos/plugin-client/types";
26
+ import { createExtension, toSignal } from "@dxos/plugin-graph";
27
+ import { ObservabilityAction } from "@dxos/plugin-observability/types";
28
+ import { memoizeQuery } from "@dxos/plugin-space";
30
29
  import { ChannelType as ChannelType2, MessageType as MessageType2, ThreadType as ThreadType2 } from "@dxos/plugin-space/types";
31
- import { create as create2, fullyQualifiedId as fullyQualifiedId5, getSpace as getSpace3, getTypename, loadObjectReferences, parseId, SpaceState } from "@dxos/react-client/echo";
30
+ import { create as create2, fullyQualifiedId as fullyQualifiedId5, getSpace as getSpace3, getTypename, makeRef as makeRef2, parseId, RefArray as RefArray4, SpaceState } from "@dxos/react-client/echo";
32
31
  import { translations as threadTranslations } from "@dxos/react-ui-thread";
33
32
 
34
33
  // packages/plugins/plugin-thread/src/components/index.ts
@@ -37,7 +36,7 @@ import { lazy } from "react";
37
36
  // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
38
37
  import { CheckCircle, X } from "@phosphor-icons/react";
39
38
  import React, { useCallback, useMemo, useRef, useState } from "react";
40
- import { create } from "@dxos/live-object";
39
+ import { create, makeRef, RefArray } from "@dxos/live-object";
41
40
  import { MessageType } from "@dxos/plugin-space/types";
42
41
  import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
43
42
  import { useIdentity } from "@dxos/react-client/halo";
@@ -68,9 +67,7 @@ var ToggleResolvedButton = ({ isResolved, onResolve }) => {
68
67
  weight: "fill"
69
68
  }) : /* @__PURE__ */ React.createElement(CheckCircle, {
70
69
  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))));
70
+ }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, null, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
74
71
  };
75
72
  var DeleteThreadButton = ({ onDelete }) => {
76
73
  const { t } = useTranslation(THREAD_PLUGIN);
@@ -90,7 +87,7 @@ var DeleteThreadButton = ({ onDelete }) => {
90
87
  }, label), /* @__PURE__ */ React.createElement(X, {
91
88
  className: sizeClass
92
89
  }))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
93
- classNames: "z-[21]"
90
+ classNames: "z-30"
94
91
  }, label, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
95
92
  };
96
93
  var CommentContainer = ({ thread, detached, context, current, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
@@ -127,14 +124,14 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
127
124
  if (!messageRef.current) {
128
125
  return false;
129
126
  }
130
- thread.messages.push(create(MessageType, {
127
+ thread.messages.push(makeRef(create(MessageType, {
131
128
  sender: {
132
129
  identityKey: identity.identityKey.toHex()
133
130
  },
134
131
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
135
132
  text: messageRef.current,
136
- context
137
- }));
133
+ context: context ? makeRef(context) : void 0
134
+ })));
138
135
  onComment?.(thread);
139
136
  messageRef.current = "";
140
137
  scrollToEnd("instant");
@@ -157,7 +154,7 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
157
154
  }, /* @__PURE__ */ React.createElement(ThreadHeading, {
158
155
  detached: true
159
156
  }, thread.name)), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, {
160
- classNames: "z-[21]",
157
+ classNames: "z-30",
161
158
  side: "top"
162
159
  }, t("detached thread label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React.createElement(ThreadHeading, null, thread.name), /* @__PURE__ */ React.createElement("div", {
163
160
  className: "flex flex-row items-center pli-1"
@@ -168,7 +165,7 @@ var CommentContainer = ({ thread, detached, context, current, onAttend, onThread
168
165
  onResolve
169
166
  }), onThreadDelete && /* @__PURE__ */ React.createElement(DeleteThreadButton, {
170
167
  onDelete: onThreadDelete
171
- }))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
168
+ }))), RefArray.allResolvedTargets(thread.messages?.filter(nonNullable) ?? []).map((message) => /* @__PURE__ */ React.createElement(MessageContainer, {
172
169
  key: message.id,
173
170
  message,
174
171
  members,
@@ -244,13 +241,13 @@ var CommentsContainer = ({ threads: threads2, detached = [], currentId, showReso
244
241
 
245
242
  // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
246
243
  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";
244
+ import { createIntent, LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
245
+ import { fullyQualifiedId as fullyQualifiedId3, RefArray as RefArray2 } from "@dxos/react-client/echo";
249
246
  import { useAttended } from "@dxos/react-ui-attention";
250
247
  import { nonNullable as nonNullable2 } from "@dxos/util";
251
248
  var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
252
- var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads }) => {
253
- const dispatch = useIntentDispatcher();
249
+ var ThreadComplementary = ({ subject, drafts, current, showResolvedThreads }) => {
250
+ const { dispatchPromise: dispatch } = useIntentDispatcher();
254
251
  const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
255
252
  const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
256
253
  threadsIntegrators
@@ -263,10 +260,11 @@ var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads
263
260
  createSort,
264
261
  subject
265
262
  ]);
263
+ const threadObjects = RefArray2.allResolvedTargets(subject.threads ?? []);
266
264
  const threads2 = useMemo2(() => {
267
- return subject.threads.concat(drafts ?? []).filter(nonNullable2);
265
+ return threadObjects.concat(drafts ?? []).filter(nonNullable2);
268
266
  }, [
269
- JSON.stringify(subject.threads),
267
+ JSON.stringify(threadObjects),
270
268
  JSON.stringify(drafts)
271
269
  ]);
272
270
  const detachedIds = useMemo2(() => {
@@ -294,53 +292,29 @@ var ThreadComplementary = ({ role, subject, drafts, current, showResolvedThreads
294
292
  const threadId = fullyQualifiedId3(thread);
295
293
  if (current !== threadId) {
296
294
  current = threadId;
297
- void dispatch?.([
298
- {
299
- action: LayoutAction.SCROLL_INTO_VIEW,
300
- data: {
301
- id: fullyQualifiedId3(subject),
302
- thread: threadId,
303
- cursor: thread.anchor
304
- }
305
- }
306
- ]);
295
+ void dispatch?.(createIntent(LayoutAction.ScrollIntoView, {
296
+ id: fullyQualifiedId3(subject),
297
+ cursor: thread.anchor,
298
+ ref: threadId
299
+ }));
307
300
  }
308
301
  },
309
- onThreadDelete: (thread) => {
310
- return dispatch({
311
- plugin: THREAD_PLUGIN,
312
- action: ThreadAction.DELETE,
313
- data: {
314
- subject,
315
- thread
316
- }
317
- });
318
- },
319
- onMessageDelete: (thread, messageId) => dispatch({
320
- plugin: THREAD_PLUGIN,
321
- action: ThreadAction.DELETE_MESSAGE,
322
- data: {
323
- subject,
324
- thread,
325
- messageId
326
- }
327
- }),
328
- onThreadToggleResolved: (thread) => dispatch({
329
- plugin: THREAD_PLUGIN,
330
- action: ThreadAction.TOGGLE_RESOLVED,
331
- data: {
332
- thread
333
- }
334
- }),
335
- onComment: (thread) => {
336
- void dispatch({
337
- action: ThreadAction.ON_MESSAGE_ADD,
338
- data: {
339
- thread,
340
- subject
341
- }
342
- });
343
- }
302
+ onThreadDelete: (thread) => dispatch(createIntent(ThreadAction.Delete, {
303
+ thread,
304
+ subject
305
+ })),
306
+ onMessageDelete: (thread, messageId) => dispatch(createIntent(ThreadAction.DeleteMessage, {
307
+ thread,
308
+ subject,
309
+ messageId
310
+ })),
311
+ onThreadToggleResolved: (thread) => dispatch(createIntent(ThreadAction.ToggleResolved, {
312
+ thread
313
+ })),
314
+ onComment: (thread) => dispatch(createIntent(ThreadAction.OnMessageAdd, {
315
+ thread,
316
+ subject
317
+ }))
344
318
  });
345
319
  };
346
320
 
@@ -359,20 +333,22 @@ var ThreadSettings = ({ settings }) => {
359
333
  };
360
334
 
361
335
  // packages/plugins/plugin-thread/src/components/index.ts
362
- var ThreadMain = lazy(() => import("./ThreadMain-VISGW4IF.mjs"));
363
- var ThreadArticle = lazy(() => import("./ThreadArticle-CJHYMF2W.mjs"));
336
+ var ThreadMain = lazy(() => import("./ThreadMain-OL6ZHNZY.mjs"));
337
+ var ThreadArticle = lazy(() => import("./ThreadArticle-F37HYTOU.mjs"));
364
338
 
365
339
  // packages/plugins/plugin-thread/src/extensions/threads.ts
366
340
  import { EditorView } from "@codemirror/view";
367
341
  import { computed, effect } from "@preact/signals-core";
342
+ import { createIntent as createIntent2 } from "@dxos/app-framework";
343
+ import { Ref } from "@dxos/echo-schema";
344
+ import { RefArray as RefArray3 } from "@dxos/live-object";
368
345
  import { ThreadType } from "@dxos/plugin-space/types";
369
346
  import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4 } from "@dxos/react-client/echo";
370
347
  import { comments, createExternalCommentSync } from "@dxos/react-ui-editor";
371
- import { nonNullable as nonNullable3 } from "@dxos/util";
372
348
  var getName = (doc, anchor) => {
373
349
  if (doc.content) {
374
350
  const [start, end] = anchor.split(":");
375
- return getTextInRange(createDocAccessor(doc.content, [
351
+ return getTextInRange(createDocAccessor(doc.content.target, [
376
352
  "content"
377
353
  ]), start, end);
378
354
  }
@@ -385,14 +361,14 @@ var threads = (state, doc, dispatch) => {
385
361
  ];
386
362
  }
387
363
  const threads2 = computed(() => [
388
- ...doc.threads.filter(nonNullable3),
364
+ ...RefArray3.allResolvedTargets(doc.threads),
389
365
  ...state.drafts[fullyQualifiedId4(doc)] ?? []
390
366
  ].filter((thread) => !(thread?.status === "resolved")));
391
367
  return [
392
368
  EditorView.updateListener.of((update) => {
393
369
  if (update.docChanged) {
394
- doc.threads.forEach((thread) => {
395
- if (thread?.anchor) {
370
+ RefArray3.allResolvedTargets(doc.threads).forEach((thread) => {
371
+ if (thread.anchor) {
396
372
  const name = getName(doc, thread.anchor);
397
373
  if (name && name !== thread.name) {
398
374
  thread.name = name;
@@ -409,14 +385,11 @@ var threads = (state, doc, dispatch) => {
409
385
  id: fullyQualifiedId4(doc),
410
386
  onCreate: ({ cursor }) => {
411
387
  const name = getName(doc, cursor);
412
- void dispatch({
413
- action: ThreadAction.CREATE,
414
- data: {
415
- cursor,
416
- name,
417
- subject: doc
418
- }
419
- });
388
+ void dispatch(createIntent2(ThreadAction.Create, {
389
+ cursor,
390
+ name,
391
+ subject: doc
392
+ }));
420
393
  },
421
394
  onDelete: ({ id }) => {
422
395
  const draft = state.drafts[fullyQualifiedId4(doc)];
@@ -426,26 +399,26 @@ var threads = (state, doc, dispatch) => {
426
399
  draft.splice(index, 1);
427
400
  }
428
401
  }
429
- const thread = doc.threads.find((thread2) => thread2?.id === id);
402
+ const thread = doc.threads.find(Ref.hasObjectId(id))?.target;
430
403
  if (thread) {
431
404
  thread.anchor = void 0;
432
405
  }
433
406
  },
434
407
  onUpdate: ({ id, cursor }) => {
435
- const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
408
+ const thread = state.drafts[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find(Ref.hasObjectId(id))?.target;
436
409
  if (thread instanceof ThreadType && thread.anchor) {
437
410
  thread.name = getName(doc, thread.anchor);
438
411
  thread.anchor = cursor;
439
412
  }
440
413
  },
441
- onSelect: ({ selection: { current, closest } }) => {
442
- void dispatch({
443
- action: ThreadAction.SELECT,
444
- data: {
445
- current: current ?? closest,
414
+ onSelect: ({ selection }) => {
415
+ const current = selection.current ?? selection.closest;
416
+ if (current) {
417
+ void dispatch(createIntent2(ThreadAction.Select, {
418
+ current,
446
419
  skipOpen: true
447
- }
448
- });
420
+ }));
421
+ }
449
422
  }
450
423
  })
451
424
  ];
@@ -511,7 +484,6 @@ var ThreadPlugin = () => {
511
484
  }
512
485
  return viewStore[subjectId];
513
486
  };
514
- let navigationPlugin;
515
487
  let intentPlugin;
516
488
  const unsubscribeCallbacks = [];
517
489
  return {
@@ -538,8 +510,7 @@ var ThreadPlugin = () => {
538
510
  }
539
511
  };
540
512
  },
541
- ready: async (plugins) => {
542
- navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
513
+ ready: async ({ plugins }) => {
543
514
  intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
544
515
  },
545
516
  unload: async () => {
@@ -550,7 +521,7 @@ var ThreadPlugin = () => {
550
521
  metadata: {
551
522
  records: {
552
523
  [ChannelType2.typename]: {
553
- createObject: ThreadAction.CREATE,
524
+ createObject: (props) => createIntent3(ThreadAction.Create, props),
554
525
  placeholder: [
555
526
  "channel name placeholder",
556
527
  {
@@ -559,11 +530,11 @@ var ThreadPlugin = () => {
559
530
  ],
560
531
  icon: "ph--chat--regular",
561
532
  // TODO(wittjosiah): Move out of metadata.
562
- loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
533
+ loadReferences: async (channel) => await RefArray4.loadAll(channel.threads ?? [])
563
534
  },
564
535
  [ThreadType2.typename]: {
565
536
  // TODO(wittjosiah): Move out of metadata.
566
- loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
537
+ loadReferences: async (thread) => await RefArray4.loadAll(thread.messages ?? [])
567
538
  },
568
539
  [MessageType2.typename]: {
569
540
  // TODO(wittjosiah): Move out of metadata.
@@ -611,7 +582,7 @@ var ThreadPlugin = () => {
611
582
  graph: {
612
583
  builder: (plugins) => {
613
584
  const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
614
- const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
585
+ const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatchPromise;
615
586
  const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
616
587
  if (!client || !dispatch || !metadataResolver) {
617
588
  return [];
@@ -681,20 +652,17 @@ var ThreadPlugin = () => {
681
652
  }
682
653
  const [spaceId, objectId] = dataId.split(":");
683
654
  const viewState = getViewState(dataId);
684
- const toggle = () => {
655
+ const toggle = async () => {
685
656
  const newToggleState = !viewState.showResolvedThreads;
686
657
  viewState.showResolvedThreads = newToggleState;
687
- void dispatch({
688
- action: ObservabilityAction.SEND_EVENT,
689
- data: {
690
- name: "threads.toggle-show-resolved",
691
- properties: {
692
- spaceId,
693
- threadId: objectId,
694
- showResolved: newToggleState
695
- }
658
+ await dispatch(createIntent3(ObservabilityAction.SendEvent, {
659
+ name: "threads.toggle-show-resolved",
660
+ properties: {
661
+ spaceId,
662
+ threadId: objectId,
663
+ showResolved: newToggleState
696
664
  }
697
- });
665
+ }));
698
666
  };
699
667
  return [
700
668
  {
@@ -715,440 +683,315 @@ var ThreadPlugin = () => {
715
683
  }
716
684
  ];
717
685
  }
718
- }),
719
- createExtension({
720
- id: ThreadAction.CREATE,
721
- filter: (node) => !!settings.values.standalone && isActionGroup(node) && node.id.startsWith(SpaceAction.ADD_OBJECT),
722
- actions: ({ node }) => {
723
- const id = node.id.split("/").at(-1);
724
- const [spaceId, objectId] = id?.split(":") ?? [];
725
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
726
- const object = objectId && space?.db.getObjectById(objectId);
727
- const target = objectId ? object : space;
728
- if (!target) {
729
- return;
730
- }
731
- return [
732
- {
733
- id: `${THREAD_PLUGIN}/create/${node.id}`,
734
- data: async () => {
735
- await dispatch([
736
- {
737
- plugin: THREAD_PLUGIN,
738
- action: ThreadAction.CREATE
739
- },
740
- {
741
- action: SpaceAction.ADD_OBJECT,
742
- data: {
743
- target
744
- }
745
- },
746
- {
747
- action: NavigationAction.OPEN
748
- }
749
- ]);
750
- },
751
- properties: {
752
- label: [
753
- "create channel label",
754
- {
755
- ns: THREAD_PLUGIN
756
- }
757
- ],
758
- icon: "ph--chat--regular",
759
- testId: "threadPlugin.createObject"
760
- }
761
- }
762
- ];
763
- }
764
686
  })
765
687
  ];
766
688
  }
767
689
  },
768
690
  surface: {
769
- component: ({ data, role }) => {
770
- switch (role) {
771
- case "main": {
772
- return data.active instanceof ChannelType2 && data.active.threads[0] ? /* @__PURE__ */ React5.createElement(ThreadMain, {
773
- thread: data.active.threads[0]
774
- }) : null;
775
- }
776
- case "settings": {
777
- return data.plugin === meta_default.id ? /* @__PURE__ */ React5.createElement(ThreadSettings, {
778
- settings: settings.values
779
- }) : null;
780
- }
781
- case "article": {
782
- const location = navigationPlugin?.provides.location;
783
- if (data.object instanceof ChannelType2 && data.object.threads[0]) {
784
- const channel = data.object;
691
+ definitions: ({ plugins }) => {
692
+ const location = resolvePlugin(plugins, parseNavigationPlugin)?.provides.location;
693
+ return [
694
+ createSurface({
695
+ id: `${THREAD_PLUGIN}/channel`,
696
+ role: "article",
697
+ filter: (data) => data.subject instanceof ChannelType2 && !!data.subject.threads[0],
698
+ component: ({ data }) => {
699
+ const channel = data.subject;
700
+ const thread = channel.threads[0].target;
785
701
  if (isLayoutParts(location?.active) && location.active.main) {
786
702
  const layoutEntries = location.active.main;
787
703
  const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
788
704
  if (currentPosition > 0) {
789
705
  const objectToTheLeft = layoutEntries[currentPosition - 1];
790
- const context = getSpace3(data.object)?.db.getObjectById(objectToTheLeft.id);
706
+ const context = getSpace3(channel)?.db.getObjectById(objectToTheLeft.id);
791
707
  return /* @__PURE__ */ React5.createElement(ThreadArticle, {
792
- thread: data.object.threads[0],
708
+ thread,
793
709
  context
794
710
  });
795
711
  }
796
712
  }
797
713
  return /* @__PURE__ */ React5.createElement(ThreadArticle, {
798
- thread: data.object.threads[0]
714
+ thread
799
715
  });
800
716
  }
801
- if (data.subject instanceof ThreadType2) {
802
- return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(ChatHeading, {
803
- attendableId: data.subject.id
804
- }), /* @__PURE__ */ React5.createElement(ChatContainer, {
805
- thread: data.subject
806
- }));
807
- }
808
- break;
809
- }
810
- case "complementary--comments": {
811
- if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads) && !(data.subject instanceof ChannelType2)) {
717
+ }),
718
+ createSurface({
719
+ id: `${THREAD_PLUGIN}/thread`,
720
+ role: "complementary--comments",
721
+ filter: (data) => !!data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads) && !(data.subject instanceof ChannelType2),
722
+ component: ({ data }) => {
812
723
  const { showResolvedThreads } = getViewState(fullyQualifiedId5(data.subject));
813
724
  return /* @__PURE__ */ React5.createElement(ThreadComplementary, {
814
- role,
815
725
  subject: data.subject,
816
726
  drafts: state.drafts[fullyQualifiedId5(data.subject)],
817
727
  current: state.current,
818
728
  showResolvedThreads
819
729
  });
820
730
  }
821
- break;
822
- }
823
- }
824
- return null;
731
+ }),
732
+ createSurface({
733
+ id: `${THREAD_PLUGIN}/settings`,
734
+ role: "settings",
735
+ filter: (data) => data.plugin === THREAD_PLUGIN,
736
+ component: () => /* @__PURE__ */ React5.createElement(ThreadSettings, {
737
+ settings: settings.values
738
+ })
739
+ })
740
+ ];
825
741
  }
826
742
  },
827
743
  intent: {
828
- resolver: async (intent) => {
829
- switch (intent.action) {
830
- case ThreadAction.CREATE: {
831
- if (intent.data && intent.data.cursor !== void 0) {
832
- const { cursor, name, subject } = intent.data;
833
- if (subject?.threads === void 0) {
834
- try {
835
- subject.threads = [];
836
- } catch (err) {
837
- log.error("Subject does not support threads array", subject?.typename, {
838
- F: __dxlog_file,
839
- L: 371,
840
- S: void 0,
841
- C: (f, a) => f(...a)
842
- });
843
- return;
844
- }
845
- }
846
- const subjectId = fullyQualifiedId5(subject);
847
- const thread = create2(ThreadType2, {
848
- name,
849
- anchor: cursor,
850
- messages: [],
851
- status: "staged"
852
- });
853
- const draft = state.drafts[subjectId];
854
- if (draft) {
855
- draft.push(thread);
856
- } else {
857
- state.drafts[subjectId] = [
858
- thread
859
- ];
744
+ resolvers: () => [
745
+ createResolver(ThreadAction.Create, ({ name, cursor, subject }) => {
746
+ if (cursor && subject) {
747
+ if (subject?.threads === void 0) {
748
+ try {
749
+ subject.threads = [];
750
+ } catch (err) {
751
+ log.error("Subject does not support threads array", subject?.typename, {
752
+ F: __dxlog_file,
753
+ L: 314,
754
+ S: void 0,
755
+ C: (f, a) => f(...a)
756
+ });
757
+ return;
860
758
  }
861
- return {
862
- data: thread,
863
- intents: [
864
- [
865
- {
866
- action: ThreadAction.SELECT,
867
- data: {
868
- current: fullyQualifiedId5(thread)
869
- }
870
- }
871
- ],
872
- [
873
- {
874
- action: NavigationAction.OPEN,
875
- data: {
876
- activeParts: {
877
- complementary: "comments"
878
- }
879
- }
880
- }
881
- ],
882
- [
883
- {
884
- action: LayoutAction2.SET_LAYOUT,
885
- data: {
886
- element: "complementary",
887
- state: true
888
- }
889
- }
890
- ]
891
- ]
892
- };
759
+ }
760
+ const subjectId = fullyQualifiedId5(subject);
761
+ const thread = create2(ThreadType2, {
762
+ name,
763
+ anchor: cursor,
764
+ messages: [],
765
+ status: "staged"
766
+ });
767
+ const draft = state.drafts[subjectId];
768
+ if (draft) {
769
+ draft.push(thread);
893
770
  } else {
894
- return {
895
- data: create2(ChannelType2, {
771
+ state.drafts[subjectId] = [
772
+ thread
773
+ ];
774
+ }
775
+ return {
776
+ data: {
777
+ object: thread
778
+ },
779
+ intents: [
780
+ createIntent3(ThreadAction.Select, {
781
+ current: fullyQualifiedId5(thread)
782
+ }),
783
+ createIntent3(NavigationAction.Open, {
784
+ activeParts: {
785
+ complementary: "comments"
786
+ }
787
+ }),
788
+ createIntent3(LayoutAction2.SetLayout, {
789
+ element: "complementary",
790
+ state: true
791
+ })
792
+ ]
793
+ };
794
+ } else {
795
+ return {
796
+ data: {
797
+ object: create2(ChannelType2, {
896
798
  threads: [
897
- create2(ThreadType2, {
799
+ makeRef2(create2(ThreadType2, {
898
800
  messages: []
899
- })
801
+ }))
900
802
  ]
901
803
  })
902
- };
804
+ }
805
+ };
806
+ }
807
+ }),
808
+ createResolver(ThreadAction.Select, ({ current, skipOpen }) => {
809
+ state.current = current;
810
+ return {
811
+ intents: !skipOpen ? [
812
+ createIntent3(NavigationAction.Open, {
813
+ activeParts: {
814
+ complementary: "comments"
815
+ }
816
+ })
817
+ ] : void 0
818
+ };
819
+ }),
820
+ createResolver(ThreadAction.ToggleResolved, ({ thread }) => {
821
+ if (thread.status === "active" || thread.status === void 0) {
822
+ thread.status = "resolved";
823
+ } else if (thread.status === "resolved") {
824
+ thread.status = "active";
825
+ }
826
+ const space = getSpace3(thread);
827
+ const spaceId = space?.id;
828
+ return {
829
+ intents: [
830
+ createIntent3(ObservabilityAction.SendEvent, {
831
+ name: "threads.toggle-resolved",
832
+ properties: {
833
+ threadId: thread.id,
834
+ spaceId
835
+ }
836
+ })
837
+ ]
838
+ };
839
+ }),
840
+ createResolver(ThreadAction.Delete, ({ subject, thread }, undo) => {
841
+ const subjectId = fullyQualifiedId5(subject);
842
+ const draft = state.drafts[subjectId];
843
+ if (draft) {
844
+ const index = draft.findIndex((t) => t.id === thread.id);
845
+ if (index !== -1) {
846
+ draft.splice(index, 1);
847
+ return;
903
848
  }
904
849
  }
905
- case ThreadAction.SELECT: {
906
- state.current = intent.data?.current;
850
+ const space = getSpace3(thread);
851
+ if (!space || !subject.threads) {
852
+ return;
853
+ }
854
+ if (!undo) {
855
+ const index = subject.threads.findIndex((t) => t?.id === thread.id);
856
+ const cursor = subject.threads[index]?.anchor;
857
+ if (index !== -1) {
858
+ subject.threads?.splice(index, 1);
859
+ }
860
+ space.db.remove(thread);
907
861
  return {
908
- data: true,
909
- intents: !intent.data?.skipOpen ? [
910
- [
862
+ undoable: {
863
+ message: [
864
+ "thread deleted label",
911
865
  {
912
- action: NavigationAction.OPEN,
913
- data: {
914
- activeParts: {
915
- complementary: "comments"
916
- }
917
- }
866
+ ns: THREAD_PLUGIN
918
867
  }
919
- ]
920
- ] : []
868
+ ],
869
+ data: {
870
+ cursor
871
+ }
872
+ },
873
+ intents: [
874
+ createIntent3(ObservabilityAction.SendEvent, {
875
+ name: "threads.delete",
876
+ properties: {
877
+ threadId: thread.id,
878
+ spaceId: space.id
879
+ }
880
+ })
881
+ ]
921
882
  };
922
- }
923
- case ThreadAction.TOGGLE_RESOLVED: {
924
- const { thread } = intent.data ?? {};
925
- if (!(thread instanceof ThreadType2)) {
926
- return;
927
- }
928
- if (thread.status === "active" || thread.status === void 0) {
929
- thread.status = "resolved";
930
- } else if (thread.status === "resolved") {
931
- thread.status = "active";
932
- }
933
- const space = getSpace3(thread);
934
- const spaceId = space?.id;
883
+ } else {
884
+ const savedThread = space.db.add(thread);
885
+ subject.threads.push(savedThread);
935
886
  return {
936
- data: true,
937
887
  intents: [
938
- [
939
- {
940
- action: ObservabilityAction.SEND_EVENT,
941
- data: {
942
- name: "threads.toggle-resolved",
943
- properties: {
944
- threadId: thread.id,
945
- spaceId
946
- }
947
- }
888
+ createIntent3(ObservabilityAction.SendEvent, {
889
+ name: "threads.undo-delete",
890
+ properties: {
891
+ threadId: thread.id,
892
+ spaceId: space.id
948
893
  }
949
- ]
894
+ })
950
895
  ]
951
896
  };
952
897
  }
953
- case ThreadAction.DELETE: {
954
- const { subject, thread } = intent.data ?? {};
955
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
956
- return;
957
- }
958
- const subjectId = fullyQualifiedId5(subject);
959
- const draft = state.drafts[subjectId];
960
- if (draft) {
961
- const index = draft.findIndex((t) => t.id === thread.id);
962
- if (index !== -1) {
963
- draft.splice(index, 1);
964
- return {
965
- data: true
966
- };
967
- }
898
+ }),
899
+ createResolver(ThreadAction.OnMessageAdd, ({ thread, subject }) => {
900
+ const subjectId = fullyQualifiedId5(subject);
901
+ const space = getSpace3(subject);
902
+ const intents = [];
903
+ const analyticsProperties = {
904
+ threadId: thread.id,
905
+ spaceId: space?.id
906
+ };
907
+ if (state.drafts[subjectId]?.find((t) => t === thread)) {
908
+ thread.status = "active";
909
+ subject.threads ? subject.threads.push(makeRef2(thread)) : subject.threads = [
910
+ makeRef2(thread)
911
+ ];
912
+ state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
913
+ intents.push(createIntent3(ObservabilityAction.SendEvent, {
914
+ name: "threads.thread-created",
915
+ properties: analyticsProperties
916
+ }));
917
+ }
918
+ intents.push(createIntent3(ObservabilityAction.SendEvent, {
919
+ name: "threads.message-added",
920
+ properties: {
921
+ ...analyticsProperties,
922
+ threadLength: thread.messages.length
968
923
  }
969
- const space = getSpace3(thread);
970
- if (!space || !subject.threads) {
924
+ }));
925
+ return {
926
+ intents
927
+ };
928
+ }),
929
+ createResolver(ThreadAction.DeleteMessage, ({ subject, thread, messageId, message, messageIndex }, undo) => {
930
+ const space = getSpace3(subject);
931
+ if (!undo) {
932
+ const messageIndex2 = thread.messages.findIndex(Ref2.hasObjectId(messageId));
933
+ const message2 = thread.messages[messageIndex2]?.target;
934
+ if (!message2) {
971
935
  return;
972
936
  }
973
- if (!intent.undo) {
974
- const index = subject.threads.findIndex((t) => t?.id === thread.id);
975
- const cursor = subject.threads[index]?.anchor;
976
- if (index !== -1) {
977
- subject.threads?.splice(index, 1);
978
- }
979
- space.db.remove(thread);
980
- return {
981
- undoable: {
982
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["thread deleted label"],
983
- data: {
984
- cursor
985
- }
986
- },
987
- intents: [
988
- [
989
- {
990
- action: ObservabilityAction.SEND_EVENT,
991
- data: {
992
- name: "threads.delete",
993
- properties: {
994
- threadId: thread.id,
995
- spaceId: space.id
996
- }
997
- }
998
- }
999
- ]
1000
- ]
1001
- };
1002
- } else if (intent.undo) {
1003
- const savedThread = space.db.add(thread);
1004
- subject.threads.push(savedThread);
937
+ if (messageIndex2 === 0 && thread.messages.length === 1) {
1005
938
  return {
1006
- data: true,
1007
939
  intents: [
1008
- [
1009
- {
1010
- action: ObservabilityAction.SEND_EVENT,
1011
- data: {
1012
- name: "threads.undo-delete",
1013
- properties: {
1014
- threadId: thread.id,
1015
- spaceId: space.id
1016
- }
1017
- }
1018
- }
1019
- ]
940
+ createIntent3(ThreadAction.Delete, {
941
+ subject,
942
+ thread
943
+ })
1020
944
  ]
1021
945
  };
946
+ } else {
947
+ thread.messages.splice(messageIndex2, 1);
1022
948
  }
1023
- break;
1024
- }
1025
- case ThreadAction.ON_MESSAGE_ADD: {
1026
- const { thread, subject } = intent.data ?? {};
1027
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
1028
- return;
1029
- }
1030
- const subjectId = fullyQualifiedId5(subject);
1031
- const space = getSpace3(subject);
1032
- const intents = [];
1033
- const analyticsProperties = {
1034
- threadId: thread.id,
1035
- spaceId: space?.id
1036
- };
1037
- if (state.drafts[subjectId]?.find((t) => t === thread)) {
1038
- thread.status = "active";
1039
- subject.threads ? subject.threads.push(thread) : subject.threads = [
1040
- thread
1041
- ];
1042
- state.drafts[subjectId] = state.drafts[subjectId]?.filter(({ id }) => id !== thread.id);
1043
- intents.push({
1044
- action: ObservabilityAction.SEND_EVENT,
949
+ return {
950
+ undoable: {
951
+ message: [
952
+ "message deleted label",
953
+ {
954
+ ns: THREAD_PLUGIN
955
+ }
956
+ ],
1045
957
  data: {
1046
- name: "threads.thread-created",
1047
- properties: analyticsProperties
1048
- }
1049
- });
1050
- }
1051
- intents.push({
1052
- action: ObservabilityAction.SEND_EVENT,
1053
- data: {
1054
- name: "threads.message-added",
1055
- properties: {
1056
- ...analyticsProperties,
1057
- threadLength: thread.messages.length
958
+ message: message2,
959
+ messageIndex: messageIndex2
1058
960
  }
1059
- }
1060
- });
1061
- return {
1062
- data: thread,
961
+ },
1063
962
  intents: [
1064
- intents
963
+ createIntent3(ObservabilityAction.SendEvent, {
964
+ name: "threads.message.delete",
965
+ properties: {
966
+ threadId: thread.id,
967
+ spaceId: space?.id
968
+ }
969
+ })
1065
970
  ]
1066
971
  };
1067
- }
1068
- case ThreadAction.DELETE_MESSAGE: {
1069
- const { subject, thread, messageId } = intent.data ?? {};
1070
- const space = getSpace3(subject);
1071
- if (!(thread instanceof ThreadType2) || !(subject && typeof subject === "object" && "threads" in subject)) {
972
+ } else {
973
+ if (!messageIndex || !message) {
1072
974
  return;
1073
975
  }
1074
- if (!intent.undo) {
1075
- const message = thread.messages.find((m) => m?.id === messageId);
1076
- const messageIndex = thread.messages.findIndex((m) => m?.id === messageId);
1077
- if (messageIndex === -1 || !message) {
1078
- return void 0;
1079
- }
1080
- if (messageIndex === 0 && thread.messages.length === 1) {
1081
- return {
1082
- intents: [
1083
- [
1084
- {
1085
- action: ThreadAction.DELETE,
1086
- data: {
1087
- subject,
1088
- thread
1089
- }
1090
- }
1091
- ]
1092
- ]
1093
- };
1094
- } else {
1095
- thread.messages.splice(messageIndex, 1);
1096
- }
1097
- return {
1098
- undoable: {
1099
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["message deleted label"],
1100
- data: {
1101
- message,
1102
- messageIndex
976
+ thread.messages.splice(messageIndex, 0, makeRef2(message));
977
+ return {
978
+ intents: [
979
+ createIntent3(ObservabilityAction.SendEvent, {
980
+ name: "threads.message.undo-delete",
981
+ properties: {
982
+ threadId: thread.id,
983
+ spaceId: space?.id
1103
984
  }
1104
- },
1105
- intents: [
1106
- [
1107
- {
1108
- action: ObservabilityAction.SEND_EVENT,
1109
- data: {
1110
- name: "threads.message.delete",
1111
- properties: {
1112
- threadId: thread.id,
1113
- spaceId: space?.id
1114
- }
1115
- }
1116
- }
1117
- ]
1118
- ]
1119
- };
1120
- } else if (intent.undo) {
1121
- const message = intent.data?.message;
1122
- const messageIndex = intent.data?.messageIndex;
1123
- if (!(message instanceof MessageType2) || !(typeof messageIndex === "number")) {
1124
- return;
1125
- }
1126
- thread.messages.splice(messageIndex, 0, message);
1127
- return {
1128
- data: true,
1129
- intents: [
1130
- [
1131
- {
1132
- action: ObservabilityAction.SEND_EVENT,
1133
- data: {
1134
- name: "threads.message.undo-delete",
1135
- properties: {
1136
- threadId: thread.id,
1137
- spaceId: space?.id
1138
- }
1139
- }
1140
- }
1141
- ]
1142
- ]
1143
- };
1144
- }
985
+ })
986
+ ]
987
+ };
1145
988
  }
1146
- }
1147
- }
989
+ })
990
+ ]
1148
991
  },
1149
992
  markdown: {
1150
993
  extensions: ({ document: doc }) => {
1151
- return threads(state, doc, intentPlugin?.provides.intent.dispatch);
994
+ return threads(state, doc, intentPlugin?.provides.intent.dispatchPromise);
1152
995
  }
1153
996
  }
1154
997
  }