@brass-build/client 0.4.1 → 0.5.0
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/AGENTS.md +124 -45
- package/CHANGELOG.md +80 -4
- package/README.md +666 -179
- package/dist/api-fetch.d.ts +8 -0
- package/dist/api-fetch.d.ts.map +1 -1
- package/dist/api-fetch.js +35 -8
- package/dist/api-fetch.js.map +1 -1
- package/dist/batched-get.d.ts +11 -0
- package/dist/batched-get.d.ts.map +1 -0
- package/dist/batched-get.js +92 -0
- package/dist/batched-get.js.map +1 -0
- package/dist/call-service.d.ts +4 -0
- package/dist/call-service.d.ts.map +1 -1
- package/dist/call-service.js +66 -3
- package/dist/call-service.js.map +1 -1
- package/dist/client.d.ts +48 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +918 -115
- package/dist/client.js.map +1 -1
- package/dist/document-checkpoints.d.ts +25 -2
- package/dist/document-checkpoints.d.ts.map +1 -1
- package/dist/document-checkpoints.js +258 -61
- package/dist/document-checkpoints.js.map +1 -1
- package/dist/document-commands.d.ts.map +1 -1
- package/dist/document-commands.js +5 -3
- package/dist/document-commands.js.map +1 -1
- package/dist/document-contents.d.ts +10 -0
- package/dist/document-contents.d.ts.map +1 -1
- package/dist/document-contents.js +23 -1
- package/dist/document-contents.js.map +1 -1
- package/dist/document-set-subscription.d.ts +56 -0
- package/dist/document-set-subscription.d.ts.map +1 -0
- package/dist/document-set-subscription.js +240 -0
- package/dist/document-set-subscription.js.map +1 -0
- package/dist/document-signals.d.ts +6 -0
- package/dist/document-signals.d.ts.map +1 -1
- package/dist/document-signals.js +31 -1
- package/dist/document-signals.js.map +1 -1
- package/dist/document-streams.d.ts +36 -2
- package/dist/document-streams.d.ts.map +1 -1
- package/dist/document-streams.js +69 -18
- package/dist/document-streams.js.map +1 -1
- package/dist/document-thumbnail-capture.d.ts +12 -2
- package/dist/document-thumbnail-capture.d.ts.map +1 -1
- package/dist/document-thumbnail-capture.js +103 -27
- package/dist/document-thumbnail-capture.js.map +1 -1
- package/dist/documents-namespace.d.ts +92 -10
- package/dist/documents-namespace.d.ts.map +1 -1
- package/dist/documents-namespace.js +285 -39
- package/dist/documents-namespace.js.map +1 -1
- package/dist/documents.d.ts +173 -8
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +1778 -310
- package/dist/documents.js.map +1 -1
- package/dist/errors.d.ts +3 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fetch-retry.d.ts +1 -0
- package/dist/fetch-retry.d.ts.map +1 -1
- package/dist/fetch-retry.js +2 -0
- package/dist/fetch-retry.js.map +1 -1
- package/dist/file-choice.d.ts +2 -0
- package/dist/file-choice.d.ts.map +1 -0
- package/dist/file-choice.js +27 -0
- package/dist/file-choice.js.map +1 -0
- package/dist/guest-link.d.ts +18 -1
- package/dist/guest-link.d.ts.map +1 -1
- package/dist/guest-link.js +329 -1
- package/dist/guest-link.js.map +1 -1
- package/dist/handle-types.d.ts +67 -5
- package/dist/handle-types.d.ts.map +1 -1
- package/dist/handles.d.ts +15 -19
- package/dist/handles.d.ts.map +1 -1
- package/dist/handles.js +231 -76
- package/dist/handles.js.map +1 -1
- package/dist/hosted-ui.d.ts +61 -0
- package/dist/hosted-ui.d.ts.map +1 -1
- package/dist/hosted-ui.js +94 -42
- package/dist/hosted-ui.js.map +1 -1
- package/dist/import-contract.d.ts +74 -0
- package/dist/import-contract.d.ts.map +1 -0
- package/dist/import-contract.js +163 -0
- package/dist/import-contract.js.map +1 -0
- package/dist/import-guest.d.ts +9 -0
- package/dist/import-guest.d.ts.map +1 -0
- package/dist/import-guest.js +155 -0
- package/dist/import-guest.js.map +1 -0
- package/dist/import-report.d.ts +17 -0
- package/dist/import-report.d.ts.map +1 -0
- package/dist/import-report.js +7 -0
- package/dist/import-report.js.map +1 -0
- package/dist/importer-wait.d.ts +2 -0
- package/dist/importer-wait.d.ts.map +1 -0
- package/dist/importer-wait.js +5 -0
- package/dist/importer-wait.js.map +1 -0
- package/dist/importer.d.ts +18 -4
- package/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +322 -105
- package/dist/importer.js.map +1 -1
- package/dist/in-development.d.ts +2 -0
- package/dist/in-development.d.ts.map +1 -0
- package/dist/in-development.js +10 -0
- package/dist/in-development.js.map +1 -0
- package/dist/index.d.ts +16 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -8
- package/dist/index.js.map +1 -1
- package/dist/init-keys.d.ts +1 -1
- package/dist/init-keys.d.ts.map +1 -1
- package/dist/init-keys.js +6 -1
- package/dist/init-keys.js.map +1 -1
- package/dist/input-documents.d.ts +67 -0
- package/dist/input-documents.d.ts.map +1 -0
- package/dist/input-documents.js +693 -0
- package/dist/input-documents.js.map +1 -0
- package/dist/inputs-status.d.ts +80 -0
- package/dist/inputs-status.d.ts.map +1 -0
- package/dist/inputs-status.js +460 -0
- package/dist/inputs-status.js.map +1 -0
- package/dist/inputs.d.ts +2 -0
- package/dist/inputs.d.ts.map +1 -0
- package/dist/inputs.js +793 -0
- package/dist/inputs.js.map +1 -0
- package/dist/internal.d.ts +6 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -1
- package/dist/internal.js.map +1 -1
- package/dist/join-content.d.ts +33 -0
- package/dist/join-content.d.ts.map +1 -0
- package/dist/join-content.js +114 -0
- package/dist/join-content.js.map +1 -0
- package/dist/join-stamp.d.ts +3 -0
- package/dist/join-stamp.d.ts.map +1 -0
- package/dist/join-stamp.js +12 -0
- package/dist/join-stamp.js.map +1 -0
- package/dist/manifest-drift.d.ts +9 -0
- package/dist/manifest-drift.d.ts.map +1 -0
- package/dist/manifest-drift.js +46 -0
- package/dist/manifest-drift.js.map +1 -0
- package/dist/open-document.d.ts +109 -2
- package/dist/open-document.d.ts.map +1 -1
- package/dist/open-document.js +1822 -811
- package/dist/open-document.js.map +1 -1
- package/dist/page-restore.d.ts +12 -0
- package/dist/page-restore.d.ts.map +1 -0
- package/dist/page-restore.js +23 -0
- package/dist/page-restore.js.map +1 -0
- package/dist/placement.d.ts +13 -0
- package/dist/placement.d.ts.map +1 -0
- package/dist/placement.js +34 -0
- package/dist/placement.js.map +1 -0
- package/dist/presence.d.ts +1 -0
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +16 -4
- package/dist/presence.js.map +1 -1
- package/dist/read-only-document.d.ts +87 -0
- package/dist/read-only-document.d.ts.map +1 -0
- package/dist/read-only-document.js +4 -0
- package/dist/read-only-document.js.map +1 -0
- package/dist/record-paging.d.ts +63 -6
- package/dist/record-paging.d.ts.map +1 -1
- package/dist/record-paging.js +122 -29
- package/dist/record-paging.js.map +1 -1
- package/dist/references.d.ts +40 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +135 -0
- package/dist/references.js.map +1 -0
- package/dist/request-lane.d.ts +5 -0
- package/dist/request-lane.d.ts.map +1 -0
- package/dist/request-lane.js +48 -0
- package/dist/request-lane.js.map +1 -0
- package/dist/sealed-arrow.d.ts +170 -0
- package/dist/sealed-arrow.d.ts.map +1 -0
- package/dist/sealed-arrow.js +769 -0
- package/dist/sealed-arrow.js.map +1 -0
- package/dist/sealed-cache.d.ts +21 -0
- package/dist/sealed-cache.d.ts.map +1 -0
- package/dist/sealed-cache.js +247 -0
- package/dist/sealed-cache.js.map +1 -0
- package/dist/sealed-encode.d.ts +87 -0
- package/dist/sealed-encode.d.ts.map +1 -0
- package/dist/sealed-encode.js +876 -0
- package/dist/sealed-encode.js.map +1 -0
- package/dist/sealed-handles.d.ts +45 -0
- package/dist/sealed-handles.d.ts.map +1 -0
- package/dist/sealed-handles.js +408 -0
- package/dist/sealed-handles.js.map +1 -0
- package/dist/sealed-store.d.ts +242 -0
- package/dist/sealed-store.d.ts.map +1 -0
- package/dist/sealed-store.js +1155 -0
- package/dist/sealed-store.js.map +1 -0
- package/dist/serializer.d.ts +6 -15
- package/dist/serializer.d.ts.map +1 -1
- package/dist/session-toolbar.d.ts +20 -5
- package/dist/session-toolbar.d.ts.map +1 -1
- package/dist/session-toolbar.js +419 -67
- package/dist/session-toolbar.js.map +1 -1
- package/dist/session.d.ts +38 -1
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +562 -79
- package/dist/session.js.map +1 -1
- package/dist/sha256.d.ts +3 -0
- package/dist/sha256.d.ts.map +1 -0
- package/dist/sha256.js +74 -0
- package/dist/sha256.js.map +1 -0
- package/dist/stable-handles.d.ts +19 -0
- package/dist/stable-handles.d.ts.map +1 -0
- package/dist/stable-handles.js +193 -0
- package/dist/stable-handles.js.map +1 -0
- package/dist/staged-seal.d.ts +2 -0
- package/dist/staged-seal.d.ts.map +1 -0
- package/dist/staged-seal.js +76 -0
- package/dist/staged-seal.js.map +1 -0
- package/dist/subscriber-delivery.d.ts +8 -0
- package/dist/subscriber-delivery.d.ts.map +1 -0
- package/dist/subscriber-delivery.js +31 -0
- package/dist/subscriber-delivery.js.map +1 -0
- package/dist/tail-op-import.d.ts +10 -0
- package/dist/tail-op-import.d.ts.map +1 -0
- package/dist/tail-op-import.js +33 -0
- package/dist/tail-op-import.js.map +1 -0
- package/dist/topic-lifecycle.d.ts +6 -0
- package/dist/topic-lifecycle.d.ts.map +1 -1
- package/dist/topic-lifecycle.js +32 -2
- package/dist/topic-lifecycle.js.map +1 -1
- package/dist/trial-replace-dialog.d.ts +10 -0
- package/dist/trial-replace-dialog.d.ts.map +1 -0
- package/dist/trial-replace-dialog.js +153 -0
- package/dist/trial-replace-dialog.js.map +1 -0
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/undo.d.ts +60 -5
- package/dist/undo.d.ts.map +1 -1
- package/dist/undo.js +344 -75
- package/dist/undo.js.map +1 -1
- package/dist/version-bar.d.ts +1 -0
- package/dist/version-bar.d.ts.map +1 -1
- package/dist/version-bar.js +2 -1
- package/dist/version-bar.js.map +1 -1
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/dist/ws-client.d.ts +21 -0
- package/dist/ws-client.d.ts.map +1 -1
- package/dist/ws-client.js +192 -8
- package/dist/ws-client.js.map +1 -1
- package/dist/ws-frame-limit.d.ts +1 -0
- package/dist/ws-frame-limit.d.ts.map +1 -1
- package/dist/ws-frame-limit.js.map +1 -1
- package/docs/app-manifest.md +121 -17
- package/docs/custom-chrome.md +24 -16
- package/docs/hosted-ui-advanced.md +38 -6
- package/docs/imported-documents.md +104 -51
- package/docs/presence.md +16 -4
- package/docs/schemas.md +8 -5
- package/docs/services.md +6 -6
- package/docs/streams.md +139 -150
- package/docs/text-fields.md +26 -19
- package/package.json +5 -2
- package/src/api-fetch.ts +53 -3
- package/src/auth-flow.ts +1 -1
- package/src/batched-get.ts +117 -0
- package/src/call-service.ts +78 -3
- package/src/client.ts +1022 -112
- package/src/document-checkpoints.ts +307 -65
- package/src/document-commands.ts +5 -5
- package/src/document-contents.ts +27 -1
- package/src/document-set-subscription.ts +274 -0
- package/src/document-signals.ts +47 -5
- package/src/document-streams.ts +85 -16
- package/src/document-thumbnail-capture.ts +118 -32
- package/src/documents-namespace.ts +539 -84
- package/src/documents.ts +2017 -348
- package/src/errors.ts +17 -6
- package/src/fetch-retry.ts +5 -0
- package/src/file-choice.ts +26 -0
- package/src/guest-link.ts +362 -1
- package/src/handle-types.ts +73 -47
- package/src/handles.ts +253 -83
- package/src/hosted-ui.ts +211 -50
- package/src/import-contract.ts +227 -0
- package/src/import-guest.ts +193 -0
- package/src/import-report.ts +24 -0
- package/src/importer-wait.ts +4 -0
- package/src/importer.ts +386 -131
- package/src/in-development.ts +10 -0
- package/src/index.ts +76 -16
- package/src/init-keys.ts +6 -1
- package/src/input-documents.ts +819 -0
- package/src/inputs-status.ts +598 -0
- package/src/inputs.ts +1090 -0
- package/src/internal.ts +7 -0
- package/src/join-content.ts +135 -0
- package/src/join-stamp.ts +12 -0
- package/src/manifest-drift.ts +54 -0
- package/src/open-document.ts +2346 -930
- package/src/page-restore.ts +38 -0
- package/src/placement.ts +54 -0
- package/src/presence.ts +21 -5
- package/src/read-only-document.ts +133 -0
- package/src/record-paging.ts +147 -25
- package/src/references.ts +207 -0
- package/src/request-lane.ts +59 -0
- package/src/sealed-arrow.ts +843 -0
- package/src/sealed-cache.ts +267 -0
- package/src/sealed-encode.ts +1015 -0
- package/src/sealed-handles.ts +486 -0
- package/src/sealed-store.ts +1330 -0
- package/src/serializer.ts +8 -20
- package/src/session-toolbar.ts +463 -72
- package/src/session.ts +740 -99
- package/src/sha256.ts +65 -0
- package/src/stable-handles.ts +235 -0
- package/src/staged-seal.ts +90 -0
- package/src/subscriber-delivery.ts +37 -0
- package/src/tail-op-import.ts +30 -0
- package/src/topic-lifecycle.ts +38 -2
- package/src/trial-replace-dialog.ts +163 -0
- package/src/types.ts +6 -6
- package/src/undo.ts +386 -73
- package/src/version-bar.ts +5 -1
- package/src/version.ts +1 -1
- package/src/ws-client.ts +208 -16
- package/src/ws-frame-limit.ts +1 -0
|
@@ -16,12 +16,23 @@ export type CanvasSource =
|
|
|
16
16
|
| HTMLCanvasElement
|
|
17
17
|
| (() => HTMLCanvasElement | null);
|
|
18
18
|
|
|
19
|
+
// `version` names the document version the image depicts; omitted, the
|
|
20
|
+
// uploader reads the document's current version.
|
|
19
21
|
export type ThumbnailUploader = (
|
|
20
22
|
image: Blob,
|
|
21
23
|
width: number,
|
|
22
24
|
height: number,
|
|
25
|
+
version?: number,
|
|
23
26
|
) => Promise<void>;
|
|
24
27
|
|
|
28
|
+
// A frame taken from the registered canvas, held until the version it depicts
|
|
29
|
+
// is known.
|
|
30
|
+
export interface CapturedFrame {
|
|
31
|
+
image: Blob;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
// Debounce window: a screenshot is taken this long after the last local edit,
|
|
26
37
|
// so a continuous drag uploads once when it settles, not once per frame.
|
|
27
38
|
const THUMBNAIL_CAPTURE_DEBOUNCE_MS = 1500;
|
|
@@ -52,6 +63,23 @@ const FINGERPRINT_EDGE = 64;
|
|
|
52
63
|
// per-surface derivative is a server-side concern.
|
|
53
64
|
const MAX_THUMBNAIL_CAPTURE_EDGE = 512;
|
|
54
65
|
|
|
66
|
+
// Resolve after the browser paints the next frame. A hidden tab paints none,
|
|
67
|
+
// so a short timeout stands in for it there; outside a browser it resolves at
|
|
68
|
+
// once.
|
|
69
|
+
function nextFrame(): Promise<void> {
|
|
70
|
+
if (typeof requestAnimationFrame !== 'function') return Promise.resolve();
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
let done = false;
|
|
73
|
+
const finish = (): void => {
|
|
74
|
+
if (done) return;
|
|
75
|
+
done = true;
|
|
76
|
+
resolve();
|
|
77
|
+
};
|
|
78
|
+
requestAnimationFrame(() => finish());
|
|
79
|
+
setTimeout(finish, 100);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
55
83
|
// Cap the longest edge to `maxEdge`, preserving aspect ratio, never upscaling:
|
|
56
84
|
// a canvas within the cap is uploaded at native size (`scaled: false`), so the
|
|
57
85
|
// common small-canvas case skips the offscreen redraw. The returned dimensions
|
|
@@ -81,9 +109,12 @@ export interface ThumbnailCaptureHost {
|
|
|
81
109
|
// True when the doc is still attached, re-checked after the async toBlob +
|
|
82
110
|
// upload boundary so a capture in flight when the doc closes does not upload.
|
|
83
111
|
isAttached(): boolean;
|
|
112
|
+
// The version the document shows now: what a frame taken now depicts.
|
|
113
|
+
currentVersion(): number | null;
|
|
84
114
|
// Called once an upload lands, so the host can record which version of the
|
|
85
|
-
// document now has a picture
|
|
86
|
-
|
|
115
|
+
// document now has a picture: `version` when the upload named one, else the
|
|
116
|
+
// document's current version.
|
|
117
|
+
onCaptured?(version?: number): void;
|
|
87
118
|
}
|
|
88
119
|
|
|
89
120
|
export class ThumbnailCapture {
|
|
@@ -345,45 +376,100 @@ export class ThumbnailCapture {
|
|
|
345
376
|
return typeof this._canvas === 'function' ? this._canvas() : this._canvas;
|
|
346
377
|
}
|
|
347
378
|
|
|
379
|
+
// Take a frame for a checkpoint: on the next animation frame, so the redraw
|
|
380
|
+
// the app makes for the action it just finished is in the picture. The
|
|
381
|
+
// frame supersedes a pending debounced capture, since it depicts the same
|
|
382
|
+
// edits; an edit after it schedules a new one. Null when there is no canvas
|
|
383
|
+
// or nothing may be captured.
|
|
384
|
+
async captureFrame(): Promise<CapturedFrame | null> {
|
|
385
|
+
if (this._canvas === null || this._uploader === null) return null;
|
|
386
|
+
if (!this.host.isCaptureAllowed()) return null;
|
|
387
|
+
if (this._timer !== null) {
|
|
388
|
+
clearTimeout(this._timer);
|
|
389
|
+
this._timer = null;
|
|
390
|
+
}
|
|
391
|
+
// Once the document has a picture, a checkpoint's frame supersedes a seed
|
|
392
|
+
// watch the way an edit does (see `schedule`).
|
|
393
|
+
if (this._uploaded) {
|
|
394
|
+
this._stopSeed();
|
|
395
|
+
this._seedOwed = false;
|
|
396
|
+
}
|
|
397
|
+
await nextFrame();
|
|
398
|
+
try {
|
|
399
|
+
return await this._render();
|
|
400
|
+
} catch (err) {
|
|
401
|
+
this._warnFailure(err);
|
|
402
|
+
return null;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Upload a frame taken by `captureFrame` as the picture of `version`.
|
|
407
|
+
async uploadFrame(frame: CapturedFrame, version: number): Promise<void> {
|
|
408
|
+
if (this._uploader === null || !this.host.isAttached()) return;
|
|
409
|
+
try {
|
|
410
|
+
await this._uploader(frame.image, frame.width, frame.height, version);
|
|
411
|
+
this._uploaded = true;
|
|
412
|
+
this.host.onCaptured?.(version);
|
|
413
|
+
} catch (err) {
|
|
414
|
+
this._warnFailure(err);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private async _render(): Promise<CapturedFrame | null> {
|
|
419
|
+
const el = this._resolveCanvas();
|
|
420
|
+
if (!el) return null;
|
|
421
|
+
this._warnIfWebglContextWillProduceBlankCapture(el);
|
|
422
|
+
const target = fitWithinMaxEdge(
|
|
423
|
+
el.width,
|
|
424
|
+
el.height,
|
|
425
|
+
MAX_THUMBNAIL_CAPTURE_EDGE,
|
|
426
|
+
);
|
|
427
|
+
const source = target.scaled ? this._downscale(el, target) : el;
|
|
428
|
+
const image = await new Promise<Blob>((resolve, reject) => {
|
|
429
|
+
source.toBlob((blob) => {
|
|
430
|
+
if (blob) resolve(blob);
|
|
431
|
+
else reject(new Error('thumbnail capture: canvas produced no image'));
|
|
432
|
+
}, 'image/png');
|
|
433
|
+
});
|
|
434
|
+
return { image, width: target.width, height: target.height };
|
|
435
|
+
}
|
|
436
|
+
|
|
348
437
|
private async _capture(): Promise<void> {
|
|
349
438
|
if (!this.host.isCaptureAllowed()) return;
|
|
350
439
|
if (this._uploader === null) return;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
440
|
+
// Read before the frame is taken, so the upload names the version the
|
|
441
|
+
// frame depicts rather than whatever the document reached while the
|
|
442
|
+
// image encoded.
|
|
443
|
+
const version = this.host.currentVersion();
|
|
354
444
|
try {
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
source.toBlob((blob) => {
|
|
363
|
-
if (blob) resolve(blob);
|
|
364
|
-
else reject(new Error('thumbnail capture: canvas produced no image'));
|
|
365
|
-
}, 'image/png');
|
|
366
|
-
});
|
|
367
|
-
if (!this.host.isAttached()) return;
|
|
368
|
-
await this._uploader(image, target.width, target.height);
|
|
445
|
+
const frame = await this._render();
|
|
446
|
+
if (frame === null || !this.host.isAttached()) return;
|
|
447
|
+
if (version === null) {
|
|
448
|
+
await this._uploader(frame.image, frame.width, frame.height);
|
|
449
|
+
} else {
|
|
450
|
+
await this._uploader(frame.image, frame.width, frame.height, version);
|
|
451
|
+
}
|
|
369
452
|
this._uploaded = true;
|
|
370
|
-
this.host.onCaptured?.();
|
|
453
|
+
this.host.onCaptured?.(version ?? undefined);
|
|
371
454
|
} catch (err) {
|
|
372
|
-
|
|
373
|
-
// transient failure leaves the document on its last picture, and the
|
|
374
|
-
// next edit or arrival reschedules. Reported once, because the refusals
|
|
375
|
-
// that persist (no write access, an oversized image) are otherwise
|
|
376
|
-
// indistinguishable from a capture that never ran.
|
|
377
|
-
if (!this._warnedCaptureFailure) {
|
|
378
|
-
this._warnedCaptureFailure = true;
|
|
379
|
-
console.warn(
|
|
380
|
-
'@brass-build/client: uploading the document thumbnail failed: ' +
|
|
381
|
-
(err instanceof Error ? err.message : String(err)),
|
|
382
|
-
);
|
|
383
|
-
}
|
|
455
|
+
this._warnFailure(err);
|
|
384
456
|
}
|
|
385
457
|
}
|
|
386
458
|
|
|
459
|
+
// Best-effort: a rate-limit rejection, a lack of write access, or a
|
|
460
|
+
// transient failure leaves the document on its last picture, and the next
|
|
461
|
+
// edit or arrival reschedules. Reported once, because the refusals that
|
|
462
|
+
// persist (no write access, an oversized image) are otherwise
|
|
463
|
+
// indistinguishable from a capture that never ran.
|
|
464
|
+
private _warnFailure(err: unknown): void {
|
|
465
|
+
if (this._warnedCaptureFailure) return;
|
|
466
|
+
this._warnedCaptureFailure = true;
|
|
467
|
+
console.warn(
|
|
468
|
+
'@brass-build/client: uploading the document thumbnail failed: ' +
|
|
469
|
+
(err instanceof Error ? err.message : String(err)),
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
387
473
|
// Redraw an oversized canvas into an offscreen 2D canvas at the capped
|
|
388
474
|
// dimensions. `drawImage` reads the source's front buffer, so the WebGL
|
|
389
475
|
// `preserveDrawingBuffer` caveat above applies here too. If a 2D context
|