@arbidocs/react 0.5.86 → 0.5.88

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 (117) hide show
  1. package/README.md +2 -3
  2. package/dist/artifacts/index.cjs +46 -48
  3. package/dist/artifacts/index.cjs.map +1 -1
  4. package/dist/artifacts/index.js +7 -9
  5. package/dist/artifacts/index.js.map +1 -1
  6. package/dist/calls/livekit/index.cjs +60 -62
  7. package/dist/calls/livekit/index.cjs.map +1 -1
  8. package/dist/calls/livekit/index.js +6 -8
  9. package/dist/calls/livekit/index.js.map +1 -1
  10. package/dist/{chunk-Z3LLUO32.cjs → chunk-5NOZDH3F.cjs} +12 -2
  11. package/dist/chunk-5NOZDH3F.cjs.map +1 -0
  12. package/dist/{chunk-WQY3RQ6G.js → chunk-73ENECAT.js} +5 -6
  13. package/dist/{chunk-LUDIYWT7.cjs.map → chunk-73ENECAT.js.map} +1 -1
  14. package/dist/{chunk-2Y2WOIHH.cjs → chunk-AOPGD23L.cjs} +60 -148
  15. package/dist/chunk-AOPGD23L.cjs.map +1 -0
  16. package/dist/{chunk-G4Z3IP4J.js → chunk-BF5KW5ZI.js} +3 -17
  17. package/dist/chunk-BF5KW5ZI.js.map +1 -0
  18. package/dist/{chunk-TK7ERJPE.js → chunk-BFNY3RZG.js} +22 -12
  19. package/dist/chunk-BFNY3RZG.js.map +1 -0
  20. package/dist/{chunk-U4PWVSCT.cjs → chunk-C4WODQGO.cjs} +24 -11
  21. package/dist/chunk-C4WODQGO.cjs.map +1 -0
  22. package/dist/{chunk-E7VD5WNY.cjs → chunk-DS7NTSKH.cjs} +41 -74
  23. package/dist/chunk-DS7NTSKH.cjs.map +1 -0
  24. package/dist/{chunk-JT7PN7JH.js → chunk-DU2P354H.js} +6 -37
  25. package/dist/chunk-DU2P354H.js.map +1 -0
  26. package/dist/{chunk-TAVS54EN.cjs → chunk-GKWMT64A.cjs} +6 -6
  27. package/dist/{chunk-TAVS54EN.cjs.map → chunk-GKWMT64A.cjs.map} +1 -1
  28. package/dist/{chunk-AXKHDLBB.cjs → chunk-HEVPIVF2.cjs} +15 -15
  29. package/dist/{chunk-AXKHDLBB.cjs.map → chunk-HEVPIVF2.cjs.map} +1 -1
  30. package/dist/{chunk-XPLD4LFC.js → chunk-KTXZ222T.js} +6 -91
  31. package/dist/chunk-KTXZ222T.js.map +1 -0
  32. package/dist/{chunk-PXWKJI4K.cjs → chunk-LBAG7KL7.cjs} +35 -261
  33. package/dist/chunk-LBAG7KL7.cjs.map +1 -0
  34. package/dist/{chunk-CSPAEVZS.js → chunk-MS43RNXM.js} +5 -5
  35. package/dist/{chunk-CSPAEVZS.js.map → chunk-MS43RNXM.js.map} +1 -1
  36. package/dist/{chunk-OC7F5SNA.cjs → chunk-MXP4O4DI.cjs} +5 -5
  37. package/dist/{chunk-OC7F5SNA.cjs.map → chunk-MXP4O4DI.cjs.map} +1 -1
  38. package/dist/{chunk-ZWFMFOGP.cjs → chunk-NDIKMOBJ.cjs} +4 -4
  39. package/dist/{chunk-ZWFMFOGP.cjs.map → chunk-NDIKMOBJ.cjs.map} +1 -1
  40. package/dist/{chunk-XAEVT7ZM.js → chunk-NNAJLY6B.js} +34 -257
  41. package/dist/chunk-NNAJLY6B.js.map +1 -0
  42. package/dist/{chunk-LUDIYWT7.cjs → chunk-QLRDHLWR.cjs} +72 -73
  43. package/dist/chunk-QLRDHLWR.cjs.map +1 -0
  44. package/dist/{chunk-DZUBZ45Y.cjs → chunk-RLSBRZ6Z.cjs} +2 -17
  45. package/dist/chunk-RLSBRZ6Z.cjs.map +1 -0
  46. package/dist/{chunk-VGAA7AFS.js → chunk-S3OGDLDC.js} +4 -13
  47. package/dist/chunk-S3OGDLDC.js.map +1 -0
  48. package/dist/{chunk-NNWMHMEC.js → chunk-UW2SGTI5.js} +3 -3
  49. package/dist/{chunk-NNWMHMEC.js.map → chunk-UW2SGTI5.js.map} +1 -1
  50. package/dist/{chunk-QRCMKEE6.js → chunk-VSCU7K4V.js} +11 -3
  51. package/dist/chunk-VSCU7K4V.js.map +1 -0
  52. package/dist/{chunk-C44GO33B.js → chunk-WL2Y2T47.js} +3 -3
  53. package/dist/{chunk-C44GO33B.js.map → chunk-WL2Y2T47.js.map} +1 -1
  54. package/dist/{chunk-47YVW3J4.js → chunk-YQBDEOVE.js} +4 -4
  55. package/dist/{chunk-47YVW3J4.js.map → chunk-YQBDEOVE.js.map} +1 -1
  56. package/dist/{chunk-Q6U7ALNV.cjs → chunk-ZHXYFJIA.cjs} +44 -54
  57. package/dist/chunk-ZHXYFJIA.cjs.map +1 -0
  58. package/dist/document-tools/core.cjs +100 -110
  59. package/dist/document-tools/core.d.cts +3 -78
  60. package/dist/document-tools/core.d.ts +3 -78
  61. package/dist/document-tools/core.js +5 -7
  62. package/dist/document-tools/index.cjs +102 -112
  63. package/dist/document-tools/index.cjs.map +1 -1
  64. package/dist/document-tools/index.d.cts +2 -2
  65. package/dist/document-tools/index.d.ts +2 -2
  66. package/dist/document-tools/index.js +6 -8
  67. package/dist/document-tools/index.js.map +1 -1
  68. package/dist/index.cjs +1740 -2305
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/{index.d-BDcwpFVa.d.cts → index.d-1_bJB-Yl.d.cts} +1 -58
  71. package/dist/{index.d-BDcwpFVa.d.ts → index.d-1_bJB-Yl.d.ts} +1 -58
  72. package/dist/{index.d-Deqz5-pF.d.ts → index.d-ChaR6kMc.d.cts} +1 -6
  73. package/dist/{index.d-Deqz5-pF.d.cts → index.d-ChaR6kMc.d.ts} +1 -6
  74. package/dist/index.d.cts +184 -1423
  75. package/dist/index.d.ts +184 -1423
  76. package/dist/index.js +281 -799
  77. package/dist/index.js.map +1 -1
  78. package/dist/{query-keys.d-Dm0NL9nr.d.cts → query-keys.d-D6SAUl7S.d.cts} +0 -9
  79. package/dist/{query-keys.d-Dm0NL9nr.d.ts → query-keys.d-D6SAUl7S.d.ts} +0 -9
  80. package/dist/shell/index.cjs +48 -53
  81. package/dist/shell/index.d.cts +1 -1
  82. package/dist/shell/index.d.ts +1 -1
  83. package/dist/shell/index.js +4 -5
  84. package/dist/ui/index.cjs +156 -169
  85. package/dist/ui/index.d.cts +1 -1
  86. package/dist/ui/index.d.ts +1 -1
  87. package/dist/ui/index.js +3 -4
  88. package/dist/viewers/index.cjs +0 -120
  89. package/dist/viewers/index.cjs.map +1 -1
  90. package/dist/viewers/index.d.cts +3 -40
  91. package/dist/viewers/index.d.ts +3 -40
  92. package/dist/viewers/index.js +1 -120
  93. package/dist/viewers/index.js.map +1 -1
  94. package/package.json +3 -3
  95. package/dist/chunk-2Y2WOIHH.cjs.map +0 -1
  96. package/dist/chunk-CPZ36AQS.js +0 -11
  97. package/dist/chunk-CPZ36AQS.js.map +0 -1
  98. package/dist/chunk-DZUBZ45Y.cjs.map +0 -1
  99. package/dist/chunk-E7VD5WNY.cjs.map +0 -1
  100. package/dist/chunk-G4Z3IP4J.js.map +0 -1
  101. package/dist/chunk-JT7PN7JH.js.map +0 -1
  102. package/dist/chunk-PXWKJI4K.cjs.map +0 -1
  103. package/dist/chunk-Q6U7ALNV.cjs.map +0 -1
  104. package/dist/chunk-QRCMKEE6.js.map +0 -1
  105. package/dist/chunk-RCKA7BEF.cjs +0 -14
  106. package/dist/chunk-RCKA7BEF.cjs.map +0 -1
  107. package/dist/chunk-TK7ERJPE.js.map +0 -1
  108. package/dist/chunk-U4PWVSCT.cjs.map +0 -1
  109. package/dist/chunk-VGAA7AFS.js.map +0 -1
  110. package/dist/chunk-VGMMK5OM.cjs +0 -26
  111. package/dist/chunk-VGMMK5OM.cjs.map +0 -1
  112. package/dist/chunk-VGO77X5U.js +0 -22
  113. package/dist/chunk-VGO77X5U.js.map +0 -1
  114. package/dist/chunk-WQY3RQ6G.js.map +0 -1
  115. package/dist/chunk-XAEVT7ZM.js.map +0 -1
  116. package/dist/chunk-XPLD4LFC.js.map +0 -1
  117. package/dist/chunk-Z3LLUO32.cjs.map +0 -1
package/README.md CHANGED
@@ -114,7 +114,6 @@ That's it — three hooks and you have a streaming RAG chat.
114
114
  | `useWorkspaces()` | User's workspaces | Logged in |
115
115
  | `useCurrentWorkspace()` | The selected workspace (`workspaceId`, `workspaceStatus`, its list entry) and my `role` / `isMember` in it | Logged in |
