@arbidocs/react 0.5.88 → 0.5.90
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.
- package/README.md +11 -6
- package/dist/artifacts/index.cjs +13 -13
- package/dist/artifacts/index.js +3 -3
- package/dist/calls/livekit/index.cjs +48 -48
- package/dist/calls/livekit/index.js +3 -3
- package/dist/{chunk-DS7NTSKH.cjs → chunk-6BXRZYL2.cjs} +38 -38
- package/dist/{chunk-DS7NTSKH.cjs.map → chunk-6BXRZYL2.cjs.map} +1 -1
- package/dist/{chunk-BFNY3RZG.js → chunk-7PMNITKA.js} +2 -2
- package/dist/chunk-7PMNITKA.js.map +1 -0
- package/dist/{chunk-AOPGD23L.cjs → chunk-7RUVJZZG.cjs} +57 -57
- package/dist/{chunk-AOPGD23L.cjs.map → chunk-7RUVJZZG.cjs.map} +1 -1
- package/dist/{chunk-C4WODQGO.cjs → chunk-BRFRQWAY.cjs} +2 -2
- package/dist/chunk-BRFRQWAY.cjs.map +1 -0
- package/dist/{chunk-YQBDEOVE.js → chunk-HGLS3IC6.js} +3 -3
- package/dist/{chunk-YQBDEOVE.js.map → chunk-HGLS3IC6.js.map} +1 -1
- package/dist/{chunk-DU2P354H.js → chunk-IIOOXKOB.js} +4 -4
- package/dist/{chunk-DU2P354H.js.map → chunk-IIOOXKOB.js.map} +1 -1
- package/dist/{chunk-S3OGDLDC.js → chunk-KZBYWXPS.js} +3 -3
- package/dist/{chunk-S3OGDLDC.js.map → chunk-KZBYWXPS.js.map} +1 -1
- package/dist/{chunk-KTXZ222T.js → chunk-N3SFVZ7H.js} +3 -3
- package/dist/{chunk-KTXZ222T.js.map → chunk-N3SFVZ7H.js.map} +1 -1
- package/dist/{chunk-GKWMT64A.cjs → chunk-NJDVQIJR.cjs} +4 -4
- package/dist/{chunk-GKWMT64A.cjs.map → chunk-NJDVQIJR.cjs.map} +1 -1
- package/dist/{chunk-ZHXYFJIA.cjs → chunk-NR6PUE5O.cjs} +44 -44
- package/dist/{chunk-ZHXYFJIA.cjs.map → chunk-NR6PUE5O.cjs.map} +1 -1
- package/dist/{chunk-73ENECAT.js → chunk-RIPYDSRJ.js} +259 -10
- package/dist/chunk-RIPYDSRJ.js.map +1 -0
- package/dist/{chunk-QLRDHLWR.cjs → chunk-X4HGUBWU.cjs} +344 -69
- package/dist/chunk-X4HGUBWU.cjs.map +1 -0
- package/dist/document-tools/core.cjs +98 -98
- package/dist/document-tools/core.js +3 -3
- package/dist/document-tools/index.cjs +100 -100
- package/dist/document-tools/index.js +4 -4
- package/dist/index.cjs +5882 -5768
- package/dist/index.cjs.map +1 -1
- package/dist/{index.d-1_bJB-Yl.d.ts → index.d-BMhTH98a.d.cts} +65 -65
- package/dist/{index.d-1_bJB-Yl.d.cts → index.d-BMhTH98a.d.ts} +65 -65
- package/dist/index.d.cts +123 -43
- package/dist/index.d.ts +123 -43
- package/dist/index.js +4986 -4879
- package/dist/index.js.map +1 -1
- package/dist/ui/index.d.cts +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/package.json +3 -3
- package/dist/chunk-73ENECAT.js.map +0 -1
- package/dist/chunk-BFNY3RZG.js.map +0 -1
- package/dist/chunk-C4WODQGO.cjs.map +0 -1
- package/dist/chunk-QLRDHLWR.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkBRFRQWAY_cjs = require('./chunk-BRFRQWAY.cjs');
|
|
4
4
|
var chunkNDIKMOBJ_cjs = require('./chunk-NDIKMOBJ.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -47,7 +47,7 @@ function certificateLink(signature, certificateUrl) {
|
|
|
47
47
|
}
|
|
48
48
|
var DocumentToolsContext = react.createContext(null);
|
|
49
49
|
function DocumentToolsProvider({ children, ...env }) {
|
|
50
|
-
const arbiDeploymentDomain =
|
|
50
|
+
const arbiDeploymentDomain = chunkBRFRQWAY_cjs.useDeploymentDomain();
|
|
51
51
|
const guards = react.useRef(/* @__PURE__ */ new Map());
|
|
52
52
|
const pendingFlushes = react.useRef(/* @__PURE__ */ new Map());
|
|
53
53
|
const registerBeforeFileShare = react.useCallback((id, flush) => {
|
|
@@ -248,5 +248,5 @@ exports.isSignedVersion = isSignedVersion;
|
|
|
248
248
|
exports.uploadQueryString = uploadQueryString;
|
|
249
249
|
exports.useDocumentTools = useDocumentTools;
|
|
250
250
|
exports.useOptionalDocumentTools = useOptionalDocumentTools;
|
|
251
|
-
//# sourceMappingURL=chunk-
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
251
|
+
//# sourceMappingURL=chunk-NJDVQIJR.cjs.map
|
|
252
|
+
//# sourceMappingURL=chunk-NJDVQIJR.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":["createContext","useDeploymentDomain","useRef","useCallback","useMemo","jsx","useContext","parseVersionRef"],"mappings":"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","file":"chunk-GKWMT64A.cjs","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: { path: { document_ext_id: ref.docId }, query: version ? { version } : {} },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: { path: { document_ext_id: documentId }, query: version ? { version } : {} },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/document-tools/environment.tsx","../src/document-tools/document-pdf.ts","../src/document-tools/markup-download.ts"],"names":["createContext","useDeploymentDomain","useRef","useCallback","useMemo","jsx","useContext","parseVersionRef"],"mappings":"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","file":"chunk-NJDVQIJR.cjs","sourcesContent":["/**\n * The host app's side of the document tools (markup, freeze, e-signing, versions): the one place\n * the tools reach the app. They never import a store, a router, a toast library or app API code;\n * the host passes what it has to `<DocumentToolsProvider>` and every optional field has a default.\n *\n * `client` is an openapi-fetch client for the ARBI API (`ArbiClient['fetch']` from\n * `@arbidocs/client`, or `arbi.getClient().fetch` from an `@arbidocs/sdk` `Arbi`), signed in with the\n * user's session; it carries the auth.\n */\n\nimport { createContext, useCallback, useContext, useMemo, useRef, type ReactNode } from 'react'\nimport type { ArbiClient, operations } from '@arbidocs/client'\nimport { useDeploymentDomain } from '../useArbi'\n\nexport type DocumentToolsClient = ArbiClient['fetch']\n\nexport type DocumentToolsNoticeKind = 'success' | 'error' | 'info' | 'warning'\n\nexport interface DocumentToolsNoticeOptions {\n /** A second line under the message. */\n description?: string\n /** One action button on the notice (\"Email it\"). */\n action?: { label: string; onClick: () => void }\n}\n\nexport type DocumentToolsNotify = (\n message: string,\n kind: DocumentToolsNoticeKind,\n options?: DocumentToolsNoticeOptions\n) => void\n\nexport interface DocumentToolsUser {\n /** The name marks are authored as and the signer's name is prefilled with. */\n name: string\n /** The sign-in email: signing re-derives the user's key from it and the password. */\n email?: string | null\n /** The user's id (usr-*): which fields of a signature request are theirs. */\n externalId?: string | null\n}\n\n/** What changed about a document, so the host can refresh its own lists and caches. */\nexport type DocumentChange =\n /** A version's markup got its first mark or lost its last one. */\n | 'markup'\n /** A signature was added: the document has a new current version. */\n | 'signed'\n /** A new document was made from it (a frozen copy). The ids are the NEW documents. */\n | 'copy'\n /** A new version was saved (the Word editor's Save version): the document's current version. */\n | 'version'\n\n/**\n * The `/v1/document/upload` query, typed from the API schema: `derived_from` is a list (a\n * production set is derived from every document in it), `shared` a boolean.\n */\nexport type DocumentUploadQuery = NonNullable<operations['upload_documents']['parameters']['query']>\n\nexport interface DocumentUploadRequest {\n file: File\n /** `/v1/document/upload` query: `derived_from`, `derived_role`, `shared`, `folder`. */\n query: DocumentUploadQuery\n}\n\n/**\n * The upload query as a URL query string, for a host that posts the upload itself (an XHR with\n * progress): a list repeats its key (`derived_from=a&derived_from=b`), empty values are left out.\n */\nexport function uploadQueryString(query: DocumentUploadQuery): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value === null || value === undefined) continue\n for (const item of Array.isArray(value) ? value : [value]) params.append(key, String(item))\n }\n return params.toString()\n}\n\nexport interface DocumentToolsEnvironment {\n client: DocumentToolsClient\n /**\n * The deployment domain the user's keys are derived for. Needed for signing. Default: the one\n * the host's `Arbi` computes (`arbi.getDeploymentDomain()`), if any.\n */\n deploymentDomain?: string\n /** The signed-in user; marks are authored as \"You\" without one, and signing is unavailable. */\n user?: DocumentToolsUser | null\n /** Surface a transient message. Default: none (errors still show inline where they can). */\n notify?: DocumentToolsNotify\n /** Open a document or a version reference (`doc-…@v2`): the copy just made, the signed copy. */\n openDocument?: (documentRef: string) => void\n /**\n * Documents changed on the server (see {@link DocumentChange}); refresh the host's lists. The\n * tools wait for it before opening the document, so a copy is listed when it opens.\n */\n onDocumentsChanged?: (documentIds: string[], change: DocumentChange) => void | Promise<void>\n /** Upload a derived copy. Default: `POST /v1/document/upload` through `client`. */\n uploadDocument?: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n /** Save a file to the user's computer. Default: a temporary download link. */\n saveFile?: (blob: Blob, fileName: string) => void\n /** Email a document (offered once it is signed). Omitted: no \"Email it\". */\n emailDocument?: (documentRef: string) => void\n /**\n * The public page that checks a signature (the certificate) in this app. When given, \"View\n * certificate\" opens it in preference to the backend's `certificate_url` (which is on the\n * deployment domain, like the link embedded in the signed PDF). Without it: the backend's\n * `certificate_url`, else `/verify/{reference}` on this origin.\n */\n certificateUrl?: (reference: string) => string\n}\n\n/** The environment with every default filled in. */\nexport interface ResolvedDocumentToolsEnvironment extends DocumentToolsEnvironment {\n prepareFileShare: (documentId: string) => Promise<void>\n registerBeforeFileShare: (documentId: string, flush: () => Promise<void>) => () => void\n notify: DocumentToolsNotify\n saveFile: (blob: Blob, fileName: string) => void\n uploadDocument: (\n request: DocumentUploadRequest\n ) => Promise<{ doc_ext_ids?: string[] } | undefined>\n}\n\n/**\n * Save a blob through a temporary `<a download>`. The object URL is revoked a minute later, not at\n * once: revoking straight after `click()` can cancel the download (Safari, and large files\n * elsewhere) before the browser has read the blob.\n */\nexport function downloadBlob(blob: Blob, fileName: string): void {\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = fileName\n document.body.appendChild(a)\n a.click()\n a.remove()\n setTimeout(() => URL.revokeObjectURL(url), 60_000)\n}\n\n/** The default upload: multipart `files` to `/v1/document/upload` through the API client. */\nexport function clientUpload(client: DocumentToolsClient) {\n return async ({ file, query }: DocumentUploadRequest) => {\n const formData = new FormData()\n formData.append('files', file)\n const { data, response } = await client.POST('/v1/document/upload', {\n params: { query },\n // The schema types the multipart body as `{ files: string[] }`; the FormData is sent as is.\n body: formData as unknown as { files: string[] },\n bodySerializer: () => formData,\n })\n if (!response.ok) throw new Error(`Upload failed with status ${response.status}`)\n return data\n }\n}\n\nexport function defaultCertificateUrl(reference: string): string {\n const origin = typeof location === 'undefined' ? '' : location.origin\n return `${origin}/verify/${encodeURIComponent(reference)}`\n}\n\n/**\n * Where \"View certificate\" goes for a signature: the host's `certificateUrl(reference)` when it\n * gives one, else the `certificate_url` the backend returned, else `/verify/{reference}` here.\n */\nexport function certificateLink(\n signature: { reference: string; certificate_url?: string | null },\n certificateUrl?: (reference: string) => string\n): string {\n if (certificateUrl) return certificateUrl(signature.reference)\n return signature.certificate_url || defaultCertificateUrl(signature.reference)\n}\n\nconst DocumentToolsContext = createContext<ResolvedDocumentToolsEnvironment | null>(null)\n\nexport interface DocumentToolsProviderProps extends DocumentToolsEnvironment {\n children: ReactNode\n}\n\nexport function DocumentToolsProvider({ children, ...env }: DocumentToolsProviderProps) {\n const arbiDeploymentDomain = useDeploymentDomain()\n const guards = useRef(new Map<string, () => Promise<void>>())\n const pendingFlushes = useRef(new Map<string, Promise<void>>())\n const registerBeforeFileShare = useCallback((id: string, flush: () => Promise<void>) => {\n guards.current.set(id, flush)\n return () => {\n if (guards.current.get(id) !== flush) return\n guards.current.delete(id)\n const pending = flush()\n pendingFlushes.current.set(id, pending)\n void pending.then(\n () => {\n if (pendingFlushes.current.get(id) === pending) pendingFlushes.current.delete(id)\n },\n () => {}\n )\n }\n }, [])\n const prepareFileShare = useCallback(async (id: string) => {\n const guard = guards.current.get(id)\n if (guard) {\n await guard()\n pendingFlushes.current.delete(id)\n } else await pendingFlushes.current.get(id)\n }, [])\n const {\n client,\n deploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n } = env\n const value = useMemo<ResolvedDocumentToolsEnvironment>(\n () => ({\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain: deploymentDomain ?? arbiDeploymentDomain,\n user,\n openDocument,\n onDocumentsChanged,\n emailDocument,\n notify: notify ?? (() => {}),\n saveFile: saveFile ?? downloadBlob,\n uploadDocument: uploadDocument ?? clientUpload(client),\n certificateUrl,\n }),\n [\n client,\n prepareFileShare,\n registerBeforeFileShare,\n deploymentDomain,\n arbiDeploymentDomain,\n user,\n notify,\n openDocument,\n onDocumentsChanged,\n uploadDocument,\n saveFile,\n emailDocument,\n certificateUrl,\n ]\n )\n return <DocumentToolsContext.Provider value={value}>{children}</DocumentToolsContext.Provider>\n}\n\n/** The host's environment, or `null` outside a `<DocumentToolsProvider>`. */\nexport function useOptionalDocumentTools(): ResolvedDocumentToolsEnvironment | null {\n return useContext(DocumentToolsContext)\n}\n\n/** The host's environment; throws outside a `<DocumentToolsProvider>`. */\nexport function useDocumentTools(): ResolvedDocumentToolsEnvironment {\n const env = useContext(DocumentToolsContext)\n if (!env) throw new Error('The document tools must be used within a <DocumentToolsProvider>')\n return env\n}\n","/**\n * A document's bytes, through the host's API client: the PDF the viewer and the tools draw on\n * (`/view`: the file itself for a PDF, its PDF rendering for a Word or text file) and the stored\n * file (`/download`). Either takes a document id or a version reference `doc-…@v{n}`.\n */\n\nimport { parseVersionRef } from '../artifacts/versions'\nimport type { DocumentToolsClient } from './environment'\n\nexport interface DocumentFetchOptions {\n /** The version to fetch. Default: the one `documentRef` names, else the current version. */\n version?: number | null\n signal?: AbortSignal\n}\n\n/** A document's bytes could not be fetched; `status` is the HTTP status. */\nexport class DocumentFetchError extends Error {\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'DocumentFetchError'\n this.status = status\n }\n}\n\nasync function fetchDocumentBytes(\n client: DocumentToolsClient,\n endpoint: '/v1/document/{document_ext_id}/view' | '/v1/document/{document_ext_id}/download',\n documentRef: string,\n options: DocumentFetchOptions,\n headers: Record<string, string>,\n what: string\n): Promise<{ blob: Blob; response: Response }> {\n const ref = parseVersionRef(documentRef)\n const version = options.version ?? ref.version\n const { data, response } = await client.GET(endpoint, {\n params: { path: { document_ext_id: ref.docId }, query: version ? { version } : {} },\n headers,\n parseAs: 'blob',\n signal: options.signal,\n })\n if (!response.ok || !(data instanceof Blob)) {\n throw new DocumentFetchError(\n `${what} could not be loaded (${response.status})`,\n response.status\n )\n }\n return { blob: data, response }\n}\n\n/**\n * The file name a `Content-Disposition` header gives, or `undefined`. Prefers the RFC 5987\n * `filename*=UTF-8''…` form (percent-encoded, any script) over the plain `filename=`.\n */\nexport function contentDispositionFileName(header: string | null | undefined): string | undefined {\n if (!header) return undefined\n const extended = /filename\\*\\s*=\\s*(?:[\\w-]+)?'[^']*'([^;]+)/i.exec(header)\n if (extended) {\n try {\n return decodeURIComponent(extended[1].trim().replace(/^\"|\"$/g, '')) || undefined\n } catch {\n // A malformed escape: fall back to the plain parameter.\n }\n }\n const plain = /filename\\s*=\\s*(\"((?:[^\"\\\\]|\\\\.)*)\"|[^;]+)/i.exec(header)\n if (!plain) return undefined\n const name = plain[2] !== undefined ? plain[2].replace(/\\\\(.)/g, '$1') : plain[1].trim()\n return name || undefined\n}\n\n/**\n * The PDF of a document version: `GET /v1/document/{id}/view?version=` with\n * `Accept: application/pdf`. Throws a {@link DocumentFetchError} when there is none (yet).\n */\nexport async function fetchDocumentPdf(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob> {\n const { blob } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/view',\n documentRef,\n options,\n { Accept: 'application/pdf' },\n 'The PDF'\n )\n return blob\n}\n\n/**\n * The stored file of a document version, as uploaded: `GET /v1/document/{id}/download`. When the\n * server names the file (`Content-Disposition`), the result is a `File` carrying that name.\n */\nexport async function fetchDocumentFile(\n client: DocumentToolsClient,\n documentRef: string,\n options: DocumentFetchOptions = {}\n): Promise<Blob | File> {\n const { blob, response } = await fetchDocumentBytes(\n client,\n '/v1/document/{document_ext_id}/download',\n documentRef,\n options,\n {},\n 'The file'\n )\n const name = contentDispositionFileName(response.headers.get('Content-Disposition'))\n return name ? new File([blob], name, { type: blob.type }) : blob\n}\n","/**\n * \"Download with markup\": a document version's markup PDF, the PDF with its annotations as native\n * PDF annotations (comments, highlights, stamps, unapplied redactions), which Acrobat and Preview\n * show. The plain Download serves the original. Kept apart from the annotation layer code so a\n * documents list can offer it without loading the annotation tools.\n *\n * A SIGNED version is locked: nothing but a further signature changes it. Its markup stays in the\n * separate markup layer (a title beside the signature, say) and is never written into its PDF, so\n * it has no \"Download with markup\"; the plain Download is the signed file as it is.\n */\n\nimport type { DocumentToolsClient } from './environment'\n\ninterface DocumentVersions {\n current_version?: number | null\n versions?: Array<{ n: number; markup_count?: number | null; reason?: string | null }> | null\n}\n\n/** Why \"Download with markup\" is off for a signed version. */\nexport const SIGNED_LOCKED_REASON =\n \"Signed documents can't be changed — download the signed file instead\"\n\n/** Whether a version (default: the current one) is a signed copy, per its version entry. */\nexport function isSignedVersion(doc: DocumentVersions, version?: number): boolean {\n const n = version ?? doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && v.reason === 'signed')\n}\n\nexport class MarkupDownloadError extends Error {\n constructor(\n message: string,\n readonly status?: number\n ) {\n super(message)\n this.name = 'MarkupDownloadError'\n }\n}\n\n/** Whether a document's current version has markup (per its version entries). */\nexport function currentHasMarkup(doc: DocumentVersions): boolean {\n const n = doc.current_version ?? 1\n return (doc.versions ?? []).some((v) => v.n === n && (v.markup_count ?? 0) > 0)\n}\n\n/** Fetch a version's markup PDF (default: the current version's). */\nexport async function fetchMarkupPdf(\n client: DocumentToolsClient,\n documentId: string,\n version?: number\n): Promise<{ blob: Blob; fileName: string }> {\n const { data, response } = await client.GET('/v1/document/{document_ext_id}/markup/pdf', {\n params: { path: { document_ext_id: documentId }, query: version ? { version } : {} },\n parseAs: 'blob',\n })\n if (!response.ok || !data) {\n throw new MarkupDownloadError(\n response.status === 404\n ? 'This document has no markup yet'\n : // The server refuses a signed version: its PDF takes no more changes.\n response.status === 409\n ? SIGNED_LOCKED_REASON\n : 'The markup could not be downloaded',\n response.status\n )\n }\n const disposition = response.headers.get('content-disposition') ?? ''\n const utf8 = /filename\\*=UTF-8''([^;]+)/i.exec(disposition)?.[1]\n const plain = /filename=\"([^\"]+)\"/i.exec(disposition)?.[1]\n const fileName = utf8 ? decodeURIComponent(utf8) : (plain ?? 'markup.pdf')\n return { blob: data as Blob, fileName }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkBRFRQWAY_cjs = require('./chunk-BRFRQWAY.cjs');
|
|
4
4
|
var zustand = require('zustand');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var reactQuery = require('@tanstack/react-query');
|
|
@@ -17,10 +17,10 @@ function subscribeDocumentRows(listener) {
|
|
|
17
17
|
}
|
|
18
18
|
function getCachedDocuments(qc, workspaceId) {
|
|
19
19
|
if (!workspaceId) return void 0;
|
|
20
|
-
return qc.getQueryData(
|
|
20
|
+
return qc.getQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.documents(workspaceId));
|
|
21
21
|
}
|
|
22
22
|
function cachedLists(qc) {
|
|
23
|
-
return qc.getQueriesData({ queryKey:
|
|
23
|
+
return qc.getQueriesData({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.allDocuments() }).flatMap(
|
|
24
24
|
([key, data]) => typeof key[2] === "string" && Array.isArray(data) ? [[key[2], data]] : []
|
|
25
25
|
);
|
|
26
26
|
}
|
|
@@ -46,13 +46,13 @@ function patchDocuments(qc, reducer, workspaceId) {
|
|
|
46
46
|
for (const [id, before] of lists) {
|
|
47
47
|
const after = reducer(before);
|
|
48
48
|
if (after === before) continue;
|
|
49
|
-
qc.setQueryData(
|
|
49
|
+
qc.setQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.documents(id), after);
|
|
50
50
|
const change = diffRows(id, before, after);
|
|
51
51
|
const beforeById = new Map(before.map((doc) => [doc.external_id, doc]));
|
|
52
52
|
if (change.update.some(
|
|
53
53
|
(doc) => doc.current_version !== beforeById.get(doc.external_id)?.current_version
|
|
54
54
|
))
|
|
55
|
-
void qc.invalidateQueries({ queryKey:
|
|
55
|
+
void qc.invalidateQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.allDocumentVersions() });
|
|
56
56
|
if (change.add.length || change.update.length || change.remove.length)
|
|
57
57
|
for (const listener of rowListeners) listener(change);
|
|
58
58
|
}
|
|
@@ -80,11 +80,11 @@ function upsertDocuments(qc, documents, workspaceId) {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
function setCachedDocument(qc, doc) {
|
|
83
|
-
qc.setQueryData(
|
|
83
|
+
qc.setQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.document(doc.external_id), doc);
|
|
84
84
|
}
|
|
85
85
|
function patchCachedDocument(qc, docId, reducer) {
|
|
86
|
-
const current = qc.getQueryData(
|
|
87
|
-
if (current) qc.setQueryData(
|
|
86
|
+
const current = qc.getQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.document(docId));
|
|
87
|
+
if (current) qc.setQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.document(docId), reducer(current));
|
|
88
88
|
}
|
|
89
89
|
function dropTagFromCachedDocuments(qc, tagId) {
|
|
90
90
|
const strip = (doc) => {
|
|
@@ -101,9 +101,9 @@ function dropTagFromCachedDocuments(qc, tagId) {
|
|
|
101
101
|
}
|
|
102
102
|
function forgetDocuments(qc, docIds) {
|
|
103
103
|
for (const id of docIds) {
|
|
104
|
-
qc.removeQueries({ queryKey:
|
|
105
|
-
qc.removeQueries({ queryKey:
|
|
106
|
-
qc.removeQueries({ queryKey:
|
|
104
|
+
qc.removeQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.document(id) });
|
|
105
|
+
qc.removeQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.documentVersions(id) });
|
|
106
|
+
qc.removeQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.parsedDocument(id) });
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
var useEntityExtractionStore = zustand.create(() => ({ docIds: [] }));
|
|
@@ -173,7 +173,7 @@ function useCapturingWorkspace(mutation, capture) {
|
|
|
173
173
|
// src/tags.ts
|
|
174
174
|
function workspaceOfTag(qc, tagId) {
|
|
175
175
|
for (const [key, tags] of qc.getQueriesData({
|
|
176
|
-
queryKey:
|
|
176
|
+
queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.allTags()
|
|
177
177
|
})) {
|
|
178
178
|
if (Array.isArray(tags) && tags.some((t) => t.external_id === tagId))
|
|
179
179
|
return key[2] ?? null;
|
|
@@ -184,23 +184,23 @@ function openWorkspaceId(arbi) {
|
|
|
184
184
|
return arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
|
|
185
185
|
}
|
|
186
186
|
function patchWorkspaceTags(qc, workspaceId, reducer) {
|
|
187
|
-
const key =
|
|
187
|
+
const key = chunkBRFRQWAY_cjs.arbiQueryKeys.tags(workspaceId);
|
|
188
188
|
const current = qc.getQueryData(key);
|
|
189
189
|
if (!current) return;
|
|
190
190
|
const next = reducer(current);
|
|
191
191
|
if (next !== current) qc.setQueryData(key, next);
|
|
192
192
|
}
|
|
193
193
|
function invalidateTagTables(qc, workspaceId) {
|
|
194
|
-
return qc.invalidateQueries({ queryKey:
|
|
194
|
+
return qc.invalidateQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.tagLists(workspaceId) });
|
|
195
195
|
}
|
|
196
196
|
function invalidateTagData(qc, workspaceId) {
|
|
197
197
|
return Promise.all([
|
|
198
|
-
qc.invalidateQueries({ queryKey:
|
|
199
|
-
qc.invalidateQueries({ queryKey:
|
|
198
|
+
qc.invalidateQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.tags(workspaceId) }),
|
|
199
|
+
qc.invalidateQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.facts(workspaceId) })
|
|
200
200
|
]);
|
|
201
201
|
}
|
|
202
202
|
function useInvalidateTagData() {
|
|
203
|
-
const arbi =
|
|
203
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
204
204
|
const qc = reactQuery.useQueryClient();
|
|
205
205
|
return react.useCallback(() => {
|
|
206
206
|
const workspaceId = openWorkspaceId(arbi);
|
|
@@ -227,19 +227,19 @@ function settleChangedTag(qc, tag) {
|
|
|
227
227
|
}
|
|
228
228
|
var replayableTagMutations = [
|
|
229
229
|
{
|
|
230
|
-
mutationKey:
|
|
230
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.createTag(),
|
|
231
231
|
// In the workspace it was made in (named on the request), opened for this session first.
|
|
232
232
|
run: (client, input) => inWorkspace(primeOnClient(client), input.workspaceId, () => browser.tags.createTag(client, input)),
|
|
233
233
|
settle: (qc, created) => settleCreatedTag(qc, created)
|
|
234
234
|
}
|
|
235
235
|
];
|
|
236
236
|
function useCreateTag() {
|
|
237
|
-
const arbi =
|
|
237
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
238
238
|
const qc = reactQuery.useQueryClient();
|
|
239
239
|
const capture = (input) => input.workspaceId || !arbi.hasWorkspace ? input : { ...input, workspaceId: arbi.getWorkspaceId() };
|
|
240
240
|
return useCapturingWorkspace(
|
|
241
241
|
reactQuery.useMutation({
|
|
242
|
-
mutationKey:
|
|
242
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.createTag(),
|
|
243
243
|
mutationFn: (input) => inWorkspace(primeOnArbi(arbi), input.workspaceId, () => arbi.tags.create(input)),
|
|
244
244
|
onSuccess: (created) => settleCreatedTag(qc, created),
|
|
245
245
|
...QUEUED_WRITE_RETRY
|
|
@@ -253,7 +253,7 @@ function useIsCreatingTag() {
|
|
|
253
253
|
(name) => {
|
|
254
254
|
const wanted = name.trim().toLowerCase();
|
|
255
255
|
return qc.getMutationCache().findAll({
|
|
256
|
-
mutationKey:
|
|
256
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.createTag(),
|
|
257
257
|
predicate: (m) => m.state.status === "pending" && m.state.variables?.name.trim().toLowerCase() === wanted
|
|
258
258
|
}).length > 0;
|
|
259
259
|
},
|
|
@@ -261,19 +261,19 @@ function useIsCreatingTag() {
|
|
|
261
261
|
);
|
|
262
262
|
}
|
|
263
263
|
function useUpdateTag() {
|
|
264
|
-
const arbi =
|
|
264
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
265
265
|
const qc = reactQuery.useQueryClient();
|
|
266
266
|
return reactQuery.useMutation({
|
|
267
|
-
mutationKey:
|
|
267
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.updateTag(),
|
|
268
268
|
mutationFn: ({ tagId, change }) => arbi.tags.update(tagId, change),
|
|
269
269
|
onSuccess: (tag) => settleChangedTag(qc, tag)
|
|
270
270
|
});
|
|
271
271
|
}
|
|
272
272
|
function useSetTagValues() {
|
|
273
|
-
const arbi =
|
|
273
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
274
274
|
const qc = reactQuery.useQueryClient();
|
|
275
275
|
return reactQuery.useMutation({
|
|
276
|
-
mutationKey:
|
|
276
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.updateTag(),
|
|
277
277
|
mutationFn: ({
|
|
278
278
|
tagId,
|
|
279
279
|
values
|
|
@@ -282,10 +282,10 @@ function useSetTagValues() {
|
|
|
282
282
|
});
|
|
283
283
|
}
|
|
284
284
|
function useDeleteTag() {
|
|
285
|
-
const arbi =
|
|
285
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
286
286
|
const qc = reactQuery.useQueryClient();
|
|
287
287
|
return reactQuery.useMutation({
|
|
288
|
-
mutationKey:
|
|
288
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.deleteTag(),
|
|
289
289
|
mutationFn: (tagId) => arbi.tags.delete(tagId),
|
|
290
290
|
// The tag's own workspace (the cached list holding it), else the one open when it is sent: a
|
|
291
291
|
// switch while the delete runs must not patch the next workspace's list.
|
|
@@ -301,33 +301,33 @@ function useDeleteTag() {
|
|
|
301
301
|
);
|
|
302
302
|
return Promise.all([
|
|
303
303
|
invalidateTagTables(qc, workspaceId),
|
|
304
|
-
qc.invalidateQueries({ queryKey:
|
|
304
|
+
qc.invalidateQueries({ queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.facts(workspaceId) })
|
|
305
305
|
]);
|
|
306
306
|
}
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
309
|
function useExtractEntities() {
|
|
310
|
-
const arbi =
|
|
310
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
311
311
|
return reactQuery.useMutation({
|
|
312
|
-
mutationKey:
|
|
312
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.extractEntities(),
|
|
313
313
|
mutationFn: (docIds) => arbi.tags.extractEntities(docIds),
|
|
314
314
|
onSuccess: (data) => startEntityExtraction(data.doc_ext_ids)
|
|
315
315
|
});
|
|
316
316
|
}
|
|
317
317
|
function useTagKindSchema(kind, options) {
|
|
318
|
-
const arbi =
|
|
318
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
319
319
|
const workspaceId = openWorkspaceId(arbi) ?? "";
|
|
320
320
|
return reactQuery.useQuery({
|
|
321
|
-
queryKey:
|
|
321
|
+
queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.tagKind(workspaceId, kind ?? ""),
|
|
322
322
|
queryFn: () => arbi.readInWorkspace(workspaceId, () => arbi.tagKinds.get(kind)),
|
|
323
323
|
enabled: (options?.enabled ?? true) && !!kind && !!workspaceId
|
|
324
324
|
});
|
|
325
325
|
}
|
|
326
326
|
function useUpdateTagKindSchema() {
|
|
327
|
-
const arbi =
|
|
327
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
328
328
|
const qc = reactQuery.useQueryClient();
|
|
329
329
|
return reactQuery.useMutation({
|
|
330
|
-
mutationKey:
|
|
330
|
+
mutationKey: chunkBRFRQWAY_cjs.arbiMutationKeys.updateTagKindSchema(),
|
|
331
331
|
mutationFn: ({
|
|
332
332
|
kind,
|
|
333
333
|
fields
|
|
@@ -338,7 +338,7 @@ function useUpdateTagKindSchema() {
|
|
|
338
338
|
onSuccess: (schema, _input, context) => {
|
|
339
339
|
const workspaceId = context?.workspaceId;
|
|
340
340
|
if (!workspaceId) return;
|
|
341
|
-
qc.setQueryData(
|
|
341
|
+
qc.setQueryData(chunkBRFRQWAY_cjs.arbiQueryKeys.tagKind(workspaceId, schema.kind), schema);
|
|
342
342
|
return invalidateTagData(qc, workspaceId);
|
|
343
343
|
}
|
|
344
344
|
});
|
|
@@ -541,11 +541,11 @@ function openWorkspaceId2(arbi) {
|
|
|
541
541
|
return arbi.hasWorkspace ? arbi.getWorkspaceId() : null;
|
|
542
542
|
}
|
|
543
543
|
function useDocuments(workspaceId, options) {
|
|
544
|
-
const arbi =
|
|
544
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
545
545
|
const qc = reactQuery.useQueryClient();
|
|
546
546
|
const workspace = workspaceId ?? openWorkspaceId2(arbi) ?? "";
|
|
547
547
|
return reactQuery.useQuery({
|
|
548
|
-
queryKey:
|
|
548
|
+
queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.documents(workspace),
|
|
549
549
|
queryFn: ({ signal }) => {
|
|
550
550
|
if (openWorkspaceId2(arbi) !== workspace)
|
|
551
551
|
return Promise.reject(new Error("The selected workspace changed."));
|
|
@@ -563,9 +563,9 @@ function processingInterval(doc) {
|
|
|
563
563
|
return doc?.status && !FINISHED_DOCUMENT_STATUSES.has(doc.status) ? DOCUMENT_STATUS_POLL_MS : false;
|
|
564
564
|
}
|
|
565
565
|
function useDocument(docId, options) {
|
|
566
|
-
const arbi =
|
|
566
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
567
567
|
return reactQuery.useQuery({
|
|
568
|
-
queryKey:
|
|
568
|
+
queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.document(docId ?? ""),
|
|
569
569
|
queryFn: async () => (await arbi.documents.get([docId]))[0] ?? null,
|
|
570
570
|
enabled: (options?.enabled ?? true) && !!docId && arbi.isLoggedIn,
|
|
571
571
|
refetchInterval: options?.pollWhileProcessing ? (query) => processingInterval(query.state.data) : false
|
|
@@ -573,10 +573,10 @@ function useDocument(docId, options) {
|
|
|
573
573
|
}
|
|
574
574
|
var SIMILARITY_THRESHOLD = 0.98;
|
|
575
575
|
function useSimilarDocuments(options) {
|
|
576
|
-
const arbi =
|
|
576
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
577
577
|
const workspace = openWorkspaceId2(arbi) ?? "";
|
|
578
578
|
return reactQuery.useQuery({
|
|
579
|
-
queryKey:
|
|
579
|
+
queryKey: chunkBRFRQWAY_cjs.arbiQueryKeys.similarDocuments(workspace, SIMILARITY_THRESHOLD),
|
|
580
580
|
queryFn: () => arbi.readInWorkspace(
|
|
581
581
|
workspace,
|
|
582
582
|
() => arbi.documents.similar({ threshold: SIMILARITY_THRESHOLD })
|
|
@@ -610,7 +610,7 @@ async function refreshDocuments(qc, arbi, docIds) {
|
|
|
610
610
|
}
|
|
611
611
|
function useRefreshDocuments() {
|
|
612
612
|
const qc = reactQuery.useQueryClient();
|
|
613
|
-
const arbi =
|
|
613
|
+
const arbi = chunkBRFRQWAY_cjs.useArbi();
|
|
614
614
|
return react.useCallback((docIds) => refreshDocuments(qc, arbi, docIds), [qc, arbi]);
|
|
615
615
|
}
|
|
616
616
|
function reconcileTagCounts(qc, fresh) {
|
|
@@ -694,5 +694,5 @@ exports.useSimilarDocuments = useSimilarDocuments;
|
|
|
694
694
|
exports.useTagKindSchema = useTagKindSchema;
|
|
695
695
|
exports.useUpdateTag = useUpdateTag;
|
|
696
696
|
exports.useUpdateTagKindSchema = useUpdateTagKindSchema;
|
|
697
|
-
//# sourceMappingURL=chunk-
|
|
698
|
-
//# sourceMappingURL=chunk-
|
|
697
|
+
//# sourceMappingURL=chunk-NR6PUE5O.cjs.map
|
|
698
|
+
//# sourceMappingURL=chunk-NR6PUE5O.cjs.map
|