dsh-figmark 1.2.1 → 1.2.2
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/CHANGELOG.md +33 -0
- package/PUBLISHING.md +2 -0
- package/README.md +59 -10
- package/lib/client.js +10576 -3632
- package/lib/client.pdf.js +157 -79
- package/lib/index.js +1398 -48
- package/market/index.json +12 -4
- package/package.json +7 -2
package/lib/client.pdf.js
CHANGED
|
@@ -1189,6 +1189,9 @@ window.__ModuleLoader__.load({
|
|
|
1189
1189
|
cancel: (0, react.useCallback)(() => {
|
|
1190
1190
|
autosave.cancel();
|
|
1191
1191
|
}, [autosave]),
|
|
1192
|
+
drained: (0, react.useCallback)(async () => {
|
|
1193
|
+
await autosave.drained();
|
|
1194
|
+
}, [autosave]),
|
|
1192
1195
|
markWritten: (0, react.useCallback)((input) => {
|
|
1193
1196
|
writtenSignature.current = signature(input);
|
|
1194
1197
|
}, [signature]),
|
|
@@ -25086,20 +25089,21 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
25086
25089
|
return ordinals(allMarks(marks));
|
|
25087
25090
|
}
|
|
25088
25091
|
/**
|
|
25089
|
-
* Drop
|
|
25092
|
+
* Drop several marks from wherever in the document they were drawn.
|
|
25090
25093
|
*
|
|
25091
|
-
*
|
|
25092
|
-
*
|
|
25094
|
+
* A hand-off removes exactly the marks it carried. Doing that by repeatedly dropping
|
|
25095
|
+
* one mark would visit every page once per delivered mark, which matters on a large
|
|
25096
|
+
* document; this keeps it to one visit per page.
|
|
25093
25097
|
*
|
|
25094
25098
|
* @param marks - every page's marks.
|
|
25095
|
-
* @param
|
|
25096
|
-
* @returns the new map, or the same one when no page carried
|
|
25099
|
+
* @param ids - the marks that were delivered.
|
|
25100
|
+
* @returns the new map, or the same one when no page carried any of them.
|
|
25097
25101
|
*/
|
|
25098
|
-
function
|
|
25102
|
+
function withoutMarks(marks, ids) {
|
|
25099
25103
|
let changed = false;
|
|
25100
25104
|
const next = new Map(marks);
|
|
25101
25105
|
for (const [page, pageMarks] of marks) {
|
|
25102
|
-
const kept = pageMarks.filter((mark) => mark.id
|
|
25106
|
+
const kept = pageMarks.filter((mark) => !ids.has(mark.id));
|
|
25103
25107
|
if (kept.length !== pageMarks.length) {
|
|
25104
25108
|
changed = true;
|
|
25105
25109
|
next.set(page, kept);
|
|
@@ -25167,6 +25171,7 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
25167
25171
|
*/
|
|
25168
25172
|
async function discardDocument(context) {
|
|
25169
25173
|
context.autosave.cancel();
|
|
25174
|
+
await context.autosave.drained();
|
|
25170
25175
|
context.autosave.forget();
|
|
25171
25176
|
try {
|
|
25172
25177
|
await context.seat.discard(context.address);
|
|
@@ -25185,60 +25190,98 @@ fn fs_main(in : VertexOutput) -> @location(0) vec4<f32> {
|
|
|
25185
25190
|
* which they cannot see from the pill they pressed.
|
|
25186
25191
|
*
|
|
25187
25192
|
* @param context - the document being saved.
|
|
25188
|
-
* @param target - who receives the annotation.
|
|
25189
25193
|
* @param only - the single mark being sent, or undefined to send the document.
|
|
25194
|
+
* @returns the ready snapshot, or why there is none.
|
|
25190
25195
|
*/
|
|
25191
|
-
|
|
25196
|
+
function prepareDelivery(context, only) {
|
|
25192
25197
|
const collected = context.collect();
|
|
25193
|
-
if (collected === null) {
|
|
25194
|
-
context.fail(context.copy.notReady);
|
|
25195
|
-
return;
|
|
25196
|
-
}
|
|
25198
|
+
if (collected === null) return { kind: "not-ready" };
|
|
25197
25199
|
const input = only === void 0 ? collected : {
|
|
25198
25200
|
...collected,
|
|
25199
25201
|
marks: collected.marks.filter((mark) => mark.id === only.id)
|
|
25200
25202
|
};
|
|
25201
|
-
|
|
25202
|
-
if (input.marks.length === 0) {
|
|
25203
|
-
context.fail(context.copy.nothingToSend);
|
|
25204
|
-
return;
|
|
25205
|
-
}
|
|
25203
|
+
if (input.marks.length === 0) return { kind: "nothing" };
|
|
25206
25204
|
/* v8 ignore start -- a collected document always carries both, for the reason above. */
|
|
25207
|
-
|
|
25208
|
-
|
|
25209
|
-
return;
|
|
25210
|
-
}
|
|
25205
|
+
const { pdf, bytes } = context;
|
|
25206
|
+
if (pdf === null || bytes === void 0) return { kind: "not-ready" };
|
|
25211
25207
|
/* v8 ignore stop */
|
|
25212
|
-
|
|
25213
|
-
|
|
25214
|
-
|
|
25215
|
-
|
|
25216
|
-
|
|
25217
|
-
|
|
25218
|
-
|
|
25219
|
-
context.autosave.markWritten(input);
|
|
25220
|
-
context.setCreatedAt(input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString());
|
|
25221
|
-
context.setStale(false);
|
|
25222
|
-
const pageImages = await context.review(pdf, pages);
|
|
25223
|
-
if (target === "composer") {
|
|
25224
|
-
await context.seat.compose(input, saved, pageImages, annotatedPdf);
|
|
25225
|
-
context.say(only === void 0 ? context.copy.composed : context.copy.composedOne);
|
|
25226
|
-
} else {
|
|
25227
|
-
const warnings = await context.seat.send(input, saved, pageImages, annotatedPdf);
|
|
25228
|
-
const delivered = only === void 0 ? context.copy.sent : context.copy.sentOne;
|
|
25229
|
-
context.say(`${delivered}${warnings.length === 0 ? "" : ` ${warnings.join(" ")}`}`);
|
|
25208
|
+
return {
|
|
25209
|
+
kind: "ready",
|
|
25210
|
+
value: {
|
|
25211
|
+
input,
|
|
25212
|
+
whole: only === void 0,
|
|
25213
|
+
pdf,
|
|
25214
|
+
bytes
|
|
25230
25215
|
}
|
|
25231
|
-
|
|
25232
|
-
|
|
25233
|
-
|
|
25216
|
+
};
|
|
25217
|
+
}
|
|
25218
|
+
/**
|
|
25219
|
+
* Write and hand off one prepared snapshot.
|
|
25220
|
+
*
|
|
25221
|
+
* Failures are thrown rather than painted here: the caller owns the send card, and
|
|
25222
|
+
* that card can only show its retry button when the same task rejects.
|
|
25223
|
+
*/
|
|
25224
|
+
async function saveAndDeliver(context, target, prepared) {
|
|
25225
|
+
context.setBusy(true);
|
|
25226
|
+
const outcome = await writePrepared(context, target, prepared).then((value) => ({
|
|
25227
|
+
ok: true,
|
|
25228
|
+
value
|
|
25229
|
+
}), (cause) => ({
|
|
25230
|
+
ok: false,
|
|
25231
|
+
cause
|
|
25232
|
+
}));
|
|
25233
|
+
context.setBusy(false);
|
|
25234
|
+
if (!outcome.ok) throw new Error(`${context.copy.saveFailed}${messageOf(outcome.cause)}`);
|
|
25235
|
+
return outcome.value;
|
|
25236
|
+
}
|
|
25237
|
+
/**
|
|
25238
|
+
* Write one prepared snapshot and update the document afterwards.
|
|
25239
|
+
*
|
|
25240
|
+
* Kept apart from the busy flag so a rejection has one unwind point: the
|
|
25241
|
+
* public function turns the promise into either its warnings or the sentence
|
|
25242
|
+
* the retryable toast card shows.
|
|
25243
|
+
*/
|
|
25244
|
+
async function writePrepared(context, target, prepared) {
|
|
25245
|
+
const { input, whole, pdf, bytes } = prepared;
|
|
25246
|
+
const pages = markedPages(groupByPage(input.marks));
|
|
25247
|
+
const annotatedPdf = await context.annotate(bytes, pdf, pages, context.figureUnit);
|
|
25248
|
+
const saved = await context.seat.save(context.address, input, annotatedPdf);
|
|
25249
|
+
context.autosave.cancel();
|
|
25250
|
+
context.autosave.markWritten(input);
|
|
25251
|
+
context.setCreatedAt(input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString());
|
|
25252
|
+
context.setStale(false);
|
|
25253
|
+
const pageImages = await context.review(pdf, pages);
|
|
25254
|
+
if (target === "composer") await context.seat.compose(input, saved, pageImages);
|
|
25255
|
+
else {
|
|
25256
|
+
const warnings = await context.seat.send(input, saved, pageImages);
|
|
25257
|
+
if (whole) {
|
|
25258
|
+
const sentIds = new Set(input.marks.map((mark) => mark.id));
|
|
25259
|
+
const sentSummary = input.summary;
|
|
25260
|
+
context.autosave.cancel();
|
|
25261
|
+
await context.autosave.drained();
|
|
25262
|
+
try {
|
|
25263
|
+
await context.seat.discard(context.address);
|
|
25264
|
+
} catch (cause) {
|
|
25265
|
+
context.fail(`${context.copy.clearFailed}${messageOf(cause)}`);
|
|
25266
|
+
}
|
|
25267
|
+
context.delivered(sentIds, sentSummary, true);
|
|
25268
|
+
return warnings;
|
|
25234
25269
|
}
|
|
25235
|
-
context.autosave.
|
|
25236
|
-
context.
|
|
25270
|
+
context.autosave.cancel();
|
|
25271
|
+
await context.autosave.drained();
|
|
25272
|
+
context.delivered(new Set(input.marks.map((mark) => mark.id)), input.summary, false);
|
|
25273
|
+
return warnings;
|
|
25274
|
+
}
|
|
25275
|
+
const ids = new Set(input.marks.map((mark) => mark.id));
|
|
25276
|
+
context.autosave.cancel();
|
|
25277
|
+
await context.autosave.drained();
|
|
25278
|
+
if (whole) try {
|
|
25279
|
+
await context.seat.discard(context.address);
|
|
25237
25280
|
} catch (cause) {
|
|
25238
|
-
context.fail(`${context.copy.
|
|
25239
|
-
} finally {
|
|
25240
|
-
context.setBusy(false);
|
|
25281
|
+
context.fail(`${context.copy.clearFailed}${messageOf(cause)}`);
|
|
25241
25282
|
}
|
|
25283
|
+
context.delivered(ids, input.summary, whole);
|
|
25284
|
+
return [];
|
|
25242
25285
|
}
|
|
25243
25286
|
//#endregion
|
|
25244
25287
|
//#region node_modules/.pnpm/tslib@1.14.1/node_modules/tslib/tslib.es6.js
|
|
@@ -50953,7 +50996,8 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
50953
50996
|
* @returns the document's toolbar and the page on screen, or why it is not there yet.
|
|
50954
50997
|
*/
|
|
50955
50998
|
function PdfBody(props) {
|
|
50956
|
-
const { AnnotatorBody, seat, t } = props;
|
|
50999
|
+
const { AnnotatorBody, seat, t, toasts, ToastStack } = props;
|
|
51000
|
+
const { note, notify } = toasts;
|
|
50957
51001
|
const address = props.resourceAddress ?? "";
|
|
50958
51002
|
const { createAutosave, annotationSignature, autosaveDelayMs, figureUnit, markOrdinals } = props;
|
|
50959
51003
|
const bytes = props.content?.kind === "bytes" ? props.content.data : void 0;
|
|
@@ -50999,7 +51043,23 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
50999
51043
|
*/
|
|
51000
51044
|
const [zoom, setZoom] = (0, react.useState)("fit");
|
|
51001
51045
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
51002
|
-
|
|
51046
|
+
/**
|
|
51047
|
+
* The latest values a late delivery callback has to see.
|
|
51048
|
+
*
|
|
51049
|
+
* A send closes over the context that started it. Marks and notes added while the
|
|
51050
|
+
* session answers render into newer contexts; keeping the current values in a ref
|
|
51051
|
+
* lets the first context remove only its own snapshot without losing the newer work.
|
|
51052
|
+
*/
|
|
51053
|
+
const latest = (0, react.useRef)({
|
|
51054
|
+
marks,
|
|
51055
|
+
summary,
|
|
51056
|
+
createdAt
|
|
51057
|
+
});
|
|
51058
|
+
latest.current = {
|
|
51059
|
+
marks,
|
|
51060
|
+
summary,
|
|
51061
|
+
createdAt
|
|
51062
|
+
};
|
|
51003
51063
|
const zoomFactor = zoom === "fit" ? 1 : zoom;
|
|
51004
51064
|
const renderWidth = renderWidthFor(pane.width, zoomFactor);
|
|
51005
51065
|
/**
|
|
@@ -51021,11 +51081,11 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
51021
51081
|
setCreatedAt(saved.createdAt);
|
|
51022
51082
|
}, []),
|
|
51023
51083
|
fail: (0, react.useCallback)((cause) => {
|
|
51024
|
-
|
|
51084
|
+
note({
|
|
51025
51085
|
tone: "error",
|
|
51026
51086
|
text: `${translateRef.current("readError")}${messageOf(cause)}`
|
|
51027
51087
|
});
|
|
51028
|
-
}, [])
|
|
51088
|
+
}, [note])
|
|
51029
51089
|
});
|
|
51030
51090
|
(0, react.useEffect)(() => {
|
|
51031
51091
|
if (pdf === null || renderWidth < 120) return;
|
|
@@ -51075,6 +51135,7 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
51075
51135
|
const revealMark = (0, react.useCallback)((mark) => {
|
|
51076
51136
|
setSelectedId(mark.id);
|
|
51077
51137
|
if (mark.page !== void 0) paging.goTo(mark.page);
|
|
51138
|
+
setOpenPanel(null);
|
|
51078
51139
|
}, [paging]);
|
|
51079
51140
|
/** Everything one save persists, or null while the document is still unknown. */
|
|
51080
51141
|
const collect = (0, react.useCallback)(() => collectInput(figure, pageCount, address, marks, summary, createdAt), [
|
|
@@ -51103,35 +51164,23 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
51103
51164
|
annotationSignature,
|
|
51104
51165
|
autosaveDelayMs,
|
|
51105
51166
|
onError: (0, react.useCallback)((cause) => {
|
|
51106
|
-
|
|
51167
|
+
note({
|
|
51107
51168
|
tone: "error",
|
|
51108
51169
|
text: `${translateRef.current("saveError")}${messageOf(cause)}`
|
|
51109
51170
|
});
|
|
51110
|
-
}, [])
|
|
51171
|
+
}, [note])
|
|
51111
51172
|
}),
|
|
51112
|
-
say: (0, react.useCallback)((text) => {
|
|
51113
|
-
setStatus({
|
|
51114
|
-
tone: "info",
|
|
51115
|
-
text
|
|
51116
|
-
});
|
|
51117
|
-
}, []),
|
|
51118
51173
|
fail: (0, react.useCallback)((text) => {
|
|
51119
|
-
|
|
51174
|
+
note({
|
|
51120
51175
|
tone: "error",
|
|
51121
51176
|
text
|
|
51122
51177
|
});
|
|
51123
|
-
}, []),
|
|
51178
|
+
}, [note]),
|
|
51124
51179
|
setBusy,
|
|
51125
51180
|
copy: {
|
|
51126
51181
|
saveFailed: t("saveError"),
|
|
51127
51182
|
notReady: t("notReady"),
|
|
51128
51183
|
nothingToSend: t("sendNothingToSend"),
|
|
51129
|
-
sending: t("sending"),
|
|
51130
|
-
composing: t("composing"),
|
|
51131
|
-
composed: t("composed"),
|
|
51132
|
-
composedOne: t("composedOne"),
|
|
51133
|
-
sent: t("sent"),
|
|
51134
|
-
sentOne: t("sentOne"),
|
|
51135
51184
|
clearFailed: t("clearError")
|
|
51136
51185
|
},
|
|
51137
51186
|
cleared: (0, react.useCallback)(() => {
|
|
@@ -51141,20 +51190,49 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
51141
51190
|
setStale(false);
|
|
51142
51191
|
setGeneration((current) => current + 1);
|
|
51143
51192
|
}, []),
|
|
51144
|
-
|
|
51145
|
-
|
|
51193
|
+
delivered: (0, react.useCallback)((ids, sentSummary, summaryDelivered) => {
|
|
51194
|
+
const current = latest.current;
|
|
51195
|
+
const next = withoutMarks(current.marks, ids);
|
|
51196
|
+
const keptSummary = summaryDelivered && current.summary === sentSummary ? "" : current.summary;
|
|
51197
|
+
const remains = allMarks(next).length > 0 || keptSummary.trim() !== "";
|
|
51198
|
+
setMarks(next);
|
|
51199
|
+
setSummary(keptSummary);
|
|
51200
|
+
setCreatedAt(remains ? current.createdAt : null);
|
|
51201
|
+
setGeneration((current) => current + 1);
|
|
51146
51202
|
}, []),
|
|
51147
51203
|
setCreatedAt,
|
|
51148
51204
|
setStale
|
|
51149
51205
|
};
|
|
51150
51206
|
const contextRef = (0, react.useRef)(saveContext);
|
|
51151
51207
|
contextRef.current = saveContext;
|
|
51152
|
-
const run = (0, react.useCallback)((target) => {
|
|
51153
|
-
|
|
51154
|
-
|
|
51208
|
+
const run = (0, react.useCallback)((target, only) => {
|
|
51209
|
+
const context = contextRef.current;
|
|
51210
|
+
const prepared = prepareDelivery(context, only);
|
|
51211
|
+
if (prepared.kind === "not-ready") {
|
|
51212
|
+
note({
|
|
51213
|
+
tone: "info",
|
|
51214
|
+
text: context.copy.notReady
|
|
51215
|
+
});
|
|
51216
|
+
return;
|
|
51217
|
+
}
|
|
51218
|
+
if (prepared.kind === "nothing") {
|
|
51219
|
+
notify("annotate.none");
|
|
51220
|
+
return;
|
|
51221
|
+
}
|
|
51222
|
+
const event = target === "agent" ? "annotate.send.agent" : only === void 0 ? "annotate.save.all" : "annotate.save.one";
|
|
51223
|
+
let warnings = [];
|
|
51224
|
+
notify(event, async () => {
|
|
51225
|
+
warnings = await saveAndDeliver(context, target, prepared.value);
|
|
51226
|
+
}).then((outcome) => {
|
|
51227
|
+
if (outcome === "ok" && warnings.length > 0) note({
|
|
51228
|
+
tone: "info",
|
|
51229
|
+
text: warnings.join(" ")
|
|
51230
|
+
});
|
|
51231
|
+
});
|
|
51232
|
+
}, [note, notify]);
|
|
51155
51233
|
const runOne = (0, react.useCallback)((mark, target) => {
|
|
51156
|
-
|
|
51157
|
-
}, []);
|
|
51234
|
+
run(target, mark);
|
|
51235
|
+
}, [run]);
|
|
51158
51236
|
const clearDocument = (0, react.useCallback)(() => {
|
|
51159
51237
|
discardDocument(contextRef.current);
|
|
51160
51238
|
}, []);
|
|
@@ -51210,10 +51288,10 @@ while (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan] &
|
|
|
51210
51288
|
"data-tone": "error",
|
|
51211
51289
|
children: t("stale")
|
|
51212
51290
|
}) : null,
|
|
51213
|
-
|
|
51214
|
-
|
|
51215
|
-
|
|
51216
|
-
|
|
51291
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToastStack, {
|
|
51292
|
+
view: toasts,
|
|
51293
|
+
label: t("close"),
|
|
51294
|
+
resendLabel: t("toastResend")
|
|
51217
51295
|
}),
|
|
51218
51296
|
error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
51219
51297
|
className: "da-hint",
|