116
116
  | `useActiveConfigId()` | The configuration new work runs with (the chosen one, else the replied-to message's, else the last) | Always |
117
- | `useArbiShellWorkspaces(options)` | Workspaces as shell/gallery view models, the active one, `open(workspace)` (select, then `onOpened`) | Logged in |
118
117
  | `useShellWorkspaces(options)` | Same, over a list and `select` you supply (no provider needed) | Always |
119
118
  | `useDocuments(workspaceId)` | Workspace documents | Workspace selected |
120
119
  | `useConversations(workspaceId)` | Workspace conversations | Workspace selected |
@@ -338,8 +337,8 @@ const contacts = useContacts() // + useInviteContacts(), useCreateContact(), use
338
337
 
339
338
  Form-to-request mappings (`taskComposerToCreateRequest`, `composePersona`, ...) are in
340
339
  `@arbidocs/blocks/agents`. AI usage is reported in **£** (ex VAT), not dollars: use
341
- `formatGbp(n)` (`£0.47`, `£12.40`, whole pounds as `£10`) and the `metered` flag on `useProjectUsage` /
342
- `useProjectsUsage` (`false` = this deployment does not record usage). The messenger (a
340
+ `formatGbp(n)` (`£0.47`, `£12.40`, whole pounds as `£10`) and the `metered` flag on `useProjectUsage`
341
+ (`false` = this deployment does not record usage). The messenger (a
343
342
  side panel, or its list and thread parts on a messages page) is `ConnectedMessenger` in
344
343
  `@arbidocs/blocks/connect`. See `docs/design/blocks-package.md`
345
344
  ("Hooks and mappings a host should not rewrite").
@@ -1,16 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkQ6U7ALNV_cjs = require('../chunk-Q6U7ALNV.cjs');
4
- var chunk2Y2WOIHH_cjs = require('../chunk-2Y2WOIHH.cjs');
3
+ var chunkZHXYFJIA_cjs = require('../chunk-ZHXYFJIA.cjs');
4
+ var chunkAOPGD23L_cjs = require('../chunk-AOPGD23L.cjs');
5
5
  var chunk3AADNIOK_cjs = require('../chunk-3AADNIOK.cjs');
6
- var chunkU4PWVSCT_cjs = require('../chunk-U4PWVSCT.cjs');
7
- var chunkVGMMK5OM_cjs = require('../chunk-VGMMK5OM.cjs');
6
+ var chunkC4WODQGO_cjs = require('../chunk-C4WODQGO.cjs');
8
7
  require('../chunk-N73IMVFF.cjs');
9
- var chunkZWFMFOGP_cjs = require('../chunk-ZWFMFOGP.cjs');
8
+ var chunkNDIKMOBJ_cjs = require('../chunk-NDIKMOBJ.cjs');
10
9
  var chunkVOFNX4P6_cjs = require('../chunk-VOFNX4P6.cjs');
11
- var chunkOC7F5SNA_cjs = require('../chunk-OC7F5SNA.cjs');
12
- require('../chunk-Z3LLUO32.cjs');
13
- require('../chunk-RCKA7BEF.cjs');
10
+ var chunkMXP4O4DI_cjs = require('../chunk-MXP4O4DI.cjs');
11
+ require('../chunk-5NOZDH3F.cjs');
14
12
  require('../chunk-S6A6FSG7.cjs');
15
13
  var react = require('react');
16
14
  var reactQuery = require('@tanstack/react-query');
@@ -272,24 +270,24 @@ var isRefusal = (error) => {
272
270
  return code === 401 || code === 403;
273
271
  };
274
272
  function useArtifactText(docId, options) {
275
- const arbi = chunkVGMMK5OM_cjs.useArbi();
273
+ const arbi = chunkC4WODQGO_cjs.useArbi();
276
274
  const { attempts, baseDelayMs, maxDelayMs } = {
277
275
  ...DEFAULT_ARTIFACT_TEXT_RETRY,
278
276
  ...options?.retry
279
277
  };
280
- const enabled = (options?.enabled ?? true) && chunkZWFMFOGP_cjs.isDocumentId(docId) && arbi.hasWorkspace;
278
+ const enabled = (options?.enabled ?? true) && chunkNDIKMOBJ_cjs.isDocumentId(docId) && arbi.hasWorkspace;
281
279
  const query = reactQuery.useQuery({
282
280
  // Under the shared `parsedDoc` key, so a document's invalidation reaches it too.
283
- queryKey: [...chunkU4PWVSCT_cjs.arbiQueryKeys.parsedDoc(docId ?? "", "marker"), "artifact-text"],
281
+ queryKey: [...chunkC4WODQGO_cjs.arbiQueryKeys.parsedDoc(docId ?? "", "marker"), "artifact-text"],
284
282
  queryFn: async () => {
285
- const { docId: plainId, version } = chunkZWFMFOGP_cjs.parseVersionRef(docId);
283
+ const { docId: plainId, version } = chunkNDIKMOBJ_cjs.parseVersionRef(docId);
286
284
  const parsed = await arbi.documents.getParsedContent(
287
285
  plainId,
288
286
  "marker",
289
287
  version ?? void 0
290
288
  );
291
289
  if (!parsed.chunks?.some((c) => c.content?.trim())) throw new NotParsedYetError();
292
- return chunkZWFMFOGP_cjs.flattenChunks(parsed.chunks, { unescape: true });
290
+ return chunkNDIKMOBJ_cjs.flattenChunks(parsed.chunks, { unescape: true });
293
291
  },
294
292
  enabled,
295
293
  retry: (failureCount, error) => !isRefusal(error) && failureCount < attempts,
@@ -327,22 +325,22 @@ function useArtifactText(docId, options) {
327
325
 
328
326
  // src/artifacts/useArtifactSession.ts
329
327
  function useArtifactVersions(workspaceId, docId) {
330
- const plainId = docId ? chunkZWFMFOGP_cjs.parseVersionRef(docId).docId : null;
331
- const { data: documents } = chunkQ6U7ALNV_cjs.useDocuments(workspaceId);
328
+ const plainId = docId ? chunkNDIKMOBJ_cjs.parseVersionRef(docId).docId : null;
329
+ const { data: documents } = chunkZHXYFJIA_cjs.useDocuments(workspaceId);
332
330
  const listed = react.useMemo(
333
331
  () => (documents ?? []).find((d) => d.external_id === plainId),
334
332
  [documents, plainId]
335
333
  );
336
- const { data: history } = chunk2Y2WOIHH_cjs.useDocumentVersionList(plainId, {
334
+ const { data: history } = chunkAOPGD23L_cjs.useDocumentVersionList(plainId, {
337
335
  enabled: !!plainId && documents !== void 0 && !listed
338
336
  });
339
337
  return react.useMemo(
340
- () => listed ? chunkZWFMFOGP_cjs.documentVersions(listed) : chunkZWFMFOGP_cjs.toArtifactVersions(plainId, history),
338
+ () => listed ? chunkNDIKMOBJ_cjs.documentVersions(listed) : chunkNDIKMOBJ_cjs.toArtifactVersions(plainId, history),
341
339
  [listed, history, plainId]
342
340
  );
343
341
  }
344
342
  function useSaveArtifactVersion() {
345
- const arbi = chunkVGMMK5OM_cjs.useArbi();
343
+ const arbi = chunkC4WODQGO_cjs.useArbi();
346
344
  const queryClient = reactQuery.useQueryClient();
347
345
  return reactQuery.useMutation({
348
346
  mutationFn: async ({ title, content, versionOf, configId, wpType }) => {
@@ -352,15 +350,15 @@ function useSaveArtifactVersion() {
352
350
  fileName,
353
351
  {
354
352
  wpType: wpType ?? "artifact",
355
- versionOf: versionOf ? chunkZWFMFOGP_cjs.parseVersionRef(versionOf).docId : void 0,
353
+ versionOf: versionOf ? chunkNDIKMOBJ_cjs.parseVersionRef(versionOf).docId : void 0,
356
354
  configExtId: configId ?? void 0
357
355
  }
358
356
  );
359
357
  const docId = result.doc_ext_ids?.[0];
360
- if (docId) await chunkQ6U7ALNV_cjs.refreshDocuments(queryClient, arbi, [docId]);
361
- await queryClient.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.allDocumentVersions() });
358
+ if (docId) await chunkZHXYFJIA_cjs.refreshDocuments(queryClient, arbi, [docId]);
359
+ await queryClient.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.allDocumentVersions() });
362
360
  if (docId)
363
- await queryClient.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.parsedDocument(docId) });
361
+ await queryClient.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.parsedDocument(docId) });
364
362
  return { docId, version: result.version ?? void 0 };
365
363
  }
366
364
  });
@@ -380,7 +378,7 @@ function useArtifactSession(options) {
380
378
  const [saved, setSaved] = react.useState(null);
381
379
  const adopted = saved && saved.forId === hostDocId ? saved : null;
382
380
  const docId = adopted?.id ?? hostDocId;
383
- const isLocal = !chunkZWFMFOGP_cjs.isDocumentId(docId);
381
+ const isLocal = !chunkNDIKMOBJ_cjs.isDocumentId(docId);
384
382
  const [ownCompareId, setOwnCompareId] = react.useState(null);
385
383
  const activeCompareId = compareId === void 0 ? ownCompareId : compareId;
386
384
  const changeCompare = react.useCallback(
@@ -396,7 +394,7 @@ function useArtifactSession(options) {
396
394
  enabled: !!activeCompareId
397
395
  });
398
396
  const saveVersion = useSaveArtifactVersion();
399
- const current = chunkZWFMFOGP_cjs.findVersion(versions, docId);
397
+ const current = chunkNDIKMOBJ_cjs.findVersion(versions, docId);
400
398
  const save = react.useCallback(
401
399
  async (content) => {
402
400
  const result = await saveVersion.mutateAsync({
@@ -412,7 +410,7 @@ function useArtifactSession(options) {
412
410
  );
413
411
  const handleSaved = react.useCallback(
414
412
  (result, content) => {
415
- if (!chunkZWFMFOGP_cjs.isDocumentId(hostDocId) && result.docId)
413
+ if (!chunkNDIKMOBJ_cjs.isDocumentId(hostDocId) && result.docId)
416
414
  setSaved({ forId: hostDocId, id: result.docId, text: content });
417
415
  onSaved?.(result, content);
418
416
  },
@@ -441,7 +439,7 @@ function useArtifactSession(options) {
441
439
  isLoading,
442
440
  status,
443
441
  versions,
444
- labelOf: (id) => chunkZWFMFOGP_cjs.versionLabel(versions, id),
442
+ labelOf: (id) => chunkNDIKMOBJ_cjs.versionLabel(versions, id),
445
443
  view: {
446
444
  content: session.baseline,
447
445
  isEditing: session.isEditing,
@@ -477,16 +475,16 @@ function useArtifactSession(options) {
477
475
  );
478
476
  }
479
477
  function useArtifactSource(documentId, enabled = true) {
480
- const arbi = chunkVGMMK5OM_cjs.useArbi();
478
+ const arbi = chunkC4WODQGO_cjs.useArbi();
481
479
  return reactQuery.useQuery({
482
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.artifactSource(documentId ?? ""),
480
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.artifactSource(documentId ?? ""),
483
481
  queryFn: async () => (await arbi.documents.download(documentId)).text(),
484
482
  enabled: enabled && !!documentId && arbi.isLoggedIn,
485
483
  staleTime: 5 * 60 * 1e3
486
484
  });
487
485
  }
488
486
  function renderArtifactMarkdown(markdown, components) {
489
- return /* @__PURE__ */ jsxRuntime.jsx(chunkOC7F5SNA_cjs.MarkdownRenderer, { components, children: markdown });
487
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkMXP4O4DI_cjs.MarkdownRenderer, { components, children: markdown });
490
488
  }
491
489
  function useStreamedArtifact({
492
490
  artifacts,
@@ -506,7 +504,7 @@ function useStreamedArtifact({
506
504
  const started = react.useRef(null);
507
505
  const content = artifact?.content ?? "";
508
506
  const title = artifact?.title ?? "Draft";
509
- const passThrough = !!artifact && chunkZWFMFOGP_cjs.isDocumentId(artifact.doc_ext_id);
507
+ const passThrough = !!artifact && chunkNDIKMOBJ_cjs.isDocumentId(artifact.doc_ext_id);
510
508
  const needsSave = settled && !!artifact && !passThrough && !!content.trim() && !!workspaceId;
511
509
  react.useEffect(() => {
512
510
  const key = `${attempt}:${content}`;
@@ -516,7 +514,7 @@ function useStreamedArtifact({
516
514
  let stored;
517
515
  if (clean) stored = clean(content);
518
516
  else {
519
- const report = chunkZWFMFOGP_cjs.cleanDraftWithReport(content);
517
+ const report = chunkNDIKMOBJ_cjs.cleanDraftWithReport(content);
520
518
  stored = report.text;
521
519
  setCleaned(report);
522
520
  onCleaned?.(report);
@@ -583,71 +581,71 @@ Object.defineProperty(exports, "revertRedlineRegion", {
583
581
  });
584
582
  Object.defineProperty(exports, "cleanDraftMarkdown", {
585
583
  enumerable: true,
586
- get: function () { return chunkZWFMFOGP_cjs.cleanDraftMarkdown; }
584
+ get: function () { return chunkNDIKMOBJ_cjs.cleanDraftMarkdown; }
587
585
  });
588
586
  Object.defineProperty(exports, "cleanDraftWithReport", {
589
587
  enumerable: true,
590
- get: function () { return chunkZWFMFOGP_cjs.cleanDraftWithReport; }
588
+ get: function () { return chunkNDIKMOBJ_cjs.cleanDraftWithReport; }
591
589
  });
592
590
  Object.defineProperty(exports, "documentVersions", {
593
591
  enumerable: true,
594
- get: function () { return chunkZWFMFOGP_cjs.documentVersions; }
592
+ get: function () { return chunkNDIKMOBJ_cjs.documentVersions; }
595
593
  });
596
594
  Object.defineProperty(exports, "findVersion", {
597
595
  enumerable: true,
598
- get: function () { return chunkZWFMFOGP_cjs.findVersion; }
596
+ get: function () { return chunkNDIKMOBJ_cjs.findVersion; }
599
597
  });
600
598
  Object.defineProperty(exports, "flattenChunks", {
601
599
  enumerable: true,
602
- get: function () { return chunkZWFMFOGP_cjs.flattenChunks; }
600
+ get: function () { return chunkNDIKMOBJ_cjs.flattenChunks; }
603
601
  });
604
602
  Object.defineProperty(exports, "isDocumentId", {
605
603
  enumerable: true,
606
- get: function () { return chunkZWFMFOGP_cjs.isDocumentId; }
604
+ get: function () { return chunkNDIKMOBJ_cjs.isDocumentId; }
607
605
  });
608
606
  Object.defineProperty(exports, "parseVersionRef", {
609
607
  enumerable: true,
610
- get: function () { return chunkZWFMFOGP_cjs.parseVersionRef; }
608
+ get: function () { return chunkNDIKMOBJ_cjs.parseVersionRef; }
611
609
  });
612
610
  Object.defineProperty(exports, "promoteBoldTitle", {
613
611
  enumerable: true,
614
- get: function () { return chunkZWFMFOGP_cjs.promoteBoldTitle; }
612
+ get: function () { return chunkNDIKMOBJ_cjs.promoteBoldTitle; }
615
613
  });
616
614
  Object.defineProperty(exports, "repairParsedStructure", {
617
615
  enumerable: true,
618
- get: function () { return chunkZWFMFOGP_cjs.repairParsedStructure; }
616
+ get: function () { return chunkNDIKMOBJ_cjs.repairParsedStructure; }
619
617
  });
620
618
  Object.defineProperty(exports, "repairParsedTitle", {
621
619
  enumerable: true,
622
- get: function () { return chunkZWFMFOGP_cjs.repairParsedTitle; }
620
+ get: function () { return chunkNDIKMOBJ_cjs.repairParsedTitle; }
623
621
  });
624
622
  Object.defineProperty(exports, "savedFromId", {
625
623
  enumerable: true,
626
- get: function () { return chunkZWFMFOGP_cjs.savedFromId; }
624
+ get: function () { return chunkNDIKMOBJ_cjs.savedFromId; }
627
625
  });
628
626
  Object.defineProperty(exports, "stripAgentPreamble", {
629
627
  enumerable: true,
630
- get: function () { return chunkZWFMFOGP_cjs.stripAgentPreamble; }
628
+ get: function () { return chunkNDIKMOBJ_cjs.stripAgentPreamble; }
631
629
  });
632
630
  Object.defineProperty(exports, "toArtifactVersions", {
633
631
  enumerable: true,
634
- get: function () { return chunkZWFMFOGP_cjs.toArtifactVersions; }
632
+ get: function () { return chunkNDIKMOBJ_cjs.toArtifactVersions; }
635
633
  });
636
634
  Object.defineProperty(exports, "unescapeMarkdown", {
637
635
  enumerable: true,
638
- get: function () { return chunkZWFMFOGP_cjs.unescapeMarkdown; }
636
+ get: function () { return chunkNDIKMOBJ_cjs.unescapeMarkdown; }
639
637
  });
640
638
  Object.defineProperty(exports, "unwrapCitationLinks", {
641
639
  enumerable: true,
642
- get: function () { return chunkZWFMFOGP_cjs.unwrapCitationLinks; }
640
+ get: function () { return chunkNDIKMOBJ_cjs.unwrapCitationLinks; }
643
641
  });
644
642
  Object.defineProperty(exports, "versionLabel", {
645
643
  enumerable: true,
646
- get: function () { return chunkZWFMFOGP_cjs.versionLabel; }
644
+ get: function () { return chunkNDIKMOBJ_cjs.versionLabel; }
647
645
  });
648
646
  Object.defineProperty(exports, "versionRef", {
649
647
  enumerable: true,
650
- get: function () { return chunkZWFMFOGP_cjs.versionRef; }
648
+ get: function () { return chunkNDIKMOBJ_cjs.versionRef; }
651
649
  });
652
650
  Object.defineProperty(exports, "normalizeMarkdown", {
653
651
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/artifacts/redline-engine.ts","../../src/artifacts/useRedline.ts","../../src/artifacts/useArtifactEditSession.ts","../../src/artifacts/useArtifactText.ts","../../src/artifacts/useArtifactSession.ts","../../src/artifacts/useArtifactSource.ts","../../src/artifacts/renderArtifactMarkdown.tsx","../../src/artifacts/useStreamedArtifact.ts","../../src/artifacts/artifact-kind.ts"],"names":["buildHybridRedlineMarkdown","buildHybridRedlineWithRegions","revertRedlineRegion","useState","useRef","useEffect","normalizeMarkdown","useCallback","useMemo","savedFromId","content","useArbi","isDocumentId","useQuery","arbiQueryKeys","parseVersionRef","flattenChunks","useDocuments","useDocumentVersionList","documentVersions","toArtifactVersions","useQueryClient","useMutation","refreshDocuments","findVersion","versionLabel","jsx","MarkdownRenderer","cleanDraftWithReport"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n buildHybridRedlineMarkdown,\n buildHybridRedlineWithRegions,\n revertRedlineRegion,\n type RedlineWithRegions,\n} from './redline-diff'\n\n/**\n * Where a redline is computed. The default runs on the calling thread; a host with large\n * documents passes an engine backed by a Web Worker (for example a Comlink proxy exposing the same\n * three functions) so typing never waits on a diff.\n */\nexport interface RedlineEngine {\n buildRedline(baseText: string, compareText: string): string | Promise<string>\n buildRedlineWithRegions(\n baseText: string,\n compareText: string\n ): RedlineWithRegions | Promise<RedlineWithRegions>\n revertRegion(baseText: string, compareText: string, regionId: string): string | Promise<string>\n}\n\n/** Main-thread engine: the pure functions of `redline-diff`. */\nexport const mainThreadRedlineEngine: RedlineEngine = {\n buildRedline: buildHybridRedlineMarkdown,\n buildRedlineWithRegions: buildHybridRedlineWithRegions,\n revertRegion: revertRedlineRegion,\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { RedlineRegion } from './redline-diff'\nimport { normalizeMarkdown } from './normalize-markdown'\nimport { mainThreadRedlineEngine, type RedlineEngine } from './redline-engine'\n\n/** What a redline view can show. Mirrors the status parts of `@arbidocs/blocks/artifacts`. */\nexport type RedlineState =\n | { kind: 'idle' }\n | { kind: 'computing' }\n | { kind: 'ready'; markdown: string; regions: RedlineRegion[] }\n | { kind: 'identical' }\n | { kind: 'unavailable' }\n\nexport interface UseRedlineOptions {\n /** The older side. `null` means the text could not be loaded; `undefined` means not chosen. */\n baseText: string | null | undefined\n /** The newer side (a loaded version, or the live edit buffer). */\n compareText: string | null | undefined\n /** Either text is still being fetched. */\n isLoading?: boolean\n /** Defaults to the main thread; pass a worker-backed engine for big documents. */\n engine?: RedlineEngine\n}\n\nexport interface UseRedlineResult {\n state: RedlineState\n /** Undo one change: resolves with the compare text rebuilt without it (null if nothing changed). */\n revertRegion: (regionId: string) => Promise<string | null>\n}\n\n/**\n * Track-changes between two texts. Stale results are dropped when the inputs change mid-compute,\n * and a failed diff reports `unavailable` instead of throwing into the render.\n */\nexport function useRedline({\n baseText,\n compareText,\n isLoading = false,\n engine = mainThreadRedlineEngine,\n}: UseRedlineOptions): UseRedlineResult {\n const [state, setState] = useState<RedlineState>({ kind: 'idle' })\n const requestIdRef = useRef(0)\n\n useEffect(() => {\n if (baseText === undefined || compareText === undefined) {\n setState({ kind: 'idle' })\n return\n }\n if (isLoading) {\n setState({ kind: 'computing' })\n return\n }\n if (baseText === null || compareText === null) {\n setState({ kind: 'unavailable' })\n return\n }\n if (\n baseText === compareText ||\n normalizeMarkdown(baseText) === normalizeMarkdown(compareText)\n ) {\n setState({ kind: 'identical' })\n return\n }\n\n const id = ++requestIdRef.current\n let cancelled = false\n setState({ kind: 'computing' })\n // Every change carries a stable id, so a view can offer per-change undo.\n Promise.resolve(engine.buildRedlineWithRegions(baseText, compareText))\n .then((result) => {\n if (cancelled || id !== requestIdRef.current) return\n setState({ kind: 'ready', markdown: result.markdown, regions: result.regions })\n })\n .catch(() => {\n if (cancelled || id !== requestIdRef.current) return\n setState({ kind: 'unavailable' })\n })\n return () => {\n cancelled = true\n }\n }, [baseText, compareText, isLoading, engine])\n\n // The latest texts, so `revertRegion` stays referentially stable while the user types.\n const latest = useRef({ baseText, compareText })\n useEffect(() => {\n latest.current = { baseText, compareText }\n }, [baseText, compareText])\n\n const revertRegion = useCallback(\n async (regionId: string): Promise<string | null> => {\n const { baseText: base, compareText: compare } = latest.current\n if (!base || !compare) return null\n try {\n const next = await engine.revertRegion(base, compare, regionId)\n return next !== normalizeMarkdown(compare) ? next : null\n } catch {\n return null\n }\n },\n [engine]\n )\n\n return useMemo(() => ({ state, revertRegion }), [state, revertRegion])\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { normalizeMarkdown } from './normalize-markdown'\nimport { useRedline, type UseRedlineResult } from './useRedline'\nimport type { RedlineEngine } from './redline-engine'\n\n/** What a save reports back. `docId` is the new version when the backend already knows it. */\nexport interface ArtifactSaveResult {\n docId?: string\n /** 1-based number of the version that was just saved (1 for the first save of a draft). */\n version?: number\n}\n\nexport interface ArtifactEditSessionOptions {\n /** The artifact being edited. Changing it discards the buffer and any comparison. */\n docId: string | null | undefined\n /**\n * The saved text of the open version. `undefined` while it loads; whenever it changes the\n * baseline follows it (a version arriving from the realtime channel, a finished stream).\n */\n baseline: string | undefined\n /**\n * A new document the user types from scratch: open straight in the editor, seeded with\n * `initialContent`, instead of showing a read-only view. Read when `docId` changes.\n */\n startEditing?: boolean\n initialContent?: string\n /** The version this one was saved from. Offering \"compare with previous\" needs it. */\n savedFromId?: string | null\n /** Controlled comparison target. Omit for an uncontrolled one the session owns. */\n compareId?: string | null\n onCompareChange?: (id: string | null) => void\n /** The saved text of the compare target (the older side of the diff). */\n compareText?: string | null\n compareLoading?: boolean\n /** Starting a comparison opens the editor with track changes on (default true). */\n compareOpensEditor?: boolean\n /** Persist the buffer as a NEW version. Rejecting keeps the buffer so nothing is lost. */\n save: (content: string) => Promise<ArtifactSaveResult | void>\n onSaved?: (result: ArtifactSaveResult, content: string) => void\n onSaveError?: (error: unknown) => void\n /** Every buffer change (a host keeps a draft store in sync with it). */\n onContentChange?: (content: string) => void\n /** The unsaved-changes flag, for a host that warns before a panel is closed. */\n onDirtyChange?: (dirty: boolean) => void\n /** Where the diff runs. Defaults to the main thread. */\n redlineEngine?: RedlineEngine\n /** Typing is never debounced; the diff trails the buffer by this long. Default 300ms. */\n diffDelayMs?: number\n}\n\nexport interface ArtifactEditSession {\n isEditing: boolean\n /** The saved text of the open version. */\n baseline: string\n /** The text in the editor (the baseline until the first edit). */\n content: string\n hasChanges: boolean\n isSaving: boolean\n canCompare: boolean\n compareId: string | null\n showTrackChanges: boolean\n /** Track changes between the compare target and the (debounced) buffer. */\n redline: UseRedlineResult\n startEdit: () => void\n /** Discard the buffer and any comparison; back to the rendered view. */\n cancel: () => void\n /** Save the buffer as a new version. Resolves false when it failed (the buffer is kept). */\n save: () => Promise<boolean>\n /** The editor's `onChange`; also replaces the buffer (for example after an undo-this-change). */\n change: (markdown: string) => void\n /** The editor's `onNormalized`: adopt its canonical form as the baseline so Save does not fire. */\n normalized: (markdown: string) => void\n /** Compare with the previous version (when no id is given). */\n compare: (id?: string) => void\n stopCompare: () => void\n setShowTrackChanges: (show: boolean) => void\n /** Undo one tracked change in the buffer. */\n revertRegion: (regionId: string) => Promise<void>\n}\n\n/**\n * The state machine of an artifact edit session, with no SDK and no network: the edit buffer and\n * its baseline, the dirty flag, immutable-version saves and a track-changes comparison. A host\n * supplies the saved text and a `save` function (see `useArtifactSession` for the SDK binding).\n */\nexport function useArtifactEditSession(options: ArtifactEditSessionOptions): ArtifactEditSession {\n const {\n docId,\n baseline: loadedBaseline,\n startEditing = false,\n initialContent,\n savedFromId,\n compareId: controlledCompareId,\n onCompareChange,\n compareText,\n compareLoading = false,\n compareOpensEditor = true,\n save: persist,\n onSaved,\n onSaveError,\n onContentChange,\n onDirtyChange,\n redlineEngine,\n diffDelayMs = 300,\n } = options\n\n const [isEditing, setIsEditing] = useState(false)\n const [baseline, setBaseline] = useState('')\n const [buffer, setBuffer] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n const [showTrackChanges, setShowTrackChanges] = useState(false)\n const [ownCompareId, setOwnCompareId] = useState<string | null>(null)\n const controlled = controlledCompareId !== undefined\n const compareId = controlled ? controlledCompareId : ownCompareId\n\n const setCompareId = useCallback(\n (id: string | null) => {\n if (!controlled) setOwnCompareId(id)\n onCompareChange?.(id)\n },\n [controlled, onCompareChange]\n )\n\n // The latest values for callbacks that must not change identity while the user types.\n const latest = useRef({ buffer, baseline, isEditing, initialContent })\n latest.current = { buffer, baseline, isEditing, initialContent }\n\n // The baseline follows the loaded text. A draft has none and seeds itself below.\n useEffect(() => {\n if (loadedBaseline !== undefined) setBaseline(loadedBaseline)\n }, [loadedBaseline])\n\n // Another artifact: drop stale edits and comparison. A new typed document starts in the editor.\n useEffect(() => {\n if (startEditing) {\n const seed = latest.current.initialContent ?? ''\n setIsEditing(true)\n setBaseline(seed)\n setBuffer(seed)\n } else {\n setIsEditing(false)\n setBuffer('')\n }\n setCompareId(null)\n setShowTrackChanges(false)\n // Only the identity of the artifact resets the session.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [docId])\n\n const startEdit = useCallback(() => {\n setBuffer(latest.current.baseline)\n setIsEditing(true)\n }, [])\n\n const stopCompare = useCallback(() => {\n setCompareId(null)\n setShowTrackChanges(false)\n }, [setCompareId])\n\n const cancel = useCallback(() => {\n setIsEditing(false)\n setBuffer('')\n stopCompare()\n }, [stopCompare])\n\n const compare = useCallback(\n (id?: string) => {\n const target = id ?? savedFromId\n if (target) setCompareId(target)\n },\n [savedFromId, setCompareId]\n )\n\n // Comparing and editing are one surface: a comparison opens the editor with the diff showing,\n // like Word's Compare yields tracked changes you can keep typing through.\n const hasBaseline = baseline !== ''\n useEffect(() => {\n if (!compareId || !compareOpensEditor || !hasBaseline) return\n if (!latest.current.isEditing) startEdit()\n setShowTrackChanges(true)\n }, [compareId, compareOpensEditor, hasBaseline, startEdit])\n\n const save = useCallback(async (): Promise<boolean> => {\n // Persist the canonical spelling so the editor's gratuitous escapes never reach a version.\n const raw = latest.current.buffer\n const normalised = normalizeMarkdown(raw)\n const content = raw.endsWith('\\n') ? normalised : normalised.replace(/\\n$/, '')\n setIsSaving(true)\n try {\n const result = (await persist(content)) ?? {}\n setBaseline(content)\n setIsEditing(false)\n stopCompare()\n onSaved?.(result, content)\n return true\n } catch (error) {\n onSaveError?.(error)\n return false\n } finally {\n setIsSaving(false)\n }\n }, [persist, stopCompare, onSaved, onSaveError])\n\n const content = buffer || baseline\n const hasChanges = isEditing && !!buffer && buffer !== baseline\n useEffect(() => {\n onDirtyChange?.(hasChanges)\n return () => onDirtyChange?.(false)\n }, [hasChanges, onDirtyChange])\n\n const setContent = useCallback(\n (markdown: string) => {\n setBuffer(markdown)\n onContentChange?.(markdown)\n },\n [onContentChange]\n )\n const normalized = useCallback((markdown: string) => {\n setBaseline(markdown)\n setBuffer(markdown)\n }, [])\n\n // The diff trails the buffer so it runs on a settled text.\n const [diffContent, setDiffContent] = useState(content)\n useEffect(() => {\n const id = setTimeout(() => setDiffContent(content), diffDelayMs)\n return () => clearTimeout(id)\n }, [content, diffDelayMs])\n\n const redline = useRedline({\n baseText: compareId ? compareText : undefined,\n compareText: compareId ? diffContent || baseline : undefined,\n isLoading: compareLoading,\n engine: redlineEngine,\n })\n const { revertRegion: revertInRedline } = redline\n const revertRegion = useCallback(\n async (regionId: string): Promise<void> => {\n const next = await revertInRedline(regionId)\n if (next !== null) setContent(next)\n },\n [revertInRedline, setContent]\n )\n\n return useMemo(\n () => ({\n isEditing,\n baseline,\n content,\n hasChanges,\n isSaving,\n canCompare: !!savedFromId && !compareId,\n compareId,\n showTrackChanges,\n redline,\n startEdit,\n cancel,\n save,\n change: setContent,\n normalized,\n compare,\n stopCompare,\n setShowTrackChanges,\n revertRegion,\n }),\n [\n isEditing,\n baseline,\n content,\n hasChanges,\n isSaving,\n savedFromId,\n compareId,\n showTrackChanges,\n redline,\n startEdit,\n cancel,\n save,\n setContent,\n normalized,\n compare,\n stopCompare,\n revertRegion,\n ]\n )\n}\n","import { useCallback, useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { flattenChunks, isDocumentId, parseVersionRef } from './versions'\n\n/**\n * Where the text of a stored artifact is:\n * - `loading`: the first request is in flight (or there is no document yet);\n * - `parsing`: the backend has not finished parsing the upload (the endpoint answers 404, 422 or\n * 500, or an empty parse, for a few seconds after an upload) and the hook is retrying;\n * - `ready`: the text is here (an empty document is `ready` with `text: null`);\n * - `error`: the retries ran out, or the request was refused (401/403).\n */\nexport type ArtifactTextStatus = 'loading' | 'parsing' | 'ready' | 'error'\n\n/** How long `useArtifactText` keeps asking while a document is still being parsed. */\nexport interface ArtifactTextRetry {\n /** Retries after the first request. Default 12. */\n attempts?: number\n /** Delay before the first retry; it grows by 1.6x each time. Default 1000 ms. */\n baseDelayMs?: number\n /** Cap for one delay. Default 5000 ms (12 retries are about 50 s in all). */\n maxDelayMs?: number\n}\n\nexport const DEFAULT_ARTIFACT_TEXT_RETRY: Required<ArtifactTextRetry> = {\n attempts: 12,\n baseDelayMs: 1000,\n maxDelayMs: 5000,\n}\n\n/** Thrown inside the query when the parse has no text yet, so that it is retried like a 500. */\nclass NotParsedYetError extends Error {\n constructor() {\n super('The document has no parsed text yet')\n }\n}\n\nconst isRefusal = (error: unknown): boolean => {\n const status = error as { status?: number; response?: { status?: number } } | null\n const code = status?.status ?? status?.response?.status\n return code === 401 || code === 403\n}\n\nexport interface ArtifactText {\n /**\n * The markdown, clean: `undefined` while `loading` or `parsing`, `null` when there is none (an\n * empty document, or `error`).\n */\n text: string | null | undefined\n /** `status` is `loading` or `parsing`. */\n isLoading: boolean\n status: ArtifactTextStatus\n /** The last request error while `parsing` or after `error`. */\n error: Error | null\n /** Ask again now (after an `error`). */\n retry: () => void\n}\n\n/**\n * The saved markdown of an artifact version (its parsed chunks, joined and unescaped).\n *\n * A freshly uploaded document is parsed asynchronously, and for roughly 3 to 20 seconds the parsed\n * content endpoint answers 404, 422 or 500 (or an empty parse). The hook therefore retries with a\n * growing delay (see `ArtifactTextRetry`) and reports `status: 'parsing'` meanwhile, so a host can\n * show \"Preparing editor...\" instead of opening an editor on an empty baseline. After the last\n * retry the status is `error`; `retry()` starts a new round.\n *\n * The text is run through `unescapeMarkdown`: an artifact is always stored from markdown, and the\n * backend's parse of a `.md` escapes its punctuation.\n */\nexport function useArtifactText(\n docId: string | null | undefined,\n options?: { enabled?: boolean; retry?: ArtifactTextRetry }\n): ArtifactText {\n const arbi = useArbi()\n const { attempts, baseDelayMs, maxDelayMs } = {\n ...DEFAULT_ARTIFACT_TEXT_RETRY,\n ...options?.retry,\n }\n // A local draft (placeholder id) has no backend document: asking for its text would be a 422.\n const enabled = (options?.enabled ?? true) && isDocumentId(docId) && arbi.hasWorkspace\n const query = useQuery({\n // Under the shared `parsedDoc` key, so a document's invalidation reaches it too.\n queryKey: [...arbiQueryKeys.parsedDoc(docId ?? '', 'marker'), 'artifact-text'] as const,\n queryFn: async () => {\n // A version reference (`doc-…@v2`) reads that version; a plain id the current one.\n const { docId: plainId, version } = parseVersionRef(docId)\n const parsed = (await arbi.documents.getParsedContent(\n plainId,\n 'marker',\n version ?? undefined\n )) as {\n chunks?: { content?: string | null }[]\n }\n if (!parsed.chunks?.some((c) => c.content?.trim())) throw new NotParsedYetError()\n return flattenChunks(parsed.chunks, { unescape: true })\n },\n enabled,\n retry: (failureCount, error) => !isRefusal(error) && failureCount < attempts,\n retryDelay: (failureCount) => Math.min(baseDelayMs * 1.6 ** failureCount, maxDelayMs),\n })\n\n const { refetch } = query\n const retry = useCallback(() => void refetch(), [refetch])\n\n return useMemo<ArtifactText>(() => {\n const error = query.error\n const neverParsed = error instanceof NotParsedYetError\n let status: ArtifactTextStatus = 'loading'\n if (!enabled) status = 'loading'\n else if (query.isSuccess || (query.isError && neverParsed)) status = 'ready'\n else if (query.isError) status = 'error'\n else if (query.failureCount > 0) status = 'parsing'\n const text = !enabled\n ? undefined\n : query.isSuccess\n ? query.data\n : status === 'ready' || status === 'error'\n ? null\n : undefined\n return {\n text,\n isLoading: enabled && (status === 'loading' || status === 'parsing'),\n status,\n error: status === 'ready' ? null : (error ?? query.failureReason ?? null),\n retry,\n }\n }, [\n enabled,\n query.isSuccess,\n query.isError,\n query.data,\n query.error,\n query.failureCount,\n query.failureReason,\n retry,\n ])\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys, useDocumentVersionList } from '../hooks'\nimport { refreshDocuments, useDocuments } from '../documents/documents-data'\nimport { useArtifactText, type ArtifactTextStatus } from './useArtifactText'\nimport {\n documentVersions,\n findVersion,\n isDocumentId,\n parseVersionRef,\n toArtifactVersions,\n versionLabel,\n type ArtifactVersion,\n} from './versions'\nimport {\n useArtifactEditSession,\n type ArtifactEditSession,\n type ArtifactEditSessionOptions,\n type ArtifactSaveResult,\n} from './useArtifactEditSession'\n\n/**\n * The versions of an artifact, oldest first. `docId` is a document id or a version reference\n * (`doc-…@v2`). Every listed document carries its versions; a document that is not in the\n * workspace list asks for its version list.\n */\nexport function useArtifactVersions(\n workspaceId: string | undefined,\n docId: string | null | undefined\n): ArtifactVersion[] {\n const plainId = docId ? parseVersionRef(docId).docId : null\n const { data: documents } = useDocuments(workspaceId)\n const listed = useMemo(\n () => (documents ?? []).find((d) => d.external_id === plainId),\n [documents, plainId]\n )\n // Asked only once the list has loaded and the document is not in it.\n const { data: history } = useDocumentVersionList(plainId, {\n enabled: !!plainId && documents !== undefined && !listed,\n })\n return useMemo(\n () => (listed ? documentVersions(listed) : toArtifactVersions(plainId, history)),\n [listed, history, plainId]\n )\n}\n\nexport interface SaveArtifactVersionInput {\n /** File name of the new version (`.md` is added when missing). */\n title: string\n content: string\n /** Save as the next version of this document (it keeps its id); omit for a new document. */\n versionOf?: string | null\n /** The processing config (auto-title, parsing) to run the upload with. */\n configId?: string | null\n /** `artifact` (default) for AI-style drafts; `source` for a document the user typed. */\n wpType?: 'artifact' | 'source'\n}\n\n/**\n * Save markdown as a NEW immutable version (the next version of `versionOf`'s document, which keeps\n * its id) and refresh the workspace document list, version lists and the document's text.\n */\nexport function useSaveArtifactVersion() {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n return useMutation<ArtifactSaveResult, Error, SaveArtifactVersionInput>({\n mutationFn: async ({ title, content, versionOf, configId, wpType }) => {\n // The backend classifies uploads by extension: a title without one is silently dropped.\n const fileName = /\\.md$/i.test(title) ? title : `${title}.md`\n const result = await arbi.documents.uploadFile(\n new Blob([content], { type: 'text/markdown' }),\n fileName,\n {\n wpType: wpType ?? 'artifact',\n versionOf: versionOf ? parseVersionRef(versionOf).docId : undefined,\n configExtId: configId ?? undefined,\n }\n )\n const docId = result.doc_ext_ids?.[0]\n // The document's row moves to the new version (its version lists re-read with it).\n if (docId) await refreshDocuments(queryClient, arbi, [docId])\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.allDocumentVersions() })\n // The document's current text is the new version's now.\n if (docId)\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.parsedDocument(docId) })\n return { docId, version: result.version ?? undefined }\n },\n })\n}\n\nexport interface ArtifactSessionOptions extends Pick<\n ArtifactEditSessionOptions,\n | 'onSaved'\n | 'onSaveError'\n | 'onCompareChange'\n | 'compareId'\n | 'compareOpensEditor'\n | 'redlineEngine'\n | 'onDirtyChange'\n> {\n workspaceId: string | undefined\n /**\n * The open document (its current version), a version reference `doc-…@v{n}`, or the placeholder\n * id of an unsaved local draft (anything that is not a backend document id, i.e. does not start\n * with `doc`).\n */\n docId: string | null | undefined\n /**\n * The text of a local draft (nothing is fetched for it). The FIRST save uploads it as a real\n * document with no parent and the session switches to the new id; later saves chain from it.\n */\n draftContent?: string\n /** Name for saved versions. Defaults to the open version's file name, else \"Untitled\". */\n title?: string\n /** Processing config for saved versions. */\n configId?: string | null\n}\n\n/** Everything `ArtifactEditor` (`@arbidocs/blocks/artifacts`) takes from a session, flat. */\nexport interface ArtifactSessionView {\n content: string\n isEditing: boolean\n hasChanges: boolean\n isSaving: boolean\n canCompare: boolean\n comparing: boolean\n compareId: string | null\n showTrackChanges: boolean\n versions: ArtifactVersion[]\n currentVersionId: string\n onStartEdit: () => void\n onCancel: () => void\n onSave: () => void\n onCompare: () => void\n onStopCompare: () => void\n onToggleTrackChanges: () => void\n /**\n * Whether the text is ready. `ArtifactEditor` renders \"Preparing editor...\" while it is\n * `loading` or `parsing` (a fresh upload is parsed for a few seconds) and an error with Retry.\n */\n status: ArtifactTextStatus\n /** Ask for the text again after an `error`. */\n onRetry: () => void\n}\n\nexport interface ArtifactSession extends ArtifactEditSession {\n /** The open document: the new real id once a local draft has been saved. */\n docId: string | null | undefined\n /** The open version is an unsaved local draft (no backend document yet). */\n isLocal: boolean\n isLoading: boolean\n /** See `ArtifactTextStatus`. */\n status: ArtifactTextStatus\n versions: ArtifactVersion[]\n /** \"v2\" for any version (reference) of the document. */\n labelOf: (id: string | null | undefined) => string | null\n /** Props for `<ArtifactEditor>`. */\n view: ArtifactSessionView\n /** Props for `<ArtifactMarkdownEditor>` (`@arbidocs/blocks/artifacts/editor`). */\n editorProps: {\n markdown: string\n onChange: (markdown: string) => void\n onNormalized: (markdown: string) => void\n }\n /** Props for `<ArtifactRedlineView>`. */\n redlineProps: {\n state: ArtifactEditSession['redline']['state']\n onRevert: (regionId: string) => void\n }\n}\n\n/**\n * Edit an artifact through the SDK: load it, edit it, save it as a new version, list its versions\n * and compare any two with track changes. Needs an `<ArbiHost>` with an `arbi` and a selected workspace.\n *\n * ```tsx\n * const session = useArtifactSession({ workspaceId, docId, onSaved: ({ docId }) => docId && open(docId) })\n * <ArtifactEditor {...session.view} onOpenVersion={open}\n * editor={<ArtifactMarkdownEditor {...session.editorProps} />}\n * redline={<ArtifactRedlineView {...session.redlineProps} />} />\n * ```\n */\nexport function useArtifactSession(options: ArtifactSessionOptions): ArtifactSession {\n const {\n workspaceId,\n docId: hostDocId,\n draftContent,\n title,\n configId,\n compareId,\n onCompareChange,\n onSaved,\n ...passthrough\n } = options\n // A saved local draft becomes this real document; another host docId resets it.\n const [saved, setSaved] = useState<{\n forId: string | null | undefined\n id: string\n text: string\n } | null>(null)\n const adopted = saved && saved.forId === hostDocId ? saved : null\n const docId = adopted?.id ?? hostDocId\n const isLocal = !isDocumentId(docId)\n\n // Owned here (not in the edit session) because the compare target's text must be loaded first.\n const [ownCompareId, setOwnCompareId] = useState<string | null>(null)\n const activeCompareId = compareId === undefined ? ownCompareId : compareId\n const changeCompare = useCallback(\n (id: string | null) => {\n setOwnCompareId(id)\n onCompareChange?.(id)\n },\n [onCompareChange]\n )\n\n const { text, isLoading, status, retry } = useArtifactText(docId)\n const versions = useArtifactVersions(workspaceId, isLocal ? null : docId)\n const { text: compareText, isLoading: compareLoading } = useArtifactText(activeCompareId, {\n enabled: !!activeCompareId,\n })\n const saveVersion = useSaveArtifactVersion()\n const current = findVersion(versions, docId)\n\n const save = useCallback(\n async (content: string) => {\n const result = await saveVersion.mutateAsync({\n title: title ?? current?.name ?? 'Untitled',\n content,\n versionOf: isLocal ? null : docId,\n configId,\n })\n const latest = versions.reduce((n, v) => Math.max(n, v.number), 0)\n return { ...result, version: result.version ?? (isLocal ? 1 : latest + 1) }\n },\n [saveVersion, title, current?.name, isLocal, docId, configId, versions]\n )\n\n const handleSaved = useCallback(\n (result: ArtifactSaveResult, content: string) => {\n // A host that keeps passing the local draft's placeholder id: follow every save to the real\n // document it created (the first save creates version 1, later ones chain from it).\n if (!isDocumentId(hostDocId) && result.docId)\n setSaved({ forId: hostDocId, id: result.docId, text: content })\n onSaved?.(result, content)\n },\n [hostDocId, onSaved]\n )\n\n const session = useArtifactEditSession({\n ...passthrough,\n docId,\n // A local draft has only its own text; a just-saved one shows what was saved until the parsed\n // text of the new document arrives.\n baseline: text ?? (isLocal ? draftContent : adopted?.text),\n savedFromId: current?.savedFromId,\n compareId: activeCompareId,\n onCompareChange: changeCompare,\n compareText,\n compareLoading,\n save,\n onSaved: handleSaved,\n })\n\n const { redline } = session\n return useMemo<ArtifactSession>(\n () => ({\n ...session,\n docId,\n isLocal,\n isLoading,\n status,\n versions,\n labelOf: (id) => versionLabel(versions, id),\n view: {\n content: session.baseline,\n isEditing: session.isEditing,\n hasChanges: session.hasChanges,\n isSaving: session.isSaving,\n canCompare: session.canCompare,\n comparing: !!session.compareId,\n compareId: session.compareId,\n showTrackChanges: session.showTrackChanges,\n versions,\n currentVersionId: current?.id ?? docId ?? '',\n onStartEdit: session.startEdit,\n onCancel: session.cancel,\n onSave: () => void session.save(),\n onCompare: () => session.compare(),\n onStopCompare: session.stopCompare,\n onToggleTrackChanges: () => session.setShowTrackChanges(!session.showTrackChanges),\n // A local draft has its text already: it is ready.\n status: isLocal ? 'ready' : status,\n onRetry: retry,\n },\n editorProps: {\n markdown: session.content,\n onChange: session.change,\n onNormalized: session.normalized,\n },\n redlineProps: {\n state: redline.state,\n onRevert: (regionId) => void session.revertRegion(regionId),\n },\n }),\n [session, redline, isLoading, status, retry, isLocal, versions, docId]\n )\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../query-keys'\n\n/**\n * The stored source of a live artifact (the `.html` / `.jsx` file itself; the parsed text strips\n * it). `undefined` until it has loaded.\n */\nexport function useArtifactSource(documentId: string | null | undefined, enabled = true) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.artifactSource(documentId ?? ''),\n queryFn: async () => (await arbi.documents.download(documentId as string)).text(),\n enabled: enabled && !!documentId && arbi.isLoggedIn,\n staleTime: 5 * 60 * 1000,\n })\n}\n","import type { ComponentPropsWithoutRef, FC, ReactNode } from 'react'\nimport { MarkdownRenderer } from '../ai/MarkdownRenderer'\n\n/** The `<del>` / `<ins>` renderers `ArtifactRedlineView` hands to a markdown renderer. */\nexport interface ArtifactRedlineComponents {\n del: FC<ComponentPropsWithoutRef<'del'> & { 'data-cid'?: string }>\n ins: FC<ComponentPropsWithoutRef<'ins'> & { 'data-cid'?: string }>\n}\n\n/**\n * The kit's markdown renderer as the `renderMarkdown` slot of `ArtifactEditor` and\n * `ArtifactRedlineView`: full markdown (tables, lists, code) plus the raw `<del>` / `<ins>` tags\n * of a redline.\n */\nexport function renderArtifactMarkdown(\n markdown: string,\n components?: ArtifactRedlineComponents\n): ReactNode {\n return <MarkdownRenderer components={components}>{markdown}</MarkdownRenderer>\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ArtifactEvent } from '../ai/engine'\nimport { cleanDraftWithReport, type DraftCleanReport } from '../ai/stored-markdown'\nimport { useSaveArtifactVersion } from './useArtifactSession'\nimport { isDocumentId } from './versions'\nimport { useArtifactText, type ArtifactTextRetry } from './useArtifactText'\n\n/**\n * Where a drafted artifact is in its STREAM -> PERSIST -> EDIT life:\n * - `streaming`: the agent is still working (or has produced nothing final): show the live canvas;\n * - `persisting`: the finished draft is being stored as version 1 of the artifact;\n * - `parsing`: stored; the backend is still parsing it, so there is no editable text yet;\n * - `ready`: the text is readable: mount the editor on `docId`;\n * - `error`: storing failed or the parse never produced text (`retry()` starts over).\n */\nexport type StreamedArtifactPhase = 'streaming' | 'persisting' | 'parsing' | 'ready' | 'error'\n\nexport interface UseStreamedArtifactOptions {\n /** The artifacts of the agent run (`useConnectedAiTask().artifacts`). */\n artifacts: ArtifactEvent[]\n workspaceId: string | undefined\n /**\n * The run has stopped: not busy and not failed. Nothing is stored before this, so a draft that\n * is still streaming is never persisted half-written.\n */\n settled: boolean\n /**\n * Make the stored markdown from the streamed content. Default `cleanDraftWithReport`, which is\n * guarded: it stores the raw streamed text (or links-only text) rather than a cleanup that would\n * lose content (see `DraftCleanReport`).\n */\n clean?: (streamed: string) => string\n /** Called once per stored draft with what the cleanup did (`stage` is not `cleaned` if guarded). */\n onCleaned?: (report: DraftCleanReport) => void\n /** Processing config for the stored version. */\n configId?: string | null\n /** How long to wait for the parse (see `useArtifactText`). */\n parseRetry?: ArtifactTextRetry\n}\n\nexport interface StreamedArtifact {\n phase: StreamedArtifactPhase\n /** The finished streamed artifact (its `title` names the stored versions). */\n artifact: ArtifactEvent | undefined\n /** The backend document to edit, once there is one (while `parsing` and `ready`). */\n docId: string | undefined\n error: Error | null\n /** What the cleanup did to the stored draft (`null` until it was stored, or with a custom `clean`). */\n cleaned: DraftCleanReport | null\n /** After an `error`: store again or ask for the parse again. */\n retry: () => void\n}\n\n/**\n * The lifecycle of an agent-drafted artifact, so a host passes the stream and renders the phase.\n *\n * While the agent streams, the draft lives only on the canvas. Once the run is `settled` and the\n * draft is complete, a draft that is not yet a backend document is cleaned (`cleanDraftMarkdown`)\n * and stored ONCE as the artifact's first version (`wpType: 'artifact'`); a draft that already is a\n * backend document passes through. The hook then waits for the parse (`useArtifactText`, which\n * retries) and reports `ready` with the `docId` to open in an editor.\n *\n * Needs an `<ArbiHost>` with an `arbi` and a workspace. `@arbidocs/blocks/connect` has the whole thing as a\n * component (`StreamedArtifact`).\n */\nexport function useStreamedArtifact({\n artifacts,\n workspaceId,\n settled,\n clean,\n onCleaned,\n configId,\n parseRetry,\n}: UseStreamedArtifactOptions): StreamedArtifact {\n const artifact = artifacts.find((a) => a.is_complete)\n const { mutateAsync } = useSaveArtifactVersion()\n const [saved, setSaved] = useState<{ content: string; docId: string } | null>(null)\n const [saveError, setSaveError] = useState<Error | null>(null)\n const [attempt, setAttempt] = useState(0)\n const [cleaned, setCleaned] = useState<DraftCleanReport | null>(null)\n const started = useRef<string | null>(null)\n\n const content = artifact?.content ?? ''\n const title = artifact?.title ?? 'Draft'\n const passThrough = !!artifact && isDocumentId(artifact.doc_ext_id)\n const needsSave = settled && !!artifact && !passThrough && !!content.trim() && !!workspaceId\n\n useEffect(() => {\n const key = `${attempt}:${content}`\n if (!needsSave || started.current === key) return\n started.current = key\n setSaveError(null)\n let stored: string\n if (clean) stored = clean(content)\n else {\n const report = cleanDraftWithReport(content)\n stored = report.text\n setCleaned(report)\n onCleaned?.(report)\n if (report.guarded) {\n console.warn(\n `[useStreamedArtifact] the draft cleanup would have lost content; stored the ${report.stage} text instead (kept ${Math.round(report.ratio * 100)}%, changed by: ${report.changedBy.join(', ') || 'nothing'})`\n )\n }\n }\n mutateAsync({\n title,\n content: stored,\n configId,\n wpType: 'artifact',\n })\n .then((r) => {\n if (r.docId) setSaved({ content, docId: r.docId })\n else setSaveError(new Error('The draft was stored but the server returned no document id'))\n })\n .catch((e: unknown) => setSaveError(e instanceof Error ? e : new Error(String(e))))\n // `clean` and `onCleaned` are deliberately not dependencies: a new function identity must not\n // store twice.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [needsSave, content, title, workspaceId, configId, attempt, mutateAsync])\n\n const docId = !artifact\n ? undefined\n : passThrough\n ? artifact.doc_ext_id\n : saved?.content === content\n ? saved.docId\n : undefined\n\n const text = useArtifactText(docId, { enabled: settled, retry: parseRetry })\n const { retry: retryText } = text\n\n const retry = useCallback(() => {\n if (saveError) setAttempt((n) => n + 1)\n else retryText()\n }, [saveError, retryText])\n\n let phase: StreamedArtifactPhase\n if (!settled || !artifact) phase = 'streaming'\n else if (saveError) phase = 'error'\n else if (!docId) phase = needsSave ? 'persisting' : 'streaming'\n else if (text.status === 'ready' && text.text) phase = 'ready'\n else if (text.status === 'error' || text.status === 'ready') phase = 'error'\n else phase = 'parsing'\n\n const error =\n phase !== 'error'\n ? null\n : (saveError ?? text.error ?? new Error('The document has no text to edit'))\n return { phase, artifact, docId, error, cleaned, retry }\n}\n","/**\n * Which live renderer, if any, an artifact maps to. Kept free of heavy imports (no compiler) so the\n * document viewer can use it without pulling the preview code into its bundle.\n *\n * The backend persists an artifact's render mode in the saved file's extension: .html / .jsx are live\n * artifacts; document drafts are stored as .docx and open in the Word editor.\n */\nexport type ArtifactPreviewKind = 'html' | 'react'\n\nexport function artifactKindFromFileName(fileName?: string | null): ArtifactPreviewKind | null {\n const ext = (fileName ?? '').toLowerCase().match(/\\.[a-z0-9]+$/)?.[0]\n if (ext === '.html' || ext === '.htm') return 'html'\n if (ext === '.jsx') return 'react'\n return null\n}\n\nexport function artifactKindFromMode(mode?: string | null): ArtifactPreviewKind | null {\n return mode === 'html' || mode === 'react' ? mode : null\n}\n\n/**\n * The viewer tab an artifact opens on: a generated image on its media view ('pdf'), an html/react\n * artifact on its rendered Preview, and a document draft (stored as .docx) in the Word editor.\n */\nexport function viewerTabForArtifactMode(mode?: string | null): 'pdf' | 'preview' | 'edit' {\n if (mode === 'image') return 'pdf'\n return artifactKindFromMode(mode) ? 'preview' : 'edit'\n}\n"]}
1
+ {"version":3,"sources":["../../src/artifacts/redline-engine.ts","../../src/artifacts/useRedline.ts","../../src/artifacts/useArtifactEditSession.ts","../../src/artifacts/useArtifactText.ts","../../src/artifacts/useArtifactSession.ts","../../src/artifacts/useArtifactSource.ts","../../src/artifacts/renderArtifactMarkdown.tsx","../../src/artifacts/useStreamedArtifact.ts","../../src/artifacts/artifact-kind.ts"],"names":["buildHybridRedlineMarkdown","buildHybridRedlineWithRegions","revertRedlineRegion","useState","useRef","useEffect","normalizeMarkdown","useCallback","useMemo","savedFromId","content","useArbi","isDocumentId","useQuery","arbiQueryKeys","parseVersionRef","flattenChunks","useDocuments","useDocumentVersionList","documentVersions","toArtifactVersions","useQueryClient","useMutation","refreshDocuments","findVersion","versionLabel","jsx","MarkdownRenderer","cleanDraftWithReport"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n buildHybridRedlineMarkdown,\n buildHybridRedlineWithRegions,\n revertRedlineRegion,\n type RedlineWithRegions,\n} from './redline-diff'\n\n/**\n * Where a redline is computed. The default runs on the calling thread; a host with large\n * documents passes an engine backed by a Web Worker (for example a Comlink proxy exposing the same\n * three functions) so typing never waits on a diff.\n */\nexport interface RedlineEngine {\n buildRedline(baseText: string, compareText: string): string | Promise<string>\n buildRedlineWithRegions(\n baseText: string,\n compareText: string\n ): RedlineWithRegions | Promise<RedlineWithRegions>\n revertRegion(baseText: string, compareText: string, regionId: string): string | Promise<string>\n}\n\n/** Main-thread engine: the pure functions of `redline-diff`. */\nexport const mainThreadRedlineEngine: RedlineEngine = {\n buildRedline: buildHybridRedlineMarkdown,\n buildRedlineWithRegions: buildHybridRedlineWithRegions,\n revertRegion: revertRedlineRegion,\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { RedlineRegion } from './redline-diff'\nimport { normalizeMarkdown } from './normalize-markdown'\nimport { mainThreadRedlineEngine, type RedlineEngine } from './redline-engine'\n\n/** What a redline view can show. Mirrors the status parts of `@arbidocs/blocks/artifacts`. */\nexport type RedlineState =\n | { kind: 'idle' }\n | { kind: 'computing' }\n | { kind: 'ready'; markdown: string; regions: RedlineRegion[] }\n | { kind: 'identical' }\n | { kind: 'unavailable' }\n\nexport interface UseRedlineOptions {\n /** The older side. `null` means the text could not be loaded; `undefined` means not chosen. */\n baseText: string | null | undefined\n /** The newer side (a loaded version, or the live edit buffer). */\n compareText: string | null | undefined\n /** Either text is still being fetched. */\n isLoading?: boolean\n /** Defaults to the main thread; pass a worker-backed engine for big documents. */\n engine?: RedlineEngine\n}\n\nexport interface UseRedlineResult {\n state: RedlineState\n /** Undo one change: resolves with the compare text rebuilt without it (null if nothing changed). */\n revertRegion: (regionId: string) => Promise<string | null>\n}\n\n/**\n * Track-changes between two texts. Stale results are dropped when the inputs change mid-compute,\n * and a failed diff reports `unavailable` instead of throwing into the render.\n */\nexport function useRedline({\n baseText,\n compareText,\n isLoading = false,\n engine = mainThreadRedlineEngine,\n}: UseRedlineOptions): UseRedlineResult {\n const [state, setState] = useState<RedlineState>({ kind: 'idle' })\n const requestIdRef = useRef(0)\n\n useEffect(() => {\n if (baseText === undefined || compareText === undefined) {\n setState({ kind: 'idle' })\n return\n }\n if (isLoading) {\n setState({ kind: 'computing' })\n return\n }\n if (baseText === null || compareText === null) {\n setState({ kind: 'unavailable' })\n return\n }\n if (\n baseText === compareText ||\n normalizeMarkdown(baseText) === normalizeMarkdown(compareText)\n ) {\n setState({ kind: 'identical' })\n return\n }\n\n const id = ++requestIdRef.current\n let cancelled = false\n setState({ kind: 'computing' })\n // Every change carries a stable id, so a view can offer per-change undo.\n Promise.resolve(engine.buildRedlineWithRegions(baseText, compareText))\n .then((result) => {\n if (cancelled || id !== requestIdRef.current) return\n setState({ kind: 'ready', markdown: result.markdown, regions: result.regions })\n })\n .catch(() => {\n if (cancelled || id !== requestIdRef.current) return\n setState({ kind: 'unavailable' })\n })\n return () => {\n cancelled = true\n }\n }, [baseText, compareText, isLoading, engine])\n\n // The latest texts, so `revertRegion` stays referentially stable while the user types.\n const latest = useRef({ baseText, compareText })\n useEffect(() => {\n latest.current = { baseText, compareText }\n }, [baseText, compareText])\n\n const revertRegion = useCallback(\n async (regionId: string): Promise<string | null> => {\n const { baseText: base, compareText: compare } = latest.current\n if (!base || !compare) return null\n try {\n const next = await engine.revertRegion(base, compare, regionId)\n return next !== normalizeMarkdown(compare) ? next : null\n } catch {\n return null\n }\n },\n [engine]\n )\n\n return useMemo(() => ({ state, revertRegion }), [state, revertRegion])\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { normalizeMarkdown } from './normalize-markdown'\nimport { useRedline, type UseRedlineResult } from './useRedline'\nimport type { RedlineEngine } from './redline-engine'\n\n/** What a save reports back. `docId` is the new version when the backend already knows it. */\nexport interface ArtifactSaveResult {\n docId?: string\n /** 1-based number of the version that was just saved (1 for the first save of a draft). */\n version?: number\n}\n\nexport interface ArtifactEditSessionOptions {\n /** The artifact being edited. Changing it discards the buffer and any comparison. */\n docId: string | null | undefined\n /**\n * The saved text of the open version. `undefined` while it loads; whenever it changes the\n * baseline follows it (a version arriving from the realtime channel, a finished stream).\n */\n baseline: string | undefined\n /**\n * A new document the user types from scratch: open straight in the editor, seeded with\n * `initialContent`, instead of showing a read-only view. Read when `docId` changes.\n */\n startEditing?: boolean\n initialContent?: string\n /** The version this one was saved from. Offering \"compare with previous\" needs it. */\n savedFromId?: string | null\n /** Controlled comparison target. Omit for an uncontrolled one the session owns. */\n compareId?: string | null\n onCompareChange?: (id: string | null) => void\n /** The saved text of the compare target (the older side of the diff). */\n compareText?: string | null\n compareLoading?: boolean\n /** Starting a comparison opens the editor with track changes on (default true). */\n compareOpensEditor?: boolean\n /** Persist the buffer as a NEW version. Rejecting keeps the buffer so nothing is lost. */\n save: (content: string) => Promise<ArtifactSaveResult | void>\n onSaved?: (result: ArtifactSaveResult, content: string) => void\n onSaveError?: (error: unknown) => void\n /** Every buffer change (a host keeps a draft store in sync with it). */\n onContentChange?: (content: string) => void\n /** The unsaved-changes flag, for a host that warns before a panel is closed. */\n onDirtyChange?: (dirty: boolean) => void\n /** Where the diff runs. Defaults to the main thread. */\n redlineEngine?: RedlineEngine\n /** Typing is never debounced; the diff trails the buffer by this long. Default 300ms. */\n diffDelayMs?: number\n}\n\nexport interface ArtifactEditSession {\n isEditing: boolean\n /** The saved text of the open version. */\n baseline: string\n /** The text in the editor (the baseline until the first edit). */\n content: string\n hasChanges: boolean\n isSaving: boolean\n canCompare: boolean\n compareId: string | null\n showTrackChanges: boolean\n /** Track changes between the compare target and the (debounced) buffer. */\n redline: UseRedlineResult\n startEdit: () => void\n /** Discard the buffer and any comparison; back to the rendered view. */\n cancel: () => void\n /** Save the buffer as a new version. Resolves false when it failed (the buffer is kept). */\n save: () => Promise<boolean>\n /** The editor's `onChange`; also replaces the buffer (for example after an undo-this-change). */\n change: (markdown: string) => void\n /** The editor's `onNormalized`: adopt its canonical form as the baseline so Save does not fire. */\n normalized: (markdown: string) => void\n /** Compare with the previous version (when no id is given). */\n compare: (id?: string) => void\n stopCompare: () => void\n setShowTrackChanges: (show: boolean) => void\n /** Undo one tracked change in the buffer. */\n revertRegion: (regionId: string) => Promise<void>\n}\n\n/**\n * The state machine of an artifact edit session, with no SDK and no network: the edit buffer and\n * its baseline, the dirty flag, immutable-version saves and a track-changes comparison. A host\n * supplies the saved text and a `save` function (see `useArtifactSession` for the SDK binding).\n */\nexport function useArtifactEditSession(options: ArtifactEditSessionOptions): ArtifactEditSession {\n const {\n docId,\n baseline: loadedBaseline,\n startEditing = false,\n initialContent,\n savedFromId,\n compareId: controlledCompareId,\n onCompareChange,\n compareText,\n compareLoading = false,\n compareOpensEditor = true,\n save: persist,\n onSaved,\n onSaveError,\n onContentChange,\n onDirtyChange,\n redlineEngine,\n diffDelayMs = 300,\n } = options\n\n const [isEditing, setIsEditing] = useState(false)\n const [baseline, setBaseline] = useState('')\n const [buffer, setBuffer] = useState('')\n const [isSaving, setIsSaving] = useState(false)\n const [showTrackChanges, setShowTrackChanges] = useState(false)\n const [ownCompareId, setOwnCompareId] = useState<string | null>(null)\n const controlled = controlledCompareId !== undefined\n const compareId = controlled ? controlledCompareId : ownCompareId\n\n const setCompareId = useCallback(\n (id: string | null) => {\n if (!controlled) setOwnCompareId(id)\n onCompareChange?.(id)\n },\n [controlled, onCompareChange]\n )\n\n // The latest values for callbacks that must not change identity while the user types.\n const latest = useRef({ buffer, baseline, isEditing, initialContent })\n latest.current = { buffer, baseline, isEditing, initialContent }\n\n // The baseline follows the loaded text. A draft has none and seeds itself below.\n useEffect(() => {\n if (loadedBaseline !== undefined) setBaseline(loadedBaseline)\n }, [loadedBaseline])\n\n // Another artifact: drop stale edits and comparison. A new typed document starts in the editor.\n useEffect(() => {\n if (startEditing) {\n const seed = latest.current.initialContent ?? ''\n setIsEditing(true)\n setBaseline(seed)\n setBuffer(seed)\n } else {\n setIsEditing(false)\n setBuffer('')\n }\n setCompareId(null)\n setShowTrackChanges(false)\n // Only the identity of the artifact resets the session.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [docId])\n\n const startEdit = useCallback(() => {\n setBuffer(latest.current.baseline)\n setIsEditing(true)\n }, [])\n\n const stopCompare = useCallback(() => {\n setCompareId(null)\n setShowTrackChanges(false)\n }, [setCompareId])\n\n const cancel = useCallback(() => {\n setIsEditing(false)\n setBuffer('')\n stopCompare()\n }, [stopCompare])\n\n const compare = useCallback(\n (id?: string) => {\n const target = id ?? savedFromId\n if (target) setCompareId(target)\n },\n [savedFromId, setCompareId]\n )\n\n // Comparing and editing are one surface: a comparison opens the editor with the diff showing,\n // like Word's Compare yields tracked changes you can keep typing through.\n const hasBaseline = baseline !== ''\n useEffect(() => {\n if (!compareId || !compareOpensEditor || !hasBaseline) return\n if (!latest.current.isEditing) startEdit()\n setShowTrackChanges(true)\n }, [compareId, compareOpensEditor, hasBaseline, startEdit])\n\n const save = useCallback(async (): Promise<boolean> => {\n // Persist the canonical spelling so the editor's gratuitous escapes never reach a version.\n const raw = latest.current.buffer\n const normalised = normalizeMarkdown(raw)\n const content = raw.endsWith('\\n') ? normalised : normalised.replace(/\\n$/, '')\n setIsSaving(true)\n try {\n const result = (await persist(content)) ?? {}\n setBaseline(content)\n setIsEditing(false)\n stopCompare()\n onSaved?.(result, content)\n return true\n } catch (error) {\n onSaveError?.(error)\n return false\n } finally {\n setIsSaving(false)\n }\n }, [persist, stopCompare, onSaved, onSaveError])\n\n const content = buffer || baseline\n const hasChanges = isEditing && !!buffer && buffer !== baseline\n useEffect(() => {\n onDirtyChange?.(hasChanges)\n return () => onDirtyChange?.(false)\n }, [hasChanges, onDirtyChange])\n\n const setContent = useCallback(\n (markdown: string) => {\n setBuffer(markdown)\n onContentChange?.(markdown)\n },\n [onContentChange]\n )\n const normalized = useCallback((markdown: string) => {\n setBaseline(markdown)\n setBuffer(markdown)\n }, [])\n\n // The diff trails the buffer so it runs on a settled text.\n const [diffContent, setDiffContent] = useState(content)\n useEffect(() => {\n const id = setTimeout(() => setDiffContent(content), diffDelayMs)\n return () => clearTimeout(id)\n }, [content, diffDelayMs])\n\n const redline = useRedline({\n baseText: compareId ? compareText : undefined,\n compareText: compareId ? diffContent || baseline : undefined,\n isLoading: compareLoading,\n engine: redlineEngine,\n })\n const { revertRegion: revertInRedline } = redline\n const revertRegion = useCallback(\n async (regionId: string): Promise<void> => {\n const next = await revertInRedline(regionId)\n if (next !== null) setContent(next)\n },\n [revertInRedline, setContent]\n )\n\n return useMemo(\n () => ({\n isEditing,\n baseline,\n content,\n hasChanges,\n isSaving,\n canCompare: !!savedFromId && !compareId,\n compareId,\n showTrackChanges,\n redline,\n startEdit,\n cancel,\n save,\n change: setContent,\n normalized,\n compare,\n stopCompare,\n setShowTrackChanges,\n revertRegion,\n }),\n [\n isEditing,\n baseline,\n content,\n hasChanges,\n isSaving,\n savedFromId,\n compareId,\n showTrackChanges,\n redline,\n startEdit,\n cancel,\n save,\n setContent,\n normalized,\n compare,\n stopCompare,\n revertRegion,\n ]\n )\n}\n","import { useCallback, useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { flattenChunks, isDocumentId, parseVersionRef } from './versions'\n\n/**\n * Where the text of a stored artifact is:\n * - `loading`: the first request is in flight (or there is no document yet);\n * - `parsing`: the backend has not finished parsing the upload (the endpoint answers 404, 422 or\n * 500, or an empty parse, for a few seconds after an upload) and the hook is retrying;\n * - `ready`: the text is here (an empty document is `ready` with `text: null`);\n * - `error`: the retries ran out, or the request was refused (401/403).\n */\nexport type ArtifactTextStatus = 'loading' | 'parsing' | 'ready' | 'error'\n\n/** How long `useArtifactText` keeps asking while a document is still being parsed. */\nexport interface ArtifactTextRetry {\n /** Retries after the first request. Default 12. */\n attempts?: number\n /** Delay before the first retry; it grows by 1.6x each time. Default 1000 ms. */\n baseDelayMs?: number\n /** Cap for one delay. Default 5000 ms (12 retries are about 50 s in all). */\n maxDelayMs?: number\n}\n\nexport const DEFAULT_ARTIFACT_TEXT_RETRY: Required<ArtifactTextRetry> = {\n attempts: 12,\n baseDelayMs: 1000,\n maxDelayMs: 5000,\n}\n\n/** Thrown inside the query when the parse has no text yet, so that it is retried like a 500. */\nclass NotParsedYetError extends Error {\n constructor() {\n super('The document has no parsed text yet')\n }\n}\n\nconst isRefusal = (error: unknown): boolean => {\n const status = error as { status?: number; response?: { status?: number } } | null\n const code = status?.status ?? status?.response?.status\n return code === 401 || code === 403\n}\n\nexport interface ArtifactText {\n /**\n * The markdown, clean: `undefined` while `loading` or `parsing`, `null` when there is none (an\n * empty document, or `error`).\n */\n text: string | null | undefined\n /** `status` is `loading` or `parsing`. */\n isLoading: boolean\n status: ArtifactTextStatus\n /** The last request error while `parsing` or after `error`. */\n error: Error | null\n /** Ask again now (after an `error`). */\n retry: () => void\n}\n\n/**\n * The saved markdown of an artifact version (its parsed chunks, joined and unescaped).\n *\n * A freshly uploaded document is parsed asynchronously, and for roughly 3 to 20 seconds the parsed\n * content endpoint answers 404, 422 or 500 (or an empty parse). The hook therefore retries with a\n * growing delay (see `ArtifactTextRetry`) and reports `status: 'parsing'` meanwhile, so a host can\n * show \"Preparing editor...\" instead of opening an editor on an empty baseline. After the last\n * retry the status is `error`; `retry()` starts a new round.\n *\n * The text is run through `unescapeMarkdown`: an artifact is always stored from markdown, and the\n * backend's parse of a `.md` escapes its punctuation.\n */\nexport function useArtifactText(\n docId: string | null | undefined,\n options?: { enabled?: boolean; retry?: ArtifactTextRetry }\n): ArtifactText {\n const arbi = useArbi()\n const { attempts, baseDelayMs, maxDelayMs } = {\n ...DEFAULT_ARTIFACT_TEXT_RETRY,\n ...options?.retry,\n }\n // A local draft (placeholder id) has no backend document: asking for its text would be a 422.\n const enabled = (options?.enabled ?? true) && isDocumentId(docId) && arbi.hasWorkspace\n const query = useQuery({\n // Under the shared `parsedDoc` key, so a document's invalidation reaches it too.\n queryKey: [...arbiQueryKeys.parsedDoc(docId ?? '', 'marker'), 'artifact-text'] as const,\n queryFn: async () => {\n // A version reference (`doc-…@v2`) reads that version; a plain id the current one.\n const { docId: plainId, version } = parseVersionRef(docId)\n const parsed = (await arbi.documents.getParsedContent(\n plainId,\n 'marker',\n version ?? undefined\n )) as {\n chunks?: { content?: string | null }[]\n }\n if (!parsed.chunks?.some((c) => c.content?.trim())) throw new NotParsedYetError()\n return flattenChunks(parsed.chunks, { unescape: true })\n },\n enabled,\n retry: (failureCount, error) => !isRefusal(error) && failureCount < attempts,\n retryDelay: (failureCount) => Math.min(baseDelayMs * 1.6 ** failureCount, maxDelayMs),\n })\n\n const { refetch } = query\n const retry = useCallback(() => void refetch(), [refetch])\n\n return useMemo<ArtifactText>(() => {\n const error = query.error\n const neverParsed = error instanceof NotParsedYetError\n let status: ArtifactTextStatus = 'loading'\n if (!enabled) status = 'loading'\n else if (query.isSuccess || (query.isError && neverParsed)) status = 'ready'\n else if (query.isError) status = 'error'\n else if (query.failureCount > 0) status = 'parsing'\n const text = !enabled\n ? undefined\n : query.isSuccess\n ? query.data\n : status === 'ready' || status === 'error'\n ? null\n : undefined\n return {\n text,\n isLoading: enabled && (status === 'loading' || status === 'parsing'),\n status,\n error: status === 'ready' ? null : (error ?? query.failureReason ?? null),\n retry,\n }\n }, [\n enabled,\n query.isSuccess,\n query.isError,\n query.data,\n query.error,\n query.failureCount,\n query.failureReason,\n retry,\n ])\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport { useMutation, useQueryClient } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys, useDocumentVersionList } from '../hooks'\nimport { refreshDocuments, useDocuments } from '../documents/documents-data'\nimport { useArtifactText, type ArtifactTextStatus } from './useArtifactText'\nimport {\n documentVersions,\n findVersion,\n isDocumentId,\n parseVersionRef,\n toArtifactVersions,\n versionLabel,\n type ArtifactVersion,\n} from './versions'\nimport {\n useArtifactEditSession,\n type ArtifactEditSession,\n type ArtifactEditSessionOptions,\n type ArtifactSaveResult,\n} from './useArtifactEditSession'\n\n/**\n * The versions of an artifact, oldest first. `docId` is a document id or a version reference\n * (`doc-…@v2`). Every listed document carries its versions; a document that is not in the\n * workspace list asks for its version list.\n */\nexport function useArtifactVersions(\n workspaceId: string | undefined,\n docId: string | null | undefined\n): ArtifactVersion[] {\n const plainId = docId ? parseVersionRef(docId).docId : null\n const { data: documents } = useDocuments(workspaceId)\n const listed = useMemo(\n () => (documents ?? []).find((d) => d.external_id === plainId),\n [documents, plainId]\n )\n // Asked only once the list has loaded and the document is not in it.\n const { data: history } = useDocumentVersionList(plainId, {\n enabled: !!plainId && documents !== undefined && !listed,\n })\n return useMemo(\n () => (listed ? documentVersions(listed) : toArtifactVersions(plainId, history)),\n [listed, history, plainId]\n )\n}\n\nexport interface SaveArtifactVersionInput {\n /** File name of the new version (`.md` is added when missing). */\n title: string\n content: string\n /** Save as the next version of this document (it keeps its id); omit for a new document. */\n versionOf?: string | null\n /** The processing config (auto-title, parsing) to run the upload with. */\n configId?: string | null\n /** `artifact` (default) for AI-style drafts; `source` for a document the user typed. */\n wpType?: 'artifact' | 'source'\n}\n\n/**\n * Save markdown as a NEW immutable version (the next version of `versionOf`'s document, which keeps\n * its id) and refresh the workspace document list, version lists and the document's text.\n */\nexport function useSaveArtifactVersion() {\n const arbi = useArbi()\n const queryClient = useQueryClient()\n return useMutation<ArtifactSaveResult, Error, SaveArtifactVersionInput>({\n mutationFn: async ({ title, content, versionOf, configId, wpType }) => {\n // The backend classifies uploads by extension: a title without one is silently dropped.\n const fileName = /\\.md$/i.test(title) ? title : `${title}.md`\n const result = await arbi.documents.uploadFile(\n new Blob([content], { type: 'text/markdown' }),\n fileName,\n {\n wpType: wpType ?? 'artifact',\n versionOf: versionOf ? parseVersionRef(versionOf).docId : undefined,\n configExtId: configId ?? undefined,\n }\n )\n const docId = result.doc_ext_ids?.[0]\n // The document's row moves to the new version (its version lists re-read with it).\n if (docId) await refreshDocuments(queryClient, arbi, [docId])\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.allDocumentVersions() })\n // The document's current text is the new version's now.\n if (docId)\n await queryClient.invalidateQueries({ queryKey: arbiQueryKeys.parsedDocument(docId) })\n return { docId, version: result.version ?? undefined }\n },\n })\n}\n\nexport interface ArtifactSessionOptions extends Pick<\n ArtifactEditSessionOptions,\n | 'onSaved'\n | 'onSaveError'\n | 'onCompareChange'\n | 'compareId'\n | 'compareOpensEditor'\n | 'redlineEngine'\n | 'onDirtyChange'\n> {\n workspaceId: string | undefined\n /**\n * The open document (its current version), a version reference `doc-…@v{n}`, or the placeholder\n * id of an unsaved local draft (anything that is not a backend document id, i.e. does not start\n * with `doc`).\n */\n docId: string | null | undefined\n /**\n * The text of a local draft (nothing is fetched for it). The FIRST save uploads it as a real\n * document with no parent and the session switches to the new id; later saves chain from it.\n */\n draftContent?: string\n /** Name for saved versions. Defaults to the open version's file name, else \"Untitled\". */\n title?: string\n /** Processing config for saved versions. */\n configId?: string | null\n}\n\n/** Everything `ArtifactEditor` (`@arbidocs/blocks/artifacts`) takes from a session, flat. */\nexport interface ArtifactSessionView {\n content: string\n isEditing: boolean\n hasChanges: boolean\n isSaving: boolean\n canCompare: boolean\n comparing: boolean\n compareId: string | null\n showTrackChanges: boolean\n versions: ArtifactVersion[]\n currentVersionId: string\n onStartEdit: () => void\n onCancel: () => void\n onSave: () => void\n onCompare: () => void\n onStopCompare: () => void\n onToggleTrackChanges: () => void\n /**\n * Whether the text is ready. `ArtifactEditor` renders \"Preparing editor...\" while it is\n * `loading` or `parsing` (a fresh upload is parsed for a few seconds) and an error with Retry.\n */\n status: ArtifactTextStatus\n /** Ask for the text again after an `error`. */\n onRetry: () => void\n}\n\nexport interface ArtifactSession extends ArtifactEditSession {\n /** The open document: the new real id once a local draft has been saved. */\n docId: string | null | undefined\n /** The open version is an unsaved local draft (no backend document yet). */\n isLocal: boolean\n isLoading: boolean\n /** See `ArtifactTextStatus`. */\n status: ArtifactTextStatus\n versions: ArtifactVersion[]\n /** \"v2\" for any version (reference) of the document. */\n labelOf: (id: string | null | undefined) => string | null\n /** Props for `<ArtifactEditor>`. */\n view: ArtifactSessionView\n /** Props for `<ArtifactMarkdownEditor>` (`@arbidocs/blocks/artifacts/editor`). */\n editorProps: {\n markdown: string\n onChange: (markdown: string) => void\n onNormalized: (markdown: string) => void\n }\n /** Props for `<ArtifactRedlineView>`. */\n redlineProps: {\n state: ArtifactEditSession['redline']['state']\n onRevert: (regionId: string) => void\n }\n}\n\n/**\n * Edit an artifact through the SDK: load it, edit it, save it as a new version, list its versions\n * and compare any two with track changes. Needs an `<ArbiHost>` with an `arbi` and a selected workspace.\n *\n * ```tsx\n * const session = useArtifactSession({ workspaceId, docId, onSaved: ({ docId }) => docId && open(docId) })\n * <ArtifactEditor {...session.view} onOpenVersion={open}\n * editor={<ArtifactMarkdownEditor {...session.editorProps} />}\n * redline={<ArtifactRedlineView {...session.redlineProps} />} />\n * ```\n */\nexport function useArtifactSession(options: ArtifactSessionOptions): ArtifactSession {\n const {\n workspaceId,\n docId: hostDocId,\n draftContent,\n title,\n configId,\n compareId,\n onCompareChange,\n onSaved,\n ...passthrough\n } = options\n // A saved local draft becomes this real document; another host docId resets it.\n const [saved, setSaved] = useState<{\n forId: string | null | undefined\n id: string\n text: string\n } | null>(null)\n const adopted = saved && saved.forId === hostDocId ? saved : null\n const docId = adopted?.id ?? hostDocId\n const isLocal = !isDocumentId(docId)\n\n // Owned here (not in the edit session) because the compare target's text must be loaded first.\n const [ownCompareId, setOwnCompareId] = useState<string | null>(null)\n const activeCompareId = compareId === undefined ? ownCompareId : compareId\n const changeCompare = useCallback(\n (id: string | null) => {\n setOwnCompareId(id)\n onCompareChange?.(id)\n },\n [onCompareChange]\n )\n\n const { text, isLoading, status, retry } = useArtifactText(docId)\n const versions = useArtifactVersions(workspaceId, isLocal ? null : docId)\n const { text: compareText, isLoading: compareLoading } = useArtifactText(activeCompareId, {\n enabled: !!activeCompareId,\n })\n const saveVersion = useSaveArtifactVersion()\n const current = findVersion(versions, docId)\n\n const save = useCallback(\n async (content: string) => {\n const result = await saveVersion.mutateAsync({\n title: title ?? current?.name ?? 'Untitled',\n content,\n versionOf: isLocal ? null : docId,\n configId,\n })\n const latest = versions.reduce((n, v) => Math.max(n, v.number), 0)\n return { ...result, version: result.version ?? (isLocal ? 1 : latest + 1) }\n },\n [saveVersion, title, current?.name, isLocal, docId, configId, versions]\n )\n\n const handleSaved = useCallback(\n (result: ArtifactSaveResult, content: string) => {\n // A host that keeps passing the local draft's placeholder id: follow every save to the real\n // document it created (the first save creates version 1, later ones chain from it).\n if (!isDocumentId(hostDocId) && result.docId)\n setSaved({ forId: hostDocId, id: result.docId, text: content })\n onSaved?.(result, content)\n },\n [hostDocId, onSaved]\n )\n\n const session = useArtifactEditSession({\n ...passthrough,\n docId,\n // A local draft has only its own text; a just-saved one shows what was saved until the parsed\n // text of the new document arrives.\n baseline: text ?? (isLocal ? draftContent : adopted?.text),\n savedFromId: current?.savedFromId,\n compareId: activeCompareId,\n onCompareChange: changeCompare,\n compareText,\n compareLoading,\n save,\n onSaved: handleSaved,\n })\n\n const { redline } = session\n return useMemo<ArtifactSession>(\n () => ({\n ...session,\n docId,\n isLocal,\n isLoading,\n status,\n versions,\n labelOf: (id) => versionLabel(versions, id),\n view: {\n content: session.baseline,\n isEditing: session.isEditing,\n hasChanges: session.hasChanges,\n isSaving: session.isSaving,\n canCompare: session.canCompare,\n comparing: !!session.compareId,\n compareId: session.compareId,\n showTrackChanges: session.showTrackChanges,\n versions,\n currentVersionId: current?.id ?? docId ?? '',\n onStartEdit: session.startEdit,\n onCancel: session.cancel,\n onSave: () => void session.save(),\n onCompare: () => session.compare(),\n onStopCompare: session.stopCompare,\n onToggleTrackChanges: () => session.setShowTrackChanges(!session.showTrackChanges),\n // A local draft has its text already: it is ready.\n status: isLocal ? 'ready' : status,\n onRetry: retry,\n },\n editorProps: {\n markdown: session.content,\n onChange: session.change,\n onNormalized: session.normalized,\n },\n redlineProps: {\n state: redline.state,\n onRevert: (regionId) => void session.revertRegion(regionId),\n },\n }),\n [session, redline, isLoading, status, retry, isLocal, versions, docId]\n )\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../query-keys'\n\n/**\n * The stored source of a live artifact (the `.html` / `.jsx` file itself; the parsed text strips\n * it). `undefined` until it has loaded.\n */\nexport function useArtifactSource(documentId: string | null | undefined, enabled = true) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.artifactSource(documentId ?? ''),\n queryFn: async () => (await arbi.documents.download(documentId as string)).text(),\n enabled: enabled && !!documentId && arbi.isLoggedIn,\n staleTime: 5 * 60 * 1000,\n })\n}\n","import type { ComponentPropsWithoutRef, FC, ReactNode } from 'react'\nimport { MarkdownRenderer } from '../ai/MarkdownRenderer'\n\n/** The `<del>` / `<ins>` renderers `ArtifactRedlineView` hands to a markdown renderer. */\nexport interface ArtifactRedlineComponents {\n del: FC<ComponentPropsWithoutRef<'del'> & { 'data-cid'?: string }>\n ins: FC<ComponentPropsWithoutRef<'ins'> & { 'data-cid'?: string }>\n}\n\n/**\n * The kit's markdown renderer as the `renderMarkdown` slot of `ArtifactEditor` and\n * `ArtifactRedlineView`: full markdown (tables, lists, code) plus the raw `<del>` / `<ins>` tags\n * of a redline.\n */\nexport function renderArtifactMarkdown(\n markdown: string,\n components?: ArtifactRedlineComponents\n): ReactNode {\n return <MarkdownRenderer components={components}>{markdown}</MarkdownRenderer>\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ArtifactEvent } from '../ai/engine'\nimport { cleanDraftWithReport, type DraftCleanReport } from '../ai/stored-markdown'\nimport { useSaveArtifactVersion } from './useArtifactSession'\nimport { isDocumentId } from './versions'\nimport { useArtifactText, type ArtifactTextRetry } from './useArtifactText'\n\n/**\n * Where a drafted artifact is in its STREAM -> PERSIST -> EDIT life:\n * - `streaming`: the agent is still working (or has produced nothing final): show the live canvas;\n * - `persisting`: the finished draft is being stored as version 1 of the artifact;\n * - `parsing`: stored; the backend is still parsing it, so there is no editable text yet;\n * - `ready`: the text is readable: mount the editor on `docId`;\n * - `error`: storing failed or the parse never produced text (`retry()` starts over).\n */\nexport type StreamedArtifactPhase = 'streaming' | 'persisting' | 'parsing' | 'ready' | 'error'\n\nexport interface UseStreamedArtifactOptions {\n /** The artifacts of the agent run (`useConnectedAiTask().artifacts`). */\n artifacts: ArtifactEvent[]\n workspaceId: string | undefined\n /**\n * The run has stopped: not busy and not failed. Nothing is stored before this, so a draft that\n * is still streaming is never persisted half-written.\n */\n settled: boolean\n /**\n * Make the stored markdown from the streamed content. Default `cleanDraftWithReport`, which is\n * guarded: it stores the raw streamed text (or links-only text) rather than a cleanup that would\n * lose content (see `DraftCleanReport`).\n */\n clean?: (streamed: string) => string\n /** Called once per stored draft with what the cleanup did (`stage` is not `cleaned` if guarded). */\n onCleaned?: (report: DraftCleanReport) => void\n /** Processing config for the stored version. */\n configId?: string | null\n /** How long to wait for the parse (see `useArtifactText`). */\n parseRetry?: ArtifactTextRetry\n}\n\nexport interface StreamedArtifact {\n phase: StreamedArtifactPhase\n /** The finished streamed artifact (its `title` names the stored versions). */\n artifact: ArtifactEvent | undefined\n /** The backend document to edit, once there is one (while `parsing` and `ready`). */\n docId: string | undefined\n error: Error | null\n /** What the cleanup did to the stored draft (`null` until it was stored, or with a custom `clean`). */\n cleaned: DraftCleanReport | null\n /** After an `error`: store again or ask for the parse again. */\n retry: () => void\n}\n\n/**\n * The lifecycle of an agent-drafted artifact, so a host passes the stream and renders the phase.\n *\n * While the agent streams, the draft lives only on the canvas. Once the run is `settled` and the\n * draft is complete, a draft that is not yet a backend document is cleaned (`cleanDraftMarkdown`)\n * and stored ONCE as the artifact's first version (`wpType: 'artifact'`); a draft that already is a\n * backend document passes through. The hook then waits for the parse (`useArtifactText`, which\n * retries) and reports `ready` with the `docId` to open in an editor.\n *\n * Needs an `<ArbiHost>` with an `arbi` and a workspace. `@arbidocs/blocks/connect` has the whole thing as a\n * component (`StreamedArtifact`).\n */\nexport function useStreamedArtifact({\n artifacts,\n workspaceId,\n settled,\n clean,\n onCleaned,\n configId,\n parseRetry,\n}: UseStreamedArtifactOptions): StreamedArtifact {\n const artifact = artifacts.find((a) => a.is_complete)\n const { mutateAsync } = useSaveArtifactVersion()\n const [saved, setSaved] = useState<{ content: string; docId: string } | null>(null)\n const [saveError, setSaveError] = useState<Error | null>(null)\n const [attempt, setAttempt] = useState(0)\n const [cleaned, setCleaned] = useState<DraftCleanReport | null>(null)\n const started = useRef<string | null>(null)\n\n const content = artifact?.content ?? ''\n const title = artifact?.title ?? 'Draft'\n const passThrough = !!artifact && isDocumentId(artifact.doc_ext_id)\n const needsSave = settled && !!artifact && !passThrough && !!content.trim() && !!workspaceId\n\n useEffect(() => {\n const key = `${attempt}:${content}`\n if (!needsSave || started.current === key) return\n started.current = key\n setSaveError(null)\n let stored: string\n if (clean) stored = clean(content)\n else {\n const report = cleanDraftWithReport(content)\n stored = report.text\n setCleaned(report)\n onCleaned?.(report)\n if (report.guarded) {\n console.warn(\n `[useStreamedArtifact] the draft cleanup would have lost content; stored the ${report.stage} text instead (kept ${Math.round(report.ratio * 100)}%, changed by: ${report.changedBy.join(', ') || 'nothing'})`\n )\n }\n }\n mutateAsync({\n title,\n content: stored,\n configId,\n wpType: 'artifact',\n })\n .then((r) => {\n if (r.docId) setSaved({ content, docId: r.docId })\n else setSaveError(new Error('The draft was stored but the server returned no document id'))\n })\n .catch((e: unknown) => setSaveError(e instanceof Error ? e : new Error(String(e))))\n // `clean` and `onCleaned` are deliberately not dependencies: a new function identity must not\n // store twice.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [needsSave, content, title, workspaceId, configId, attempt, mutateAsync])\n\n const docId = !artifact\n ? undefined\n : passThrough\n ? artifact.doc_ext_id\n : saved?.content === content\n ? saved.docId\n : undefined\n\n const text = useArtifactText(docId, { enabled: settled, retry: parseRetry })\n const { retry: retryText } = text\n\n const retry = useCallback(() => {\n if (saveError) setAttempt((n) => n + 1)\n else retryText()\n }, [saveError, retryText])\n\n let phase: StreamedArtifactPhase\n if (!settled || !artifact) phase = 'streaming'\n else if (saveError) phase = 'error'\n else if (!docId) phase = needsSave ? 'persisting' : 'streaming'\n else if (text.status === 'ready' && text.text) phase = 'ready'\n else if (text.status === 'error' || text.status === 'ready') phase = 'error'\n else phase = 'parsing'\n\n const error =\n phase !== 'error'\n ? null\n : (saveError ?? text.error ?? new Error('The document has no text to edit'))\n return { phase, artifact, docId, error, cleaned, retry }\n}\n","/**\n * Which live renderer, if any, an artifact maps to. Kept free of heavy imports (no compiler) so the\n * document viewer can use it without pulling the preview code into its bundle.\n *\n * The backend persists an artifact's render mode in the saved file's extension: .html / .jsx are live\n * artifacts; document drafts are stored as .docx and open in the Word editor.\n */\nexport type ArtifactPreviewKind = 'html' | 'react'\n\nexport function artifactKindFromFileName(fileName?: string | null): ArtifactPreviewKind | null {\n const ext = (fileName ?? '').toLowerCase().match(/\\.[a-z0-9]+$/)?.[0]\n if (ext === '.html' || ext === '.htm') return 'html'\n if (ext === '.jsx') return 'react'\n return null\n}\n\nexport function artifactKindFromMode(mode?: string | null): ArtifactPreviewKind | null {\n return mode === 'html' || mode === 'react' ? mode : null\n}\n\n/**\n * The viewer tab an artifact opens on: a generated image on its media view ('pdf'), an html/react\n * artifact on its rendered Preview, and a document draft (stored as .docx) in the Word editor.\n */\nexport function viewerTabForArtifactMode(mode?: string | null): 'pdf' | 'preview' | 'edit' {\n if (mode === 'image') return 'pdf'\n return artifactKindFromMode(mode) ? 'preview' : 'edit'\n}\n"]}
@@ -1,17 +1,15 @@
1
- import { useDocuments, refreshDocuments } from '../chunk-VGAA7AFS.js';
2
- import { useDocumentVersionList } from '../chunk-XPLD4LFC.js';
1
+ import { useDocuments, refreshDocuments } from '../chunk-S3OGDLDC.js';
2
+ import { useDocumentVersionList } from '../chunk-KTXZ222T.js';
3
3
  import { revertRedlineRegion, buildHybridRedlineWithRegions, buildHybridRedlineMarkdown } from '../chunk-74N436VK.js';
4
4
  export { buildHybridRedlineMarkdown, buildHybridRedlineWithRegions, revertRedlineRegion } from '../chunk-74N436VK.js';
5
- import { arbiQueryKeys } from '../chunk-TK7ERJPE.js';
6
- import { useArbi } from '../chunk-VGO77X5U.js';
5
+ import { useArbi, arbiQueryKeys } from '../chunk-BFNY3RZG.js';
7
6
  import '../chunk-DPYBZDJB.js';
8
- import { isDocumentId, parseVersionRef, flattenChunks, documentVersions, toArtifactVersions, findVersion, versionLabel, cleanDraftWithReport } from '../chunk-NNWMHMEC.js';
9
- export { cleanDraftMarkdown, cleanDraftWithReport, documentVersions, findVersion, flattenChunks, isDocumentId, parseVersionRef, promoteBoldTitle, repairParsedStructure, repairParsedTitle, savedFromId, stripAgentPreamble, toArtifactVersions, unescapeMarkdown, unwrapCitationLinks, versionLabel, versionRef } from '../chunk-NNWMHMEC.js';
7
+ import { isDocumentId, parseVersionRef, flattenChunks, documentVersions, toArtifactVersions, findVersion, versionLabel, cleanDraftWithReport } from '../chunk-UW2SGTI5.js';
8
+ export { cleanDraftMarkdown, cleanDraftWithReport, documentVersions, findVersion, flattenChunks, isDocumentId, parseVersionRef, promoteBoldTitle, repairParsedStructure, repairParsedTitle, savedFromId, stripAgentPreamble, toArtifactVersions, unescapeMarkdown, unwrapCitationLinks, versionLabel, versionRef } from '../chunk-UW2SGTI5.js';
10
9
  import { normalizeMarkdown } from '../chunk-WUTL62MC.js';
11
10
  export { normalizeMarkdown } from '../chunk-WUTL62MC.js';
12
- import { MarkdownRenderer } from '../chunk-C44GO33B.js';
13
- import '../chunk-QRCMKEE6.js';
14
- import '../chunk-CPZ36AQS.js';
11
+ import { MarkdownRenderer } from '../chunk-WL2Y2T47.js';
12
+ import '../chunk-VSCU7K4V.js';
15
13
  import '../chunk-SN5YV6FF.js';
16
14
  import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
17
15
  import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';