@arbidocs/react 0.5.86 → 0.5.87

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
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkU4PWVSCT_cjs = require('./chunk-U4PWVSCT.cjs');
4
- var chunkVGMMK5OM_cjs = require('./chunk-VGMMK5OM.cjs');
3
+ var chunkC4WODQGO_cjs = require('./chunk-C4WODQGO.cjs');
5
4
  var zustand = require('zustand');
6
5
  var react = require('react');
7
6
  var reactQuery = require('@tanstack/react-query');
@@ -18,10 +17,10 @@ function subscribeDocumentRows(listener) {
18
17
  }
19
18
  function getCachedDocuments(qc, workspaceId) {
20
19
  if (!workspaceId) return void 0;
21
- return qc.getQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.documents(workspaceId));
20
+ return qc.getQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.documents(workspaceId));
22
21
  }
23
22
  function cachedLists(qc) {
24
- return qc.getQueriesData({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.allDocuments() }).flatMap(
23
+ return qc.getQueriesData({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.allDocuments() }).flatMap(
25
24
  ([key, data]) => typeof key[2] === "string" && Array.isArray(data) ? [[key[2], data]] : []
26
25
  );
27
26
  }
@@ -47,13 +46,13 @@ function patchDocuments(qc, reducer, workspaceId) {
47
46
  for (const [id, before] of lists) {
48
47
  const after = reducer(before);
49
48
  if (after === before) continue;
50
- qc.setQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.documents(id), after);
49
+ qc.setQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.documents(id), after);
51
50
  const change = diffRows(id, before, after);
52
51
  const beforeById = new Map(before.map((doc) => [doc.external_id, doc]));
53
52
  if (change.update.some(
54
53
  (doc) => doc.current_version !== beforeById.get(doc.external_id)?.current_version
55
54
  ))
56
- void qc.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.allDocumentVersions() });
55
+ void qc.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.allDocumentVersions() });
57
56
  if (change.add.length || change.update.length || change.remove.length)
58
57
  for (const listener of rowListeners) listener(change);
59
58
  }
@@ -81,11 +80,11 @@ function upsertDocuments(qc, documents, workspaceId) {
81
80
  }
82
81
  }
83
82
  function setCachedDocument(qc, doc) {
84
- qc.setQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.document(doc.external_id), doc);
83
+ qc.setQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.document(doc.external_id), doc);
85
84
  }
86
85
  function patchCachedDocument(qc, docId, reducer) {
87
- const current = qc.getQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.document(docId));
88
- if (current) qc.setQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.document(docId), reducer(current));
86
+ const current = qc.getQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.document(docId));
87
+ if (current) qc.setQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.document(docId), reducer(current));
89
88
  }
90
89
  function dropTagFromCachedDocuments(qc, tagId) {
91
90
  const strip = (doc) => {
@@ -102,9 +101,9 @@ function dropTagFromCachedDocuments(qc, tagId) {
102
101
  }
103
102
  function forgetDocuments(qc, docIds) {
104
103
  for (const id of docIds) {
105
- qc.removeQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.document(id) });
106
- qc.removeQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.documentVersions(id) });
107
- qc.removeQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.parsedDocument(id) });
104
+ qc.removeQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.document(id) });
105
+ qc.removeQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.documentVersions(id) });
106
+ qc.removeQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.parsedDocument(id) });
108
107
  }
109
108
  }
110
109
  var useEntityExtractionStore = zustand.create(() => ({ docIds: [] }));
@@ -174,7 +173,7 @@ function useCapturingWorkspace(mutation, capture) {
174
173
  // src/tags.ts
175
174
  function workspaceOfTag(qc, tagId) {
176
175
  for (const [key, tags] of qc.getQueriesData({
177
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.allTags()
176
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.allTags()
178
177
  })) {
179
178
  if (Array.isArray(tags) && tags.some((t) => t.external_id === tagId))
180
179
  return key[2] ?? null;
@@ -185,23 +184,23 @@ function openWorkspaceId(arbi) {
185
184
  return arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
186
185
  }
187
186
  function patchWorkspaceTags(qc, workspaceId, reducer) {
188
- const key = chunkU4PWVSCT_cjs.arbiQueryKeys.tags(workspaceId);
187
+ const key = chunkC4WODQGO_cjs.arbiQueryKeys.tags(workspaceId);
189
188
  const current = qc.getQueryData(key);
190
189
  if (!current) return;
191
190
  const next = reducer(current);
192
191
  if (next !== current) qc.setQueryData(key, next);
193
192
  }
194
193
  function invalidateTagTables(qc, workspaceId) {
195
- return qc.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.tagLists(workspaceId) });
194
+ return qc.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.tagLists(workspaceId) });
196
195
  }
197
196
  function invalidateTagData(qc, workspaceId) {
198
197
  return Promise.all([
199
- qc.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.tags(workspaceId) }),
200
- qc.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.facts(workspaceId) })
198
+ qc.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.tags(workspaceId) }),
199
+ qc.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.facts(workspaceId) })
201
200
  ]);
202
201
  }
203
202
  function useInvalidateTagData() {
204
- const arbi = chunkVGMMK5OM_cjs.useArbi();
203
+ const arbi = chunkC4WODQGO_cjs.useArbi();
205
204
  const qc = reactQuery.useQueryClient();
206
205
  return react.useCallback(() => {
207
206
  const workspaceId = openWorkspaceId(arbi);
@@ -228,19 +227,19 @@ function settleChangedTag(qc, tag) {
228
227
  }
229
228
  var replayableTagMutations = [
230
229
  {
231
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.createTag(),
230
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.createTag(),
232
231
  // In the workspace it was made in (named on the request), opened for this session first.
233
232
  run: (client, input) => inWorkspace(primeOnClient(client), input.workspaceId, () => browser.tags.createTag(client, input)),
234
233
  settle: (qc, created) => settleCreatedTag(qc, created)
235
234
  }
236
235
  ];
237
236
  function useCreateTag() {
238
- const arbi = chunkVGMMK5OM_cjs.useArbi();
237
+ const arbi = chunkC4WODQGO_cjs.useArbi();
239
238
  const qc = reactQuery.useQueryClient();
240
239
  const capture = (input) => input.workspaceId || !arbi.hasWorkspace ? input : { ...input, workspaceId: arbi.getWorkspaceId() };
241
240
  return useCapturingWorkspace(
242
241
  reactQuery.useMutation({
243
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.createTag(),
242
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.createTag(),
244
243
  mutationFn: (input) => inWorkspace(primeOnArbi(arbi), input.workspaceId, () => arbi.tags.create(input)),
245
244
  onSuccess: (created) => settleCreatedTag(qc, created),
246
245
  ...QUEUED_WRITE_RETRY
@@ -254,7 +253,7 @@ function useIsCreatingTag() {
254
253
  (name) => {
255
254
  const wanted = name.trim().toLowerCase();
256
255
  return qc.getMutationCache().findAll({
257
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.createTag(),
256
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.createTag(),
258
257
  predicate: (m) => m.state.status === "pending" && m.state.variables?.name.trim().toLowerCase() === wanted
259
258
  }).length > 0;
260
259
  },
@@ -262,19 +261,19 @@ function useIsCreatingTag() {
262
261
  );
263
262
  }
264
263
  function useUpdateTag() {
265
- const arbi = chunkVGMMK5OM_cjs.useArbi();
264
+ const arbi = chunkC4WODQGO_cjs.useArbi();
266
265
  const qc = reactQuery.useQueryClient();
267
266
  return reactQuery.useMutation({
268
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.updateTag(),
267
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.updateTag(),
269
268
  mutationFn: ({ tagId, change }) => arbi.tags.update(tagId, change),
270
269
  onSuccess: (tag) => settleChangedTag(qc, tag)
271
270
  });
272
271
  }
273
272
  function useSetTagValues() {
274
- const arbi = chunkVGMMK5OM_cjs.useArbi();
273
+ const arbi = chunkC4WODQGO_cjs.useArbi();
275
274
  const qc = reactQuery.useQueryClient();
276
275
  return reactQuery.useMutation({
277
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.updateTag(),
276
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.updateTag(),
278
277
  mutationFn: ({
279
278
  tagId,
280
279
  values
@@ -283,10 +282,10 @@ function useSetTagValues() {
283
282
  });
284
283
  }
285
284
  function useDeleteTag() {
286
- const arbi = chunkVGMMK5OM_cjs.useArbi();
285
+ const arbi = chunkC4WODQGO_cjs.useArbi();
287
286
  const qc = reactQuery.useQueryClient();
288
287
  return reactQuery.useMutation({
289
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.deleteTag(),
288
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.deleteTag(),
290
289
  mutationFn: (tagId) => arbi.tags.delete(tagId),
291
290
  // The tag's own workspace (the cached list holding it), else the one open when it is sent: a
292
291
  // switch while the delete runs must not patch the next workspace's list.
@@ -302,33 +301,33 @@ function useDeleteTag() {
302
301
  );
303
302
  return Promise.all([
304
303
  invalidateTagTables(qc, workspaceId),
305
- qc.invalidateQueries({ queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.facts(workspaceId) })
304
+ qc.invalidateQueries({ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.facts(workspaceId) })
306
305
  ]);
307
306
  }
308
307
  });
309
308
  }
310
309
  function useExtractEntities() {
311
- const arbi = chunkVGMMK5OM_cjs.useArbi();
310
+ const arbi = chunkC4WODQGO_cjs.useArbi();
312
311
  return reactQuery.useMutation({
313
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.extractEntities(),
312
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.extractEntities(),
314
313
  mutationFn: (docIds) => arbi.tags.extractEntities(docIds),
315
314
  onSuccess: (data) => startEntityExtraction(data.doc_ext_ids)
316
315
  });
317
316
  }
318
317
  function useTagKindSchema(kind, options) {
319
- const arbi = chunkVGMMK5OM_cjs.useArbi();
318
+ const arbi = chunkC4WODQGO_cjs.useArbi();
320
319
  const workspaceId = openWorkspaceId(arbi) ?? "";
321
320
  return reactQuery.useQuery({
322
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.tagKind(workspaceId, kind ?? ""),
321
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.tagKind(workspaceId, kind ?? ""),
323
322
  queryFn: () => arbi.readInWorkspace(workspaceId, () => arbi.tagKinds.get(kind)),
324
323
  enabled: (options?.enabled ?? true) && !!kind && !!workspaceId
325
324
  });
326
325
  }
327
326
  function useUpdateTagKindSchema() {
328
- const arbi = chunkVGMMK5OM_cjs.useArbi();
327
+ const arbi = chunkC4WODQGO_cjs.useArbi();
329
328
  const qc = reactQuery.useQueryClient();
330
329
  return reactQuery.useMutation({
331
- mutationKey: chunkU4PWVSCT_cjs.arbiMutationKeys.updateTagKindSchema(),
330
+ mutationKey: chunkC4WODQGO_cjs.arbiMutationKeys.updateTagKindSchema(),
332
331
  mutationFn: ({
333
332
  kind,
334
333
  fields
@@ -339,7 +338,7 @@ function useUpdateTagKindSchema() {
339
338
  onSuccess: (schema, _input, context) => {
340
339
  const workspaceId = context?.workspaceId;
341
340
  if (!workspaceId) return;
342
- qc.setQueryData(chunkU4PWVSCT_cjs.arbiQueryKeys.tagKind(workspaceId, schema.kind), schema);
341
+ qc.setQueryData(chunkC4WODQGO_cjs.arbiQueryKeys.tagKind(workspaceId, schema.kind), schema);
343
342
  return invalidateTagData(qc, workspaceId);
344
343
  }
345
344
  });
@@ -542,11 +541,11 @@ function openWorkspaceId2(arbi) {
542
541
  return arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
543
542
  }
544
543
  function useDocuments(workspaceId, options) {
545
- const arbi = chunkVGMMK5OM_cjs.useArbi();
544
+ const arbi = chunkC4WODQGO_cjs.useArbi();
546
545
  const qc = reactQuery.useQueryClient();
547
546
  const workspace = workspaceId ?? openWorkspaceId2(arbi) ?? "";
548
547
  return reactQuery.useQuery({
549
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.documents(workspace),
548
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.documents(workspace),
550
549
  queryFn: ({ signal }) => {
551
550
  if (openWorkspaceId2(arbi) !== workspace)
552
551
  return Promise.reject(new Error("The selected workspace changed."));
@@ -564,28 +563,20 @@ function processingInterval(doc) {
564
563
  return doc?.status && !FINISHED_DOCUMENT_STATUSES.has(doc.status) ? DOCUMENT_STATUS_POLL_MS : false;
565
564
  }
566
565
  function useDocument(docId, options) {
567
- const arbi = chunkVGMMK5OM_cjs.useArbi();
566
+ const arbi = chunkC4WODQGO_cjs.useArbi();
568
567
  return reactQuery.useQuery({
569
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.document(docId ?? ""),
568
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.document(docId ?? ""),
570
569
  queryFn: async () => (await arbi.documents.get([docId]))[0] ?? null,
571
570
  enabled: (options?.enabled ?? true) && !!docId && arbi.isLoggedIn,
572
571
  refetchInterval: options?.pollWhileProcessing ? (query) => processingInterval(query.state.data) : false
573
572
  });
574
573
  }
575
- function useDocumentsById(docIds, options) {
576
- const arbi = chunkVGMMK5OM_cjs.useArbi();
577
- return reactQuery.useQuery({
578
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.documentsById(docIds),
579
- queryFn: () => arbi.documents.get(docIds),
580
- enabled: (options?.enabled ?? true) && docIds.length > 0 && arbi.isLoggedIn
581
- });
582
- }
583
574
  var SIMILARITY_THRESHOLD = 0.98;
584
575
  function useSimilarDocuments(options) {
585
- const arbi = chunkVGMMK5OM_cjs.useArbi();
576
+ const arbi = chunkC4WODQGO_cjs.useArbi();
586
577
  const workspace = openWorkspaceId2(arbi) ?? "";
587
578
  return reactQuery.useQuery({
588
- queryKey: chunkU4PWVSCT_cjs.arbiQueryKeys.similarDocuments(workspace, SIMILARITY_THRESHOLD),
579
+ queryKey: chunkC4WODQGO_cjs.arbiQueryKeys.similarDocuments(workspace, SIMILARITY_THRESHOLD),
589
580
  queryFn: () => arbi.readInWorkspace(
590
581
  workspace,
591
582
  () => arbi.documents.similar({ threshold: SIMILARITY_THRESHOLD })
@@ -619,7 +610,7 @@ async function refreshDocuments(qc, arbi, docIds) {
619
610
  }
620
611
  function useRefreshDocuments() {
621
612
  const qc = reactQuery.useQueryClient();
622
- const arbi = chunkVGMMK5OM_cjs.useArbi();
613
+ const arbi = chunkC4WODQGO_cjs.useArbi();
623
614
  return react.useCallback((docIds) => refreshDocuments(qc, arbi, docIds), [qc, arbi]);
624
615
  }
625
616
  function reconcileTagCounts(qc, fresh) {
@@ -692,7 +683,6 @@ exports.useCreateTag = useCreateTag;
692
683
  exports.useDeleteTag = useDeleteTag;
693
684
  exports.useDocument = useDocument;
694
685
  exports.useDocuments = useDocuments;
695
- exports.useDocumentsById = useDocumentsById;
696
686
  exports.useDocumentsLoading = useDocumentsLoading;
697
687
  exports.useEntityExtractionDocIds = useEntityExtractionDocIds;
698
688
  exports.useExtractEntities = useExtractEntities;
@@ -704,5 +694,5 @@ exports.useSimilarDocuments = useSimilarDocuments;
704
694
  exports.useTagKindSchema = useTagKindSchema;
705
695
  exports.useUpdateTag = useUpdateTag;
706
696
  exports.useUpdateTagKindSchema = useUpdateTagKindSchema;
707
- //# sourceMappingURL=chunk-Q6U7ALNV.cjs.map
708
- //# sourceMappingURL=chunk-Q6U7ALNV.cjs.map
697
+ //# sourceMappingURL=chunk-ZHXYFJIA.cjs.map
698
+ //# sourceMappingURL=chunk-ZHXYFJIA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/documents/documents-cache.ts","../src/entity-extraction.ts","../src/queued-writes.ts","../src/tags.ts","../src/documents/documents-loader.ts","../src/documents/processing-order.ts","../src/websocket/store.ts","../src/documents/documents-data.ts"],"names":["arbiQueryKeys","update","create","isAbortError","ArbiWorkspaceUnavailableError","useRef","useCallback","useArbi","useQueryClient","arbiMutationKeys","tagOps","useMutation","useQuery","useSyncExternalStore","controller","openWorkspaceId"],"mappings":"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","file":"chunk-ZHXYFJIA.cjs","sourcesContent":["/**\n * The workspace documents list in the query cache: one entry per workspace\n * (`arbiQueryKeys.documents(workspaceId)`), read once (progressively, see `documents-loader.ts`)\n * and then kept current in place. Every write goes through {@link patchDocuments}, which also\n * tells row listeners (a grid that applies row transactions instead of re-diffing the whole list)\n * exactly which rows were added, changed or removed.\n *\n * A single document's own entry (`arbiQueryKeys.document(id)`, read by a viewer) is patched next to\n * the list by {@link setCachedDocument}, so a viewer never blanks while a write settles.\n */\n\nimport type { QueryClient } from '@tanstack/react-query'\nimport type { components } from '@arbidocs/client'\nimport { arbiQueryKeys } from '../hooks'\n\n/** A document as the server lists it. */\nexport type WorkspaceDocument = components['schemas']['DocResponse']\n\n/** The rows one write added, changed and removed (removed: by id). */\nexport interface DocumentRowChange {\n workspaceId: string\n add: WorkspaceDocument[]\n update: WorkspaceDocument[]\n remove: string[]\n}\n\ntype RowListener = (change: DocumentRowChange) => void\n\nconst rowListeners = new Set<RowListener>()\n\n/**\n * Follow the row-level changes of every write to a workspace documents list (a grid applying them\n * as transactions). Returns the unsubscribe.\n */\nexport function subscribeDocumentRows(listener: RowListener): () => void {\n rowListeners.add(listener)\n return () => {\n rowListeners.delete(listener)\n }\n}\n\n/** The cached documents of a workspace (`undefined` before its list has been read). */\nexport function getCachedDocuments(\n qc: QueryClient,\n workspaceId: string | null | undefined\n): WorkspaceDocument[] | undefined {\n if (!workspaceId) return undefined\n return qc.getQueryData<WorkspaceDocument[]>(arbiQueryKeys.documents(workspaceId))\n}\n\n/** Every cached workspace documents list, with its workspace. */\nfunction cachedLists(qc: QueryClient): Array<[string, WorkspaceDocument[]]> {\n return qc\n .getQueriesData<WorkspaceDocument[]>({ queryKey: arbiQueryKeys.allDocuments() })\n .flatMap(([key, data]) =>\n typeof key[2] === 'string' && Array.isArray(data) ? [[key[2], data]] : []\n )\n}\n\n/** Diff two versions of a list by id. */\nfunction diffRows(\n workspaceId: string,\n before: WorkspaceDocument[],\n after: WorkspaceDocument[]\n): DocumentRowChange {\n const beforeById = new Map(before.map((doc) => [doc.external_id, doc]))\n const add: WorkspaceDocument[] = []\n const update: WorkspaceDocument[] = []\n const seen = new Set<string>()\n for (const doc of after) {\n seen.add(doc.external_id)\n const previous = beforeById.get(doc.external_id)\n if (!previous) add.push(doc)\n else if (previous !== doc) update.push(doc)\n }\n const remove = [...beforeById.keys()].filter((id) => !seen.has(id))\n return { workspaceId, add, update, remove }\n}\n\n/**\n * Apply `reducer` to a workspace's documents list, or (no `workspaceId`) to every cached one: the\n * one place a list is written after it was read. Returning the same array is a no-op. Row\n * listeners get the diff; a document that moved to a new version makes the open version lists\n * re-read. A workspace whose list has not been read is left alone (its first read brings it).\n */\nexport function patchDocuments(\n qc: QueryClient,\n reducer: (documents: WorkspaceDocument[]) => WorkspaceDocument[],\n workspaceId?: string | null\n): void {\n const lists: Array<[string, WorkspaceDocument[]]> = workspaceId\n ? (() => {\n const current = getCachedDocuments(qc, workspaceId)\n return current ? [[workspaceId, current] as [string, WorkspaceDocument[]]] : []\n })()\n : cachedLists(qc)\n for (const [id, before] of lists) {\n const after = reducer(before)\n if (after === before) continue\n qc.setQueryData(arbiQueryKeys.documents(id), after)\n const change = diffRows(id, before, after)\n const beforeById = new Map(before.map((doc) => [doc.external_id, doc]))\n if (\n change.update.some(\n (doc) => doc.current_version !== beforeById.get(doc.external_id)?.current_version\n )\n )\n void qc.invalidateQueries({ queryKey: arbiQueryKeys.allDocumentVersions() })\n if (change.add.length || change.update.length || change.remove.length)\n for (const listener of rowListeners) listener(change)\n }\n}\n\n/** Put `doc` in its list in place, or at the end when the list does not hold it yet. */\nexport function upsertDocuments(\n qc: QueryClient,\n documents: WorkspaceDocument[],\n workspaceId?: string | null\n): void {\n if (!documents.length) return\n const byId = new Map(documents.map((doc) => [doc.external_id, doc]))\n const byWorkspace = new Map<string, WorkspaceDocument[]>()\n for (const doc of documents) {\n const ws = workspaceId ?? doc.workspace_ext_id\n byWorkspace.set(ws, [...(byWorkspace.get(ws) ?? []), doc])\n }\n for (const [ws, incoming] of byWorkspace) {\n patchDocuments(\n qc,\n (old) => {\n const known = new Set(old.map((doc) => doc.external_id))\n return [\n ...old.map((doc) => byId.get(doc.external_id) ?? doc),\n ...incoming.filter((doc) => !known.has(doc.external_id)),\n ]\n },\n ws\n )\n }\n}\n\n/** Write a document's own entry (what `useDocument` reads), keeping a viewer current. */\nexport function setCachedDocument(qc: QueryClient, doc: WorkspaceDocument): void {\n qc.setQueryData(arbiQueryKeys.document(doc.external_id), doc)\n}\n\n/** Apply `reducer` to a document's own entry, when one is cached. */\nexport function patchCachedDocument(\n qc: QueryClient,\n docId: string,\n reducer: (doc: WorkspaceDocument) => WorkspaceDocument\n): void {\n const current = qc.getQueryData<WorkspaceDocument | null>(arbiQueryKeys.document(docId))\n if (current) qc.setQueryData(arbiQueryKeys.document(docId), reducer(current))\n}\n\n/** A deleted tag leaves every cached document that carried it: the lists' rows and their entries. */\nexport function dropTagFromCachedDocuments(qc: QueryClient, tagId: string): void {\n const strip = (doc: WorkspaceDocument): WorkspaceDocument => {\n const doctags = doc.doctags?.filter((dt) => dt.tag_ext_id !== tagId)\n return doctags && doctags.length !== doc.doctags?.length ? { ...doc, doctags } : doc\n }\n const carriers: string[] = []\n patchDocuments(qc, (docs) => {\n const next = docs.map(strip)\n next.forEach((doc, i) => doc !== docs[i] && carriers.push(doc.external_id))\n return carriers.length ? next : docs\n })\n for (const id of carriers) patchCachedDocument(qc, id, strip)\n}\n\n/** Forget everything cached about deleted documents, so nothing re-reads them into a 404. */\nexport function forgetDocuments(qc: QueryClient, docIds: string[]): void {\n for (const id of docIds) {\n qc.removeQueries({ queryKey: arbiQueryKeys.document(id) })\n qc.removeQueries({ queryKey: arbiQueryKeys.documentVersions(id) })\n qc.removeQueries({ queryKey: arbiQueryKeys.parsedDocument(id) })\n }\n}\n","/**\n * The documents whose people and organisations are being found (`useExtractEntities`), from the\n * request until the live connection says the batch is done (`batch_complete`, `entity_extract`):\n * the package's WebSocket (`ArbiWebSocketProvider`) ends it, and a host on its own connection calls\n * `finishEntityExtraction` from its handler.\n */\n\nimport { create } from 'zustand'\n\nconst useEntityExtractionStore = create<{ docIds: readonly string[] }>(() => ({ docIds: [] }))\n\nfunction update(docIds: readonly string[], running: boolean): void {\n if (!docIds.length) return\n useEntityExtractionStore.setState((state) => {\n const ids = new Set(state.docIds)\n docIds.forEach((id) => (running ? ids.add(id) : ids.delete(id)))\n return { docIds: [...ids] }\n })\n}\n\n/** The documents an extraction was started on are running. */\nexport function startEntityExtraction(docIds: readonly string[]): void {\n update(docIds, true)\n}\n\n/** The extraction of these documents is done. */\nexport function finishEntityExtraction(docIds: readonly string[]): void {\n update(docIds, false)\n}\n\n/** The documents being extracted now. */\nexport function useEntityExtractionDocIds(): readonly string[] {\n return useEntityExtractionStore((state) => state.docIds)\n}\n","/**\n * The workspace of a write that may be queued (offline, then replayed on reconnect or after a\n * reload). The workspace is captured when the write is made and kept with it, and the write is\n * sent in that workspace: it is opened for this session first (its key deposited, without\n * switching to it), and the request names it or acts on resources the server keys by their own\n * workspace. So a replay never lands in whatever workspace happens to be open by then.\n *\n * When the workspace cannot be opened (signed out, access removed), nothing is sent: the write\n * fails with `ArbiWorkspaceUnavailableError`, is retried a few times (a reload replays before the\n * sign-in has finished), and then stays in the pending changes as not sent, with its local edit\n * kept, rather than going anywhere else.\n */\n\nimport { useCallback, useRef } from 'react'\nimport { isAbortError, type ArbiClient } from '@arbidocs/client'\nimport { ArbiWorkspaceUnavailableError } from '@arbidocs/sdk/browser'\n\n/** A queued write's own workspace (`wrk-…`), captured when it was made. */\nexport interface QueuedWriteWorkspace {\n /** The workspace the write belongs to. Filled in when it is made; absent on older queued writes. */\n workspaceId?: string\n}\n\n/** What a write that could not be sent in its workspace says. */\nexport const QUEUED_WRITE_BLOCKED_MESSAGE =\n \"This change belongs to a workspace that can't be opened right now, so it was not sent. It is kept here until it can be.\"\n\n/** Opens a workspace for this server session without switching to it (nothing for the current one). */\nexport type WorkspacePrimer = (workspaceId: string) => Promise<void> | void\n\n/** {@link WorkspacePrimer} on a bare client (a replay after a reload): its key, via `/prime-key`. */\nexport function primeOnClient(client: ArbiClient): WorkspacePrimer {\n return (workspaceId) =>\n workspaceId === client.session.getState().selectedWorkspaceId\n ? undefined\n : client.workspaceKeys.prime(workspaceId)\n}\n\n/** {@link WorkspacePrimer} on an `Arbi` (`workspaces.open`, which never switches). */\nexport function primeOnArbi(arbi: {\n hasWorkspace: boolean\n getWorkspaceId(): string\n workspaces: { open(workspaceId: string): Promise<void> }\n}): WorkspacePrimer {\n return (workspaceId) =>\n arbi.hasWorkspace && workspaceId === arbi.getWorkspaceId()\n ? undefined\n : arbi.workspaces.open(workspaceId)\n}\n\n/**\n * Run `write` in `workspaceId`: that workspace is opened for this server session first (`prime`).\n * When it can't be, nothing is sent. No workspace (a write queued before workspaces were\n * recorded): as before.\n */\nexport async function inWorkspace<T>(\n prime: WorkspacePrimer,\n workspaceId: string | null | undefined,\n write: () => Promise<T>\n): Promise<T> {\n if (workspaceId) {\n try {\n await prime(workspaceId)\n } catch (error) {\n if (isAbortError(error)) throw error\n throw new ArbiWorkspaceUnavailableError(workspaceId, error, QUEUED_WRITE_BLOCKED_MESSAGE)\n }\n }\n return write()\n}\n\n/** Whether a write failed only because its workspace could not be opened (nothing was sent). */\nexport function isWorkspaceUnavailable(error: unknown): boolean {\n return error instanceof ArbiWorkspaceUnavailableError\n}\n\n/** How many times a write whose workspace cannot be opened is tried again, and how long apart. */\nexport const QUEUED_WRITE_RETRY = {\n retry: (failureCount: number, error: unknown) =>\n isWorkspaceUnavailable(error) && failureCount < 8,\n retryDelay: (attempt: number) => Math.min(1000 * 2 ** attempt, 30_000),\n} as const\n\n/** Whether a queued write is held back because its workspace cannot be opened. */\nexport function isBlockedOnWorkspace(mutation: {\n state: { error?: unknown; failureReason?: unknown }\n}): boolean {\n return isWorkspaceUnavailable(mutation.state.error ?? mutation.state.failureReason)\n}\n\n/**\n * Fill in the workspace of each write a mutation makes, when its caller gave none: `mutate` and\n * `mutateAsync` pass `capture(variables)` on. Read when the write is made, so a write queued\n * offline keeps the workspace it was made in. The wrapped functions are as stable as the mutation's.\n */\nexport function useCapturingWorkspace<\n V,\n T extends { mutate: (variables: V, ...rest: never[]) => unknown; mutateAsync: unknown },\n>(mutation: T, capture: (variables: V) => V): T {\n const captureRef = useRef(capture)\n captureRef.current = capture\n const { mutate: rawMutate, mutateAsync: rawMutateAsync } = mutation\n const mutate = useCallback(\n (variables: V, ...rest: never[]) =>\n (rawMutate as (v: V, ...r: never[]) => unknown)(captureRef.current(variables), ...rest),\n [rawMutate]\n ) as T['mutate']\n const mutateAsync = useCallback(\n (variables: V, ...rest: never[]) =>\n (rawMutateAsync as (v: V, ...r: never[]) => Promise<unknown>)(\n captureRef.current(variables),\n ...rest\n ),\n [rawMutateAsync]\n ) as T['mutateAsync']\n return { ...mutation, mutate, mutateAsync }\n}\n","/**\n * Tags: the open workspace's tag list (`useTags()`), the writes (create, update, delete, values,\n * entity extraction), and tag kinds — a kind's fields in the workspace are the columns of a table\n * of its tags (`useTagKindSchema('issue')`), whose rows are the tag list filtered by kind with\n * links (`useTags(workspaceId, { kind, include })`).\n *\n * Everything is cached under the workspace's tags (`arbiQueryKeys.tags`). The whole list is kept\n * current in place: every write here patches it ({@link patchWorkspaceTags}, which a host also\n * uses for its own writes that move a tag's counts, e.g. applying it to documents) and refreshes\n * the filtered lists (the tables). Anything that invalidates the workspace's tags (a document batch\n * finishing, {@link useInvalidateTagData} after a doctag or fact change) refreshes them all.\n *\n * Creating a tag can be queued while offline and replayed after a reload: see `offline.ts`.\n *\n * Requires an `ArbiHost` (with an `arbi`) and a React Query client above it.\n */\n\nimport { useCallback } from 'react'\nimport { useMutation, useQuery, useQueryClient, type QueryClient } from '@tanstack/react-query'\nimport type { ArbiClient } from '@arbidocs/client'\nimport {\n tags as tagOps,\n type TagChange,\n type TagFieldDefinition,\n type TagKind,\n type TagKindSchema,\n type TagResponse,\n} from '@arbidocs/sdk/browser'\nimport { useArbi } from './useArbi'\nimport { dropTagFromCachedDocuments } from './documents/documents-cache'\nimport { startEntityExtraction } from './entity-extraction'\nimport { arbiMutationKeys, arbiQueryKeys } from './hooks'\nimport {\n QUEUED_WRITE_RETRY,\n inWorkspace,\n primeOnArbi,\n primeOnClient,\n useCapturingWorkspace,\n} from './queued-writes'\n\n/** The workspace open on `arbi`, or `null` (`getWorkspaceId()` throws when none is open). */\n/** The workspace whose cached tag list holds `tagId`, if any. */\nfunction workspaceOfTag(qc: QueryClient, tagId: string): string | null {\n for (const [key, tags] of qc.getQueriesData<TagResponse[]>({\n queryKey: arbiQueryKeys.allTags(),\n })) {\n if (Array.isArray(tags) && tags.some((t) => t.external_id === tagId))\n return (key[2] as string | undefined) ?? null\n }\n return null\n}\n\nfunction openWorkspaceId(arbi: ReturnType<typeof useArbi>): string | null {\n return arbi.hasWorkspace ? arbi.getWorkspaceId() : null\n}\n\n/**\n * Apply `reducer` to a workspace's cached tag list (nothing cached: nothing to do). The list is\n * read once, then kept current by these patches; a host's own write that changes a tag (applying\n * it to documents moves its `doctag_count`) patches it here too.\n */\nexport function patchWorkspaceTags(\n qc: QueryClient,\n workspaceId: string,\n reducer: (tags: TagResponse[]) => TagResponse[]\n): void {\n const key = arbiQueryKeys.tags(workspaceId)\n const current = qc.getQueryData<TagResponse[]>(key)\n if (!current) return\n const next = reducer(current)\n if (next !== current) qc.setQueryData(key, next)\n}\n\n/** Refetch a workspace's tables of tags (its filtered lists), not the whole list. */\nexport function invalidateTagTables(qc: QueryClient, workspaceId: string): Promise<void> {\n return qc.invalidateQueries({ queryKey: arbiQueryKeys.tagLists(workspaceId) })\n}\n\n/** Refresh what a tag, doctag or fact change affects: the workspace's tags, tables and facts. */\nexport function invalidateTagData(qc: QueryClient, workspaceId: string): Promise<unknown> {\n return Promise.all([\n qc.invalidateQueries({ queryKey: arbiQueryKeys.tags(workspaceId) }),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.facts(workspaceId) }),\n ])\n}\n\n/** {@link invalidateTagData} for the open workspace: call it after a doctag or fact write. */\nexport function useInvalidateTagData(): () => Promise<unknown> {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useCallback(() => {\n const workspaceId = openWorkspaceId(arbi)\n return workspaceId ? invalidateTagData(qc, workspaceId) : Promise.resolve()\n }, [arbi, qc])\n}\n\n/**\n * What a new tag is: its name, and optionally kind, format, parent, values, sharing, and the workspace it goes in\n * (absent: the open one).\n */\nexport type CreateTagInput = Parameters<typeof tagOps.createTag>[1]\n\n/** A created tag joins its workspace's list; the tables re-read. */\nfunction settleCreatedTag(qc: QueryClient, created: TagResponse): Promise<void> {\n const workspaceId = created.workspace_ext_id\n patchWorkspaceTags(qc, workspaceId, (old) =>\n old.some((t) => t.external_id === created.external_id) ? old : [...old, created]\n )\n return invalidateTagTables(qc, workspaceId)\n}\n\n/** A changed tag replaces its entry in the list; the tables re-read. */\nfunction settleChangedTag(qc: QueryClient, tag: TagResponse): Promise<void> {\n const workspaceId = tag.workspace_ext_id\n patchWorkspaceTags(qc, workspaceId, (old) =>\n old.map((t) => (t.external_id === tag.external_id ? { ...t, ...tag } : t))\n )\n return invalidateTagTables(qc, workspaceId)\n}\n\n/**\n * The tag writes a host may queue while offline and replay after a reload (`offline.ts`): each\n * key's request on a bare client, and what its success does to the cache.\n */\nexport const replayableTagMutations = [\n {\n mutationKey: arbiMutationKeys.createTag(),\n // In the workspace it was made in (named on the request), opened for this session first.\n run: (client: ArbiClient, input: CreateTagInput) =>\n inWorkspace(primeOnClient(client), input.workspaceId, () => tagOps.createTag(client, input)),\n settle: (qc: QueryClient, created: TagResponse) => settleCreatedTag(qc, created),\n },\n] as const\n\n/**\n * Create a tag in the open workspace, or `workspaceId` (`{ name, kind: 'issue' }`, `{ name, parentId }`, …): it is\n * added to the tag list and the tables re-read. Resolves with the new tag. Offline it is held and\n * sent on reconnect (a host that registers `registerArbiMutationDefaults` keeps it across reloads).\n */\nexport function useCreateTag() {\n const arbi = useArbi()\n const qc = useQueryClient()\n // The workspace is captured when the tag is made, so a create queued offline keeps it.\n const capture = (input: CreateTagInput): CreateTagInput =>\n input.workspaceId || !arbi.hasWorkspace\n ? input\n : { ...input, workspaceId: arbi.getWorkspaceId() }\n return useCapturingWorkspace(\n useMutation({\n mutationKey: arbiMutationKeys.createTag(),\n mutationFn: (input: CreateTagInput): Promise<TagResponse> =>\n inWorkspace(primeOnArbi(arbi), input.workspaceId, () => arbi.tags.create(input)),\n onSuccess: (created) => settleCreatedTag(qc, created),\n ...QUEUED_WRITE_RETRY,\n }),\n capture\n )\n}\n\n/**\n * Whether a tag of this name (any case) is being created right now: a second create of the same\n * name (a double Enter) is skipped instead of making a duplicate.\n */\nexport function useIsCreatingTag(): (name: string) => boolean {\n const qc = useQueryClient()\n return useCallback(\n (name: string) => {\n const wanted = name.trim().toLowerCase()\n return (\n qc.getMutationCache().findAll({\n mutationKey: arbiMutationKeys.createTag(),\n predicate: (m) =>\n m.state.status === 'pending' &&\n (m.state.variables as CreateTagInput | undefined)?.name.trim().toLowerCase() === wanted,\n }).length > 0\n )\n },\n [qc]\n )\n}\n\n/** Change a tag (name, format, instruction, parent, sharing, values): patched in the list. */\nexport function useUpdateTag() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationKey: arbiMutationKeys.updateTag(),\n mutationFn: ({ tagId, change }: { tagId: string; change: TagChange }): Promise<TagResponse> =>\n arbi.tags.update(tagId, change),\n onSuccess: (tag) => settleChangedTag(qc, tag),\n })\n}\n\n/** Merge-patch a tag's values for its kind's fields (`null` clears one); its tables refresh. */\nexport function useSetTagValues() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationKey: arbiMutationKeys.updateTag(),\n mutationFn: ({\n tagId,\n values,\n }: {\n tagId: string\n values: Record<string, unknown>\n }): Promise<TagResponse> => arbi.tags.setValues(tagId, values),\n onSuccess: (tag) => settleChangedTag(qc, tag),\n })\n}\n\n/**\n * Delete a tag: it leaves the list (its sub-tags move to the top level on the server, so the list\n * re-reads them), and the tables and facts re-read. A host that shows the tag on its own items\n * (documents' tags) follows `arbiMutationKeys.deleteTag()` to drop it there.\n */\nexport function useDeleteTag() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationKey: arbiMutationKeys.deleteTag(),\n mutationFn: (tagId: string) => arbi.tags.delete(tagId),\n // The tag's own workspace (the cached list holding it), else the one open when it is sent: a\n // switch while the delete runs must not patch the next workspace's list.\n onMutate: (tagId) => ({ workspaceId: workspaceOfTag(qc, tagId) ?? openWorkspaceId(arbi) }),\n onSuccess: (_data, tagId, context) => {\n // Its pills come off the documents grid in place (and off any open document).\n dropTagFromCachedDocuments(qc, tagId)\n const workspaceId = context?.workspaceId\n if (!workspaceId) return\n patchWorkspaceTags(qc, workspaceId, (old) =>\n old\n .filter((t) => t.external_id !== tagId)\n .map((t) => (t.parent_ext_id === tagId ? { ...t, parent_ext_id: null } : t))\n )\n return Promise.all([\n invalidateTagTables(qc, workspaceId),\n qc.invalidateQueries({ queryKey: arbiQueryKeys.facts(workspaceId) }),\n ])\n },\n })\n}\n\n/**\n * Find the people and organisations documents name and link each to its entity tag. Accepted at\n * once with the documents' ids, which show as running (`useEntityExtractionDocIds`) until a\n * `batch_complete` (`entity_extract`) WebSocket message says they are done.\n */\nexport function useExtractEntities() {\n const arbi = useArbi()\n return useMutation({\n mutationKey: arbiMutationKeys.extractEntities(),\n mutationFn: (docIds: string[]) => arbi.tags.extractEntities(docIds),\n onSuccess: (data) => startEntityExtraction(data.doc_ext_ids),\n })\n}\n\n/**\n * A kind's fields in the open workspace (`'issue'`: its issue fields): the columns of a table of\n * that kind's tags. The built-in ones (`is_default`) until the workspace sets its own.\n */\nexport function useTagKindSchema(\n kind: TagKind | null | undefined,\n options?: { enabled?: boolean }\n) {\n const arbi = useArbi()\n const workspaceId = openWorkspaceId(arbi) ?? ''\n return useQuery({\n queryKey: arbiQueryKeys.tagKind(workspaceId, kind ?? ''),\n queryFn: (): Promise<TagKindSchema> =>\n arbi.readInWorkspace(workspaceId, () => arbi.tagKinds.get(kind as TagKind)),\n enabled: (options?.enabled ?? true) && !!kind && !!workspaceId,\n })\n}\n\n/**\n * Set a kind's fields in full (a field with its `id` keeps its values; one without is new; one\n * left out is removed). The kind's schema and the workspace's tags refresh.\n */\nexport function useUpdateTagKindSchema() {\n const arbi = useArbi()\n const qc = useQueryClient()\n return useMutation({\n mutationKey: arbiMutationKeys.updateTagKindSchema(),\n mutationFn: ({\n kind,\n fields,\n }: {\n kind: TagKind\n fields: TagFieldDefinition[]\n }): Promise<TagKindSchema> => arbi.tagKinds.update(kind, fields),\n // The workspace open when it is sent (the server writes the open workspace's schema until\n // the request can name it): a switch meanwhile must not rewrite the next workspace's columns.\n onMutate: () => ({ workspaceId: openWorkspaceId(arbi) }),\n onSuccess: (schema, _input, context) => {\n const workspaceId = context?.workspaceId\n if (!workspaceId) return\n qc.setQueryData(arbiQueryKeys.tagKind(workspaceId, schema.kind), schema)\n return invalidateTagData(qc, workspaceId)\n },\n })\n}\n","/**\n * Reading a workspace's documents progressively: the first page is the query's result, so the\n * list shows within a few hundred milliseconds even for 100k documents, and the remaining pages\n * are appended to the same cache entry in the background as they arrive. One background read per\n * workspace; opening another workspace stops the previous one. Whether a background read is\n * running is observable ({@link useDocumentsLoading}), for a \"still loading\" indicator.\n */\n\nimport { useSyncExternalStore } from 'react'\nimport type { QueryClient } from '@tanstack/react-query'\nimport type { Arbi } from '@arbidocs/sdk/browser'\nimport { patchDocuments, type WorkspaceDocument } from './documents-cache'\n\n/** First page: small, so rows are on screen in a few hundred ms even in a large workspace. */\nexport const DOCUMENTS_FIRST_PAGE_SIZE = 500\n\n/** Later pages: larger, fewer round trips (the server caps a page at 10 000). */\nexport const DOCUMENTS_PAGE_SIZE = 2000\n\n/**\n * The time to the first page, as a `performance` measure of this name (a host reporting\n * performance can observe it).\n */\nexport const DOCUMENTS_FIRST_PAGE_MEASURE = 'arbi:document-list:page1'\nconst FIRST_PAGE_MEASURE = DOCUMENTS_FIRST_PAGE_MEASURE\nconst FIRST_PAGE_START = 'arbi:document-list:start'\n\nfunction mark(name: string): void {\n try {\n performance.mark(name)\n } catch {\n // No performance timeline here (an old runtime, a test): nothing to record.\n }\n}\n\nfunction measure(name: string, start: string): void {\n try {\n performance.measure(name, start)\n } catch {\n // The start mark is missing: nothing to record.\n }\n}\n\nconst backgroundReads = new Map<string, AbortController>()\nconst loadingListeners = new Set<() => void>()\n\nfunction emitLoading(): void {\n for (const listener of loadingListeners) listener()\n}\n\nfunction subscribeLoading(listener: () => void): () => void {\n loadingListeners.add(listener)\n return () => {\n loadingListeners.delete(listener)\n }\n}\n\n/** Whether a workspace's remaining document pages are being read in the background. */\nexport function isDocumentsLoading(): boolean {\n return backgroundReads.size > 0\n}\n\n/** True while the remaining pages of a documents list are still arriving. */\nexport function useDocumentsLoading(): boolean {\n return useSyncExternalStore(subscribeLoading, isDocumentsLoading, () => false)\n}\n\n/** Stop a workspace's background read (closing the workspace). */\nexport function stopDocumentsLoading(workspaceId: string): void {\n const controller = backgroundReads.get(workspaceId)\n if (!controller) return\n controller.abort()\n backgroundReads.delete(workspaceId)\n emitLoading()\n}\n\n/**\n * Read a workspace's documents: resolves with the first page and appends the rest to\n * `arbiQueryKeys.documents(workspaceId)` in the background. The query function of `useDocuments`.\n */\nexport async function loadDocuments(\n qc: QueryClient,\n arbi: Arbi,\n workspaceId: string,\n signal?: AbortSignal\n): Promise<WorkspaceDocument[]> {\n let stopped = false\n for (const [id, controller] of backgroundReads) {\n if (id === workspaceId) continue\n controller.abort()\n backgroundReads.delete(id)\n stopped = true\n }\n if (stopped) emitLoading()\n\n const controller = new AbortController()\n signal?.addEventListener('abort', () => controller.abort(), { once: true })\n // Named, not the session's open workspace: the pages are this workspace's whatever the server\n // session is in, so a list read across a workspace switch can never be another's.\n const pages = arbi.documents.listPaginated({\n workspaceId,\n pageSize: DOCUMENTS_PAGE_SIZE,\n firstPageSize: DOCUMENTS_FIRST_PAGE_SIZE,\n signal: controller.signal,\n })\n mark(FIRST_PAGE_START)\n const first = await pages.next()\n const firstPage = first.done ? [] : first.value\n measure(FIRST_PAGE_MEASURE, FIRST_PAGE_START)\n if (first.done || firstPage.length < DOCUMENTS_FIRST_PAGE_SIZE) return firstPage\n if (backgroundReads.has(workspaceId)) {\n controller.abort()\n return firstPage\n }\n\n backgroundReads.set(workspaceId, controller)\n emitLoading()\n void appendRemainingPages(qc, workspaceId, pages, controller.signal).finally(() => {\n if (backgroundReads.get(workspaceId) !== controller) return\n backgroundReads.delete(workspaceId)\n emitLoading()\n })\n return firstPage\n}\n\nasync function appendRemainingPages(\n qc: QueryClient,\n workspaceId: string,\n pages: AsyncGenerator<WorkspaceDocument[]>,\n signal: AbortSignal\n): Promise<void> {\n // Let the query store the first page before the second is appended to it.\n await Promise.resolve()\n try {\n for await (const page of pages) {\n if (signal.aborted) return\n // A write may already have added some of these (an upload finishing meanwhile).\n patchDocuments(\n qc,\n (old) => {\n const known = new Set(old.map((doc) => doc.external_id))\n const fresh = page.filter((doc) => !known.has(doc.external_id))\n return fresh.length ? [...old, ...fresh] : old\n },\n workspaceId\n )\n }\n } catch (error) {\n if (!signal.aborted) console.error(`Reading the documents of ${workspaceId} failed:`, error)\n }\n}\n\n/** Test-only: stop every background read. @internal */\nexport function resetDocumentsLoadingForTests(): void {\n for (const controller of backgroundReads.values()) controller.abort()\n backgroundReads.clear()\n emitLoading()\n}\n","/**\n * Which is newer: a document's live processing status or its row as last read?\n *\n * Every `task_update` carries `seq`, taken by the server from one sequence for all documents and\n * all of its instances, so a higher seq is a later event however the events arrive. A document row\n * carries `status_seq`: the seq of the last time its processing ended (a finished status written or\n * broadcast). The two compare:\n * - an event at or below the seq of the one already held is stale (overtaken), and is dropped;\n * - a row whose `status_seq` is above the live status's seq finished after it: the live status is\n * over (its final event was lost), and the row wins;\n * - a live status above the row's `status_seq` is newer than the row: the document is being\n * processed again (AI fields being filled) although the row still says it finished.\n *\n * Without the seqs (an optimistic \"queued\" set here, a server before them) the older rule stands:\n * a live in-flight status wins, then a finished row, then whatever was heard live.\n */\n\n/** Statuses after which a document's processing is over (`low-content`: indexed, little text). */\nexport const FINISHED_DOCUMENT_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'low-content',\n 'failed',\n 'skipped',\n 'empty',\n])\n\n/** A live processing status and its order (`task_update.seq`). */\nexport interface SequencedTask {\n status: string\n seq?: number | null\n}\n\n/** A document row's status and the order of its last finished status (`status_seq`). */\nexport interface SequencedRow {\n status?: string | null\n status_seq?: number | null\n}\n\n/** Statuses of a document still being processed. */\nexport const IN_FLIGHT_DOCUMENT_STATUSES: ReadonlySet<string> = new Set([\n 'uploading',\n 'queued',\n 'parsing',\n 'encrypting',\n 'indexing',\n 'analysing',\n])\n\nfunction ordered(value: number | null | undefined): value is number {\n return typeof value === 'number'\n}\n\n/** Whether `next` is older than (or the same event as) the live status already held. */\nexport function isStaleTaskUpdate(held: SequencedTask | undefined, next: SequencedTask): boolean {\n return !!held && ordered(held.seq) && ordered(next.seq) && next.seq <= held.seq\n}\n\n/**\n * Whether the row is newer than the live status: `true` / `false` when both are ordered, `undefined`\n * when they cannot be compared.\n */\nexport function isRowNewer(row: SequencedRow, task: SequencedTask): boolean | undefined {\n if (!ordered(row.status_seq) || !ordered(task.seq)) return undefined\n return row.status_seq > task.seq\n}\n\n/** The status a document shows now: its row's, or the live one when that is newer. */\nexport function resolveDocumentStatus(row: SequencedRow, task: SequencedTask | undefined): string {\n const rowStatus = (row.status ?? '').toLowerCase()\n const live = task?.status\n if (!task || !live) return rowStatus\n const rowNewer = isRowNewer(row, task)\n if (rowNewer !== undefined) return rowNewer ? rowStatus || live : live\n if (IN_FLIGHT_DOCUMENT_STATUSES.has(live)) return live\n if (FINISHED_DOCUMENT_STATUSES.has(rowStatus)) return rowStatus\n return live\n}\n\n/**\n * The live statuses a read of `rows` ends: each in-flight one whose row has since finished. Ordered,\n * the row must be newer (so a reprocess the row predates keeps its progress); unordered, a finished\n * row is enough (the older rule). Returns each such task with the row's status and order. Cheap when\n * nothing is in flight (it runs on every read of a list).\n */\nexport function settledByRows<T extends SequencedTask & { doc_ext_id: string }>(\n tasks: Readonly<Record<string, T>>,\n rows: ReadonlyArray<SequencedRow & { external_id: string }>\n): T[] {\n const inFlight = new Map<string, T>()\n for (const task of Object.values(tasks))\n if (IN_FLIGHT_DOCUMENT_STATUSES.has(task.status)) inFlight.set(task.doc_ext_id, task)\n if (!inFlight.size) return []\n const settled: T[] = []\n for (const row of rows) {\n const task = inFlight.get(row.external_id)\n if (!task) continue\n const rowStatus = (row.status ?? '').toLowerCase()\n if (!FINISHED_DOCUMENT_STATUSES.has(rowStatus) || isRowNewer(row, task) === false) continue\n settled.push({ ...task, status: rowStatus, seq: row.status_seq ?? task.seq })\n }\n return settled\n}\n","/**\n * Canonical WebSocket state, shared across apps.\n *\n * One store for every site's live connection: its status, people's presence and each document's\n * live processing. `ArbiWebSocketProvider` feeds it; components read it with the selector hooks in\n * `./hooks` and the documents hooks (`useProcessingTasks`, `useWorkspaceProcessing`).\n */\n\nimport { create } from 'zustand'\nimport type { WsTaskUpdateMessage, WsPresenceUpdateMessage } from '@arbidocs/client'\nimport {\n FINISHED_DOCUMENT_STATUSES,\n isStaleTaskUpdate,\n settledByRows,\n type SequencedRow,\n} from '../documents/processing-order'\n\n/** `error`: the host's socket failed. */\nexport type ArbiWsStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error'\n\n/**\n * A document's live processing: its last `task_update` (or a status set here, such as \"queued\"\n * while a write sends it back into processing), with when it was first seen (`startTime`) and\n * when it finished (`endTime`), both on this device's clock.\n */\nexport type LiveTask = Omit<WsTaskUpdateMessage, 'type' | 'seq'> & {\n type?: 'task_update'\n seq?: number | null\n startTime?: number\n endTime?: number\n}\n\n/** How long a document's tasks stay dismissed (late updates of a deleted upload are dropped). */\nexport const DISMISSED_TASK_TTL_MS = 10 * 60 * 1000\n\nexport interface ArbiWsState {\n /** Live connection status of the shared socket. */\n status: ArbiWsStatus\n /** Latest processing status per document id (the `task_update` stream). */\n tasks: Record<string, LiveTask>\n /** Documents whose processing rows were dismissed (deleted, cleared), with when. */\n dismissed: Record<string, number>\n /** The most recent `task_update` — a convenient single-value change trigger. */\n lastTaskUpdate: WsTaskUpdateMessage | null\n /** Online status keyed by user id (the `presence_update` stream). */\n presence: Record<string, string>\n /**\n * The server closed this socket for a newer session of the same user (another device, close\n * code 1008). The socket stays closed: reconnecting would only be evicted again.\n */\n evicted: boolean\n setStatus: (status: ArbiWsStatus) => void\n setEvicted: (evicted: boolean) => void\n /**\n * Take a `task_update`, unless it is older than the one held for its document (`seq`) or the\n * document was dismissed a moment ago. Resolves whether it was taken.\n */\n applyTaskUpdate: (msg: WsTaskUpdateMessage) => boolean\n /** Set a document's live processing directly (an optimistic status, or an undo). */\n putTask: (task: LiveTask) => void\n /** Drop a document's processing row, and ignore its late updates for a while. */\n clearTask: (docId: string) => void\n /** Drop every finished processing row (the in-flight ones stay). */\n clearFinishedTasks: () => void\n /** End the in-flight statuses that documents read since say finished after them. */\n settleTasks: (rows: ReadonlyArray<SequencedRow & { external_id: string }>) => void\n applyPresence: (msg: WsPresenceUpdateMessage) => void\n reset: () => void\n}\n\nconst finished = (status: string) => FINISHED_DOCUMENT_STATUSES.has(status)\n\nexport const useArbiWsStore = create<ArbiWsState>((set, get) => ({\n status: 'disconnected',\n tasks: {},\n dismissed: {},\n lastTaskUpdate: null,\n presence: {},\n evicted: false,\n setStatus: (status) => set({ status }),\n setEvicted: (evicted) => set({ evicted }),\n applyTaskUpdate: (msg) => {\n const { tasks, dismissed } = get()\n const dismissedAt = dismissed[msg.doc_ext_id]\n if (dismissedAt !== undefined && Date.now() - dismissedAt < DISMISSED_TASK_TTL_MS) return false\n const held = tasks[msg.doc_ext_id]\n if (isStaleTaskUpdate(held, msg)) return false\n const now = Date.now()\n const task: LiveTask = {\n ...msg,\n startTime: held?.startTime ?? now,\n endTime: finished(msg.status) ? (held?.endTime ?? now) : undefined,\n }\n set({ tasks: { ...tasks, [msg.doc_ext_id]: task }, lastTaskUpdate: msg })\n return true\n },\n putTask: (task) => set((s) => ({ tasks: { ...s.tasks, [task.doc_ext_id]: task } })),\n clearTask: (docId) =>\n set((s) => {\n const tasks = { ...s.tasks }\n delete tasks[docId]\n return { tasks, dismissed: { ...s.dismissed, [docId]: Date.now() } }\n }),\n clearFinishedTasks: () =>\n set((s) => ({\n tasks: Object.fromEntries(Object.entries(s.tasks).filter(([, t]) => !finished(t.status))),\n })),\n settleTasks: (rows) =>\n set((s) => {\n const settled = settledByRows(s.tasks, rows)\n if (!settled.length) return s\n const tasks = { ...s.tasks }\n const now = Date.now()\n for (const task of settled)\n tasks[task.doc_ext_id] = { ...(task as LiveTask), endTime: task.endTime ?? now }\n return { tasks }\n }),\n applyPresence: (msg) => set((s) => ({ presence: { ...s.presence, [msg.user_id]: msg.status } })),\n reset: () =>\n set({ status: 'disconnected', tasks: {}, dismissed: {}, lastTaskUpdate: null, presence: {} }),\n}))\n","/**\n * Reading documents: a workspace's list (`useDocuments`, progressive, read once and then patched in\n * place), one document (`useDocument`, for a viewer), a set of documents by id, near-duplicate pairs\n * (`useSimilarDocuments`), and {@link refreshDocuments}, which re-reads just the documents an event\n * named and patches them into every cache that shows them.\n */\n\nimport { useCallback } from 'react'\nimport { useQuery, useQueryClient, type QueryClient } from '@tanstack/react-query'\nimport type { Arbi } from '@arbidocs/sdk/browser'\nimport { useArbi } from '../useArbi'\nimport { arbiQueryKeys } from '../hooks'\nimport { invalidateTagTables, patchWorkspaceTags } from '../tags'\nimport {\n getCachedDocuments,\n setCachedDocument,\n upsertDocuments,\n type WorkspaceDocument,\n} from './documents-cache'\nimport { loadDocuments } from './documents-loader'\nimport { FINISHED_DOCUMENT_STATUSES, isRowNewer } from './processing-order'\nimport { useArbiWsStore } from '../websocket/store'\n\nexport { FINISHED_DOCUMENT_STATUSES }\n\n/** The workspace open on `arbi`, or `null`. */\nfunction openWorkspaceId(arbi: Arbi): string | null {\n return arbi.hasWorkspace ? arbi.getWorkspaceId() : null\n}\n\n/**\n * A workspace's documents (default: the open one). Read progressively: the first page is the\n * result, the remaining pages arrive in the background (`useDocumentsLoading`). After that the list\n * is never re-read on its own (mounting, focus, reconnecting): writes, processing events and\n * {@link refreshDocuments} patch it in place, as re-reading 100k documents is slow and tells\n * nothing new. Invalidating it re-reads it.\n */\nexport function useDocuments(workspaceId?: string | null, options?: { enabled?: boolean }) {\n const arbi = useArbi()\n const qc = useQueryClient()\n const workspace = workspaceId ?? openWorkspaceId(arbi) ?? ''\n return useQuery({\n queryKey: arbiQueryKeys.documents(workspace),\n queryFn: ({ signal }) => {\n if (openWorkspaceId(arbi) !== workspace)\n return Promise.reject(new Error('The selected workspace changed.'))\n return loadDocuments(qc, arbi, workspace, signal)\n },\n enabled: (options?.enabled ?? true) && !!workspace && arbi.hasWorkspace,\n staleTime: Infinity,\n refetchOnMount: false,\n refetchOnReconnect: false,\n refetchOnWindowFocus: false,\n })\n}\n\n/** How often a document still being processed is re-read (`useDocument`'s `pollWhileProcessing`). */\nexport const DOCUMENT_STATUS_POLL_MS = 4000\n\n/** Re-read a document while it is processing (a viewer waiting for its pages). */\nfunction processingInterval(doc: WorkspaceDocument | null | undefined): number | false {\n return doc?.status && !FINISHED_DOCUMENT_STATUSES.has(doc.status)\n ? DOCUMENT_STATUS_POLL_MS\n : false\n}\n\n/**\n * One document (`null`: not found or not visible). `pollWhileProcessing` re-reads it every few\n * seconds until its processing is over. Writes here keep it current.\n */\nexport function useDocument(\n docId: string | null | undefined,\n options?: { enabled?: boolean; pollWhileProcessing?: boolean }\n) {\n const arbi = useArbi()\n return useQuery({\n queryKey: arbiQueryKeys.document(docId ?? ''),\n queryFn: async (): Promise<WorkspaceDocument | null> =>\n (await arbi.documents.get([docId as string]))[0] ?? null,\n enabled: (options?.enabled ?? true) && !!docId && arbi.isLoggedIn,\n refetchInterval: options?.pollWhileProcessing\n ? (query) => processingInterval(query.state.data)\n : false,\n })\n}\n\n/**\n * The similarity at or above which two documents count as near duplicates (the Related column).\n * The server keeps every pair above 0.75 but returns only those at or above what is asked.\n */\nexport const SIMILARITY_THRESHOLD = 0.98\n\n/** Near-duplicate document pairs in the open workspace, at or above {@link SIMILARITY_THRESHOLD}. */\nexport function useSimilarDocuments(options?: { enabled?: boolean }) {\n const arbi = useArbi()\n const workspace = openWorkspaceId(arbi) ?? ''\n return useQuery({\n queryKey: arbiQueryKeys.similarDocuments(workspace, SIMILARITY_THRESHOLD),\n queryFn: () =>\n arbi.readInWorkspace(workspace, () =>\n arbi.documents.similar({ threshold: SIMILARITY_THRESHOLD })\n ),\n enabled: (options?.enabled ?? true) && !!workspace,\n })\n}\n\n// Each re-read gets a number; only the latest one issued for a document may write it. Events can\n// return out of order, and an older read must not undo tags a newer one applied.\nlet readSeq = 0\nconst latestReadByDoc = new Map<string, number>()\n\n/**\n * Re-read `docIds` and patch them into the caches that show them: their workspace's list (added\n * when new), their own entries, and the tag list's document counts (tags the server applied, e.g.\n * AI fields). For events that name documents (a batch finished, a version saved, an upload): the\n * list is never re-read for them. A failed read leaves the caches as they were.\n */\nexport async function refreshDocuments(\n qc: QueryClient,\n arbi: Arbi,\n docIds: string[]\n): Promise<WorkspaceDocument[]> {\n if (!docIds.length) return []\n const seq = ++readSeq\n for (const id of docIds) latestReadByDoc.set(id, seq)\n try {\n const read = await arbi.documents.get(docIds)\n const fresh = read\n .filter((doc) => latestReadByDoc.get(doc.external_id) === seq)\n .map((doc) => {\n // A finished status heard live wins over a read that predates it (the row may not be\n // committed yet), never over a row that finished after it.\n const live = useArbiWsStore.getState().tasks[doc.external_id]\n return live &&\n FINISHED_DOCUMENT_STATUSES.has(live.status) &&\n doc.status !== live.status &&\n isRowNewer(doc, live) !== true\n ? { ...doc, status: live.status }\n : doc\n })\n if (!fresh.length) return []\n reconcileTagCounts(qc, fresh)\n upsertDocuments(qc, fresh)\n for (const doc of fresh) setCachedDocument(qc, doc)\n return fresh\n } catch (error) {\n // Leave the caches as they were: re-reading the whole list would shrink it to its first page.\n console.error('Re-reading documents failed; the cached ones are kept:', error)\n return []\n } finally {\n for (const id of docIds) if (latestReadByDoc.get(id) === seq) latestReadByDoc.delete(id)\n }\n}\n\n/** `refreshDocuments` on this host's cache and `Arbi`, for a component or a hook. */\nexport function useRefreshDocuments(): (docIds: string[]) => Promise<WorkspaceDocument[]> {\n const qc = useQueryClient()\n const arbi = useArbi()\n return useCallback((docIds: string[]) => refreshDocuments(qc, arbi, docIds), [qc, arbi])\n}\n\n/** Move each tag's document count by the tags the re-read documents gained or lost. */\nfunction reconcileTagCounts(qc: QueryClient, fresh: WorkspaceDocument[]): void {\n const byWorkspace = new Map<string, Map<string, number>>()\n for (const doc of fresh) {\n const cached = getCachedDocuments(qc, doc.workspace_ext_id)?.find(\n (d) => d.external_id === doc.external_id\n )\n const before = new Set((cached?.doctags ?? []).map((dt) => dt.tag_ext_id))\n const after = new Set((doc.doctags ?? []).map((dt) => dt.tag_ext_id))\n const delta = byWorkspace.get(doc.workspace_ext_id) ?? new Map<string, number>()\n for (const id of after) if (!before.has(id)) delta.set(id, (delta.get(id) ?? 0) + 1)\n for (const id of before) if (!after.has(id)) delta.set(id, (delta.get(id) ?? 0) - 1)\n byWorkspace.set(doc.workspace_ext_id, delta)\n }\n for (const [workspaceId, delta] of byWorkspace) adjustTagCounts(qc, workspaceId, delta)\n}\n\n/** Add `delta` (tag id → change) to the tags' document counts; the tag tables re-read. */\nexport function adjustTagCounts(\n qc: QueryClient,\n workspaceId: string,\n delta: Map<string, number>\n): void {\n if (![...delta.values()].some(Boolean)) return\n patchWorkspaceTags(qc, workspaceId, (tags) =>\n tags.map((tag) => {\n const change = delta.get(tag.external_id)\n return change ? { ...tag, doctag_count: Math.max(0, tag.doctag_count + change) } : tag\n })\n )\n void invalidateTagTables(qc, workspaceId)\n}\n"]}