@qianxiang-ai/fu-report-image-export-engine 0.0.0-stage → 1.1.7
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/dist/controller.d.ts +23 -0
- package/dist/controller.d.ts.map +1 -0
- package/dist/controller.js +204 -0
- package/dist/controller.js.map +1 -0
- package/dist/image-export.worker.d.ts +2 -0
- package/dist/image-export.worker.d.ts.map +1 -0
- package/dist/image-export.worker.js +3 -0
- package/dist/image-export.worker.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/memory-budget.d.ts +36 -0
- package/dist/memory-budget.d.ts.map +1 -0
- package/dist/memory-budget.js +85 -0
- package/dist/memory-budget.js.map +1 -0
- package/dist/resource-lru.d.ts +16 -0
- package/dist/resource-lru.d.ts.map +1 -0
- package/dist/resource-lru.js +49 -0
- package/dist/resource-lru.js.map +1 -0
- package/dist/snapshot.d.ts +11 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +172 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/stream-encoder.d.ts +12 -0
- package/dist/stream-encoder.d.ts.map +1 -0
- package/dist/stream-encoder.js +436 -0
- package/dist/stream-encoder.js.map +1 -0
- package/dist/strip-planner.d.ts +10 -0
- package/dist/strip-planner.d.ts.map +1 -0
- package/dist/strip-planner.js +20 -0
- package/dist/strip-planner.js.map +1 -0
- package/dist/tile-renderer.d.ts +15 -0
- package/dist/tile-renderer.d.ts.map +1 -0
- package/dist/tile-renderer.js +322 -0
- package/dist/tile-renderer.js.map +1 -0
- package/dist/types.d.ts +115 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/wasm-kernel.d.ts +8 -0
- package/dist/wasm-kernel.d.ts.map +1 -0
- package/dist/wasm-kernel.js +43 -0
- package/dist/wasm-kernel.js.map +1 -0
- package/dist/worker-protocol.d.ts +38 -0
- package/dist/worker-protocol.d.ts.map +1 -0
- package/dist/worker-protocol.js +2 -0
- package/dist/worker-protocol.js.map +1 -0
- package/dist/worker-runtime.d.ts +7 -0
- package/dist/worker-runtime.d.ts.map +1 -0
- package/dist/worker-runtime.js +176 -0
- package/dist/worker-runtime.js.map +1 -0
- package/package.json +28 -3
- package/README.md +0 -3
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { FuReportImageExportOptions, FuReportImageExportResult, FuReportRenderSnapshot } from './types.js';
|
|
2
|
+
import type { FuReportImageWorkerRequest, FuReportImageWorkerResponse } from './worker-protocol.js';
|
|
3
|
+
export interface FuReportOutputTarget {
|
|
4
|
+
readonly usesFileSystemAccess: boolean;
|
|
5
|
+
write(bytes: Uint8Array): Promise<void>;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
abort(reason?: unknown): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export interface FuReportImageWorkerLike {
|
|
10
|
+
postMessage(message: FuReportImageWorkerRequest): void;
|
|
11
|
+
terminate(): void;
|
|
12
|
+
addEventListener(type: 'message', listener: (event: MessageEvent<FuReportImageWorkerResponse>) => void): void;
|
|
13
|
+
addEventListener(type: 'error', listener: (event: ErrorEvent) => void): void;
|
|
14
|
+
}
|
|
15
|
+
export interface FuReportImageExportDependencies {
|
|
16
|
+
readonly target?: FuReportOutputTarget;
|
|
17
|
+
readonly workerFactory?: () => FuReportImageWorkerLike;
|
|
18
|
+
readonly blobLimitBytes?: number;
|
|
19
|
+
readonly forceBlobFallback?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function exportFuReportImage(snapshot: FuReportRenderSnapshot, options: FuReportImageExportOptions, dependencies?: FuReportImageExportDependencies): Promise<FuReportImageExportResult>;
|
|
22
|
+
export declare function createFuReportImageWorker(_clientBuildId?: string): FuReportImageWorkerLike;
|
|
23
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,YAAY,CAAA;AAGnB,OAAO,KAAK,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAA;AAEnG,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAA;IACtC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvC;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAA;IACtD,SAAS,IAAI,IAAI,CAAA;IACjB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,2BAA2B,CAAC,KAAK,IAAI,GAAG,IAAI,CAAA;IAC7G,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAA;CAC7E;AAED,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAA;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,uBAAuB,CAAA;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;CACrC;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,0BAA0B,EACnC,YAAY,GAAE,+BAAoC,GACjD,OAAO,CAAC,yBAAyB,CAAC,CA2HpC;AAED,wBAAgB,yBAAyB,CAAC,cAAc,SAAgB,GAAG,uBAAuB,CAOjG"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { FuReportImageExportError } from './types.js';
|
|
2
|
+
import { FU_REPORT_IMAGE_WASM_SHA256, FU_REPORT_IMAGE_WORKER_PROTOCOL } from './wasm-kernel.js';
|
|
3
|
+
export async function exportFuReportImage(snapshot, options, dependencies = {}) {
|
|
4
|
+
if (options.runtimeBuildId !== options.clientBuildId) {
|
|
5
|
+
throw new FuReportImageExportError('EXPORT_BUILD_MISMATCH', 'runtime-config 与当前页面 buildId 不一致');
|
|
6
|
+
}
|
|
7
|
+
const target = dependencies.target ?? await selectFuReportOutputTarget(options.filename ?? safeFilename(snapshot.title, options.format), options.format, dependencies.blobLimitBytes, dependencies.forceBlobFallback);
|
|
8
|
+
throwIfCancelled(options.signal);
|
|
9
|
+
const worker = dependencies.workerFactory?.() ?? createFuReportImageWorker(options.clientBuildId);
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
let settled = false;
|
|
12
|
+
let writing = Promise.resolve();
|
|
13
|
+
let started = false;
|
|
14
|
+
let responseTimeout;
|
|
15
|
+
const startupTimeout = setTimeout(() => {
|
|
16
|
+
void fail(new FuReportImageExportError('EXPORT_WORKER_CRASH', '图片导出 Worker 启动超时'));
|
|
17
|
+
}, 10_000);
|
|
18
|
+
const cancel = () => worker.postMessage({ type: 'cancel', reason: 'EXPORT_CANCELLED' });
|
|
19
|
+
options.signal?.addEventListener('abort', cancel, { once: true });
|
|
20
|
+
const cleanup = () => {
|
|
21
|
+
clearTimeout(startupTimeout);
|
|
22
|
+
if (responseTimeout)
|
|
23
|
+
clearTimeout(responseTimeout);
|
|
24
|
+
options.signal?.removeEventListener('abort', cancel);
|
|
25
|
+
worker.terminate();
|
|
26
|
+
};
|
|
27
|
+
const fail = async (error) => {
|
|
28
|
+
if (settled)
|
|
29
|
+
return;
|
|
30
|
+
settled = true;
|
|
31
|
+
worker.postMessage({ type: 'cancel', reason: error.code });
|
|
32
|
+
try {
|
|
33
|
+
await writing.catch(() => undefined);
|
|
34
|
+
await target.abort(error);
|
|
35
|
+
}
|
|
36
|
+
catch (cleanupError) {
|
|
37
|
+
cleanup();
|
|
38
|
+
reject(new FuReportImageExportError('EXPORT_PARTIAL_FILE_CLEANUP_FAILED', '图片导出失败,且未能确认临时文件已清理', { cause: cleanupError }));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
cleanup();
|
|
42
|
+
reject(error);
|
|
43
|
+
};
|
|
44
|
+
worker.addEventListener('error', event => {
|
|
45
|
+
void fail(new FuReportImageExportError('EXPORT_WORKER_CRASH', event.message || '图片导出 Worker 崩溃'));
|
|
46
|
+
});
|
|
47
|
+
worker.addEventListener('message', event => {
|
|
48
|
+
const message = event.data;
|
|
49
|
+
if (started)
|
|
50
|
+
armResponseTimeout();
|
|
51
|
+
if (message.type === 'ready') {
|
|
52
|
+
if (started)
|
|
53
|
+
return;
|
|
54
|
+
if (message.protocol !== FU_REPORT_IMAGE_WORKER_PROTOCOL
|
|
55
|
+
|| (message.workerBuildId !== options.clientBuildId && message.workerBuildId !== 'development')
|
|
56
|
+
|| message.wasmSha256 !== FU_REPORT_IMAGE_WASM_SHA256) {
|
|
57
|
+
void fail(new FuReportImageExportError('EXPORT_BUILD_MISMATCH', '图片导出 Worker 版本握手失败'));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
started = true;
|
|
61
|
+
clearTimeout(startupTimeout);
|
|
62
|
+
armResponseTimeout();
|
|
63
|
+
const { signal: _signal, ...workerOptions } = options;
|
|
64
|
+
worker.postMessage({
|
|
65
|
+
type: 'start',
|
|
66
|
+
protocol: FU_REPORT_IMAGE_WORKER_PROTOCOL,
|
|
67
|
+
snapshot,
|
|
68
|
+
options: workerOptions,
|
|
69
|
+
wasmSha256: FU_REPORT_IMAGE_WASM_SHA256
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (message.type === 'chunk') {
|
|
74
|
+
writing = writing.then(async () => {
|
|
75
|
+
try {
|
|
76
|
+
await target.write(new Uint8Array(message.bytes));
|
|
77
|
+
worker.postMessage({ type: 'write-ack', chunkId: message.chunkId });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
worker.postMessage({
|
|
81
|
+
type: 'write-ack', chunkId: message.chunkId,
|
|
82
|
+
error: error instanceof Error ? error.message : '文件写入失败'
|
|
83
|
+
});
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}).catch(error => {
|
|
87
|
+
void fail(new FuReportImageExportError('EXPORT_WRITE_FAILED', error instanceof Error ? error.message : '图片文件写入失败', { cause: error }));
|
|
88
|
+
});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (message.type === 'error') {
|
|
92
|
+
void fail(new FuReportImageExportError(message.code, message.message));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (message.type === 'done') {
|
|
96
|
+
writing = writing.then(async () => {
|
|
97
|
+
if (settled)
|
|
98
|
+
return;
|
|
99
|
+
await target.close();
|
|
100
|
+
settled = true;
|
|
101
|
+
cleanup();
|
|
102
|
+
resolve({ ...message.result, usedFileSystemAccess: target.usesFileSystemAccess });
|
|
103
|
+
}).catch(error => void fail(new FuReportImageExportError('EXPORT_WRITE_FAILED', error instanceof Error ? error.message : '图片文件提交失败', { cause: error })));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
function armResponseTimeout() {
|
|
107
|
+
if (responseTimeout)
|
|
108
|
+
clearTimeout(responseTimeout);
|
|
109
|
+
responseTimeout = setTimeout(() => {
|
|
110
|
+
void fail(new FuReportImageExportError('EXPORT_WORKER_CRASH', '图片导出 Worker 响应超时'));
|
|
111
|
+
}, 30_000);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export function createFuReportImageWorker(_clientBuildId = 'development') {
|
|
116
|
+
if (typeof Worker !== 'function') {
|
|
117
|
+
throw new FuReportImageExportError('EXPORT_UNSUPPORTED', '当前浏览器不支持专用 Worker');
|
|
118
|
+
}
|
|
119
|
+
return new Worker(new URL('./image-export.worker.js', import.meta.url), {
|
|
120
|
+
type: 'module', name: 'fu-report-image-export'
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async function selectFuReportOutputTarget(filename, format, blobLimitBytes = 32 * 1024 * 1024, forceBlobFallback = false) {
|
|
124
|
+
const picker = globalThis.showSaveFilePicker;
|
|
125
|
+
if (picker && !forceBlobFallback) {
|
|
126
|
+
const activation = navigator.userActivation;
|
|
127
|
+
if (activation && !activation.isActive) {
|
|
128
|
+
throw new FuReportImageExportError('EXPORT_USER_ACTIVATION_REQUIRED', '请直接点击导出按钮选择保存位置');
|
|
129
|
+
}
|
|
130
|
+
const mime = format === 'png' ? 'image/png' : 'image/jpeg';
|
|
131
|
+
const extension = format === 'png' ? '.png' : '.jpg';
|
|
132
|
+
const handle = await picker({
|
|
133
|
+
suggestedName: filename,
|
|
134
|
+
types: [{ description: format.toUpperCase(), accept: { [mime]: [extension] } }]
|
|
135
|
+
});
|
|
136
|
+
const writable = await handle.createWritable();
|
|
137
|
+
return new FileSystemTarget(writable);
|
|
138
|
+
}
|
|
139
|
+
return new BlobDownloadTarget(filename, format === 'png' ? 'image/png' : 'image/jpeg', blobLimitBytes);
|
|
140
|
+
}
|
|
141
|
+
class FileSystemTarget {
|
|
142
|
+
writable;
|
|
143
|
+
usesFileSystemAccess = true;
|
|
144
|
+
constructor(writable) {
|
|
145
|
+
this.writable = writable;
|
|
146
|
+
}
|
|
147
|
+
write(bytes) { return this.writable.write(bytes); }
|
|
148
|
+
close() { return this.writable.close(); }
|
|
149
|
+
abort(reason) { return this.writable.abort(reason); }
|
|
150
|
+
}
|
|
151
|
+
class BlobDownloadTarget {
|
|
152
|
+
filename;
|
|
153
|
+
mime;
|
|
154
|
+
limit;
|
|
155
|
+
usesFileSystemAccess = false;
|
|
156
|
+
chunks = [];
|
|
157
|
+
bytes = 0;
|
|
158
|
+
constructor(filename, mime, limit) {
|
|
159
|
+
this.filename = filename;
|
|
160
|
+
this.mime = mime;
|
|
161
|
+
this.limit = limit;
|
|
162
|
+
}
|
|
163
|
+
async write(bytes) {
|
|
164
|
+
if (this.bytes + bytes.byteLength > this.limit) {
|
|
165
|
+
throw new FuReportImageExportError('EXPORT_BLOB_LIMIT', '浏览器不支持文件流,且导出结果超过 Blob 上限');
|
|
166
|
+
}
|
|
167
|
+
this.chunks.push(bytes.slice().buffer);
|
|
168
|
+
this.bytes += bytes.byteLength;
|
|
169
|
+
}
|
|
170
|
+
async close() {
|
|
171
|
+
const blob = new Blob(this.chunks, { type: this.mime });
|
|
172
|
+
const url = URL.createObjectURL(blob);
|
|
173
|
+
try {
|
|
174
|
+
const anchor = document.createElement('a');
|
|
175
|
+
anchor.href = url;
|
|
176
|
+
anchor.download = this.filename;
|
|
177
|
+
anchor.rel = 'noopener';
|
|
178
|
+
anchor.hidden = true;
|
|
179
|
+
document.body.append(anchor);
|
|
180
|
+
anchor.click();
|
|
181
|
+
anchor.remove();
|
|
182
|
+
// 给浏览器下载队列一个事件循环周期消费 object URL,再释放底层 Blob。
|
|
183
|
+
setTimeout(() => URL.revokeObjectURL(url), 1_000);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
URL.revokeObjectURL(url);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
this.chunks.length = 0;
|
|
191
|
+
this.bytes = 0;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async abort() { this.chunks.length = 0; this.bytes = 0; }
|
|
195
|
+
}
|
|
196
|
+
function safeFilename(title, format) {
|
|
197
|
+
const stem = title.replace(/[<>:"/\\|?*\u0000-\u001f]/g, '_').trim().slice(0, 120) || 'fu-report';
|
|
198
|
+
return `${stem}.${format === 'png' ? 'png' : 'jpg'}`;
|
|
199
|
+
}
|
|
200
|
+
function throwIfCancelled(signal) {
|
|
201
|
+
if (signal?.aborted)
|
|
202
|
+
throw new FuReportImageExportError('EXPORT_CANCELLED', '图片导出已取消');
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../src/controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-export.worker.d.ts","sourceRoot":"","sources":["../src/image-export.worker.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-export.worker.js","sourceRoot":"","sources":["../src/image-export.worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAgC,MAAM,qBAAqB,CAAA;AAE9F,0BAA0B,CAAC,IAA0C,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './snapshot.js';
|
|
3
|
+
export * from './strip-planner.js';
|
|
4
|
+
export * from './memory-budget.js';
|
|
5
|
+
export * from './resource-lru.js';
|
|
6
|
+
export * from './stream-encoder.js';
|
|
7
|
+
export * from './controller.js';
|
|
8
|
+
export { FU_REPORT_IMAGE_WASM_SHA256, FU_REPORT_IMAGE_WORKER_PROTOCOL } from './wasm-kernel.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './snapshot.js';
|
|
3
|
+
export * from './strip-planner.js';
|
|
4
|
+
export * from './memory-budget.js';
|
|
5
|
+
export * from './resource-lru.js';
|
|
6
|
+
export * from './stream-encoder.js';
|
|
7
|
+
export * from './controller.js';
|
|
8
|
+
export { FU_REPORT_IMAGE_WASM_SHA256, FU_REPORT_IMAGE_WORKER_PROTOCOL } from './wasm-kernel.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,oBAAoB,CAAA;AAClC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FuReportRenderSnapshot } from './types.js';
|
|
2
|
+
export type FuReportBudgetKind = 'imageBitmapBytes' | 'arrayBufferBytes' | 'wasmMemoryBytes' | 'inflightChunks' | 'temporaryPixels';
|
|
3
|
+
export interface FuReportExportMemoryLimits {
|
|
4
|
+
readonly maximumArea: number;
|
|
5
|
+
readonly maximumEdge: number;
|
|
6
|
+
readonly maximumDecodedPixels: number;
|
|
7
|
+
readonly maximumImages: number;
|
|
8
|
+
readonly maximumFonts: number;
|
|
9
|
+
readonly maximumLayers: number;
|
|
10
|
+
readonly maximumPrimitives: number;
|
|
11
|
+
readonly maximumGlyphs: number;
|
|
12
|
+
readonly maximumPaths: number;
|
|
13
|
+
readonly imageBitmapBytes: number;
|
|
14
|
+
readonly arrayBufferBytes: number;
|
|
15
|
+
readonly wasmMemoryBytes: number;
|
|
16
|
+
readonly inflightChunks: number;
|
|
17
|
+
readonly temporaryPixels: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_FU_REPORT_EXPORT_MEMORY_LIMITS: FuReportExportMemoryLimits;
|
|
20
|
+
export interface FuReportMemoryBudgetSnapshot {
|
|
21
|
+
readonly closed: boolean;
|
|
22
|
+
readonly current: Readonly<Record<FuReportBudgetKind, number>>;
|
|
23
|
+
readonly peak: Readonly<Record<FuReportBudgetKind, number>>;
|
|
24
|
+
}
|
|
25
|
+
export declare class FuReportExportMemoryBudget {
|
|
26
|
+
readonly limits: FuReportExportMemoryLimits;
|
|
27
|
+
private closed;
|
|
28
|
+
private readonly current;
|
|
29
|
+
private readonly peak;
|
|
30
|
+
constructor(limits?: FuReportExportMemoryLimits);
|
|
31
|
+
validateSnapshot(snapshot: FuReportRenderSnapshot): void;
|
|
32
|
+
reserve(kind: FuReportBudgetKind, amount: number): () => void;
|
|
33
|
+
snapshot(): FuReportMemoryBudgetSnapshot;
|
|
34
|
+
close(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=memory-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-budget.d.ts","sourceRoot":"","sources":["../src/memory-budget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAGxD,MAAM,MAAM,kBAAkB,GAC1B,kBAAkB,GAClB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,CAAA;AAErB,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;CACjC;AAED,eAAO,MAAM,sCAAsC,EAAE,0BAenD,CAAA;AAEF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;IAC9D,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;CAC5D;AAED,qBAAa,0BAA0B;IACrC,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAA;IAC3C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;gBAEvB,MAAM,GAAE,0BAAmE;IAIvF,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAsBxD,OAAO,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI;IAmB7D,QAAQ,IAAI,4BAA4B;IAIxC,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { FuReportImageExportError } from './types.js';
|
|
2
|
+
export const DEFAULT_FU_REPORT_EXPORT_MEMORY_LIMITS = Object.freeze({
|
|
3
|
+
maximumArea: 400_000_000,
|
|
4
|
+
maximumEdge: 32_767,
|
|
5
|
+
maximumDecodedPixels: 160_000_000,
|
|
6
|
+
maximumImages: 512,
|
|
7
|
+
maximumFonts: 64,
|
|
8
|
+
maximumLayers: 20_000,
|
|
9
|
+
maximumPrimitives: 2_000_000,
|
|
10
|
+
maximumGlyphs: 20_000_000,
|
|
11
|
+
maximumPaths: 2_000_000,
|
|
12
|
+
imageBitmapBytes: 96 * 1024 * 1024,
|
|
13
|
+
arrayBufferBytes: 64 * 1024 * 1024,
|
|
14
|
+
wasmMemoryBytes: 8 * 1024 * 1024,
|
|
15
|
+
inflightChunks: 1,
|
|
16
|
+
temporaryPixels: 16_000_000
|
|
17
|
+
});
|
|
18
|
+
export class FuReportExportMemoryBudget {
|
|
19
|
+
limits;
|
|
20
|
+
closed = false;
|
|
21
|
+
current = zeroUsage();
|
|
22
|
+
peak = zeroUsage();
|
|
23
|
+
constructor(limits = DEFAULT_FU_REPORT_EXPORT_MEMORY_LIMITS) {
|
|
24
|
+
this.limits = limits;
|
|
25
|
+
}
|
|
26
|
+
validateSnapshot(snapshot) {
|
|
27
|
+
if (snapshot.width > this.limits.maximumEdge || snapshot.height > this.limits.maximumEdge) {
|
|
28
|
+
throw new FuReportImageExportError('EXPORT_EDGE_LIMIT', '图片边长超过浏览器导出上限');
|
|
29
|
+
}
|
|
30
|
+
if (snapshot.width * snapshot.height > this.limits.maximumArea) {
|
|
31
|
+
throw new FuReportImageExportError('EXPORT_TOO_LARGE', '图片总面积超过浏览器导出上限');
|
|
32
|
+
}
|
|
33
|
+
const counters = snapshot.counters;
|
|
34
|
+
const checks = [
|
|
35
|
+
[counters.decodedPixels, this.limits.maximumDecodedPixels],
|
|
36
|
+
[counters.images, this.limits.maximumImages],
|
|
37
|
+
[counters.fonts, this.limits.maximumFonts],
|
|
38
|
+
[counters.layers, this.limits.maximumLayers],
|
|
39
|
+
[counters.primitives, this.limits.maximumPrimitives],
|
|
40
|
+
[counters.glyphs, this.limits.maximumGlyphs],
|
|
41
|
+
[counters.paths, this.limits.maximumPaths]
|
|
42
|
+
];
|
|
43
|
+
if (checks.some(([actual, limit]) => actual > limit)) {
|
|
44
|
+
throw new FuReportImageExportError('EXPORT_RESOURCE_BUDGET', '报表资源数量超过浏览器导出预算');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
reserve(kind, amount) {
|
|
48
|
+
if (this.closed)
|
|
49
|
+
throw new FuReportImageExportError('EXPORT_CANCELLED', '图片导出预算已关闭');
|
|
50
|
+
if (!Number.isSafeInteger(amount) || amount < 0) {
|
|
51
|
+
throw new FuReportImageExportError('EXPORT_RESOURCE_BUDGET', '图片导出内存申请无效');
|
|
52
|
+
}
|
|
53
|
+
const next = this.current[kind] + amount;
|
|
54
|
+
if (next > this.limits[kind]) {
|
|
55
|
+
throw new FuReportImageExportError('EXPORT_RESOURCE_BUDGET', `图片导出 ${kind} 超出预算`);
|
|
56
|
+
}
|
|
57
|
+
this.current[kind] = next;
|
|
58
|
+
this.peak[kind] = Math.max(this.peak[kind], next);
|
|
59
|
+
let released = false;
|
|
60
|
+
return () => {
|
|
61
|
+
if (released)
|
|
62
|
+
return;
|
|
63
|
+
released = true;
|
|
64
|
+
this.current[kind] = Math.max(0, this.current[kind] - amount);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
snapshot() {
|
|
68
|
+
return { closed: this.closed, current: { ...this.current }, peak: { ...this.peak } };
|
|
69
|
+
}
|
|
70
|
+
close() {
|
|
71
|
+
this.closed = true;
|
|
72
|
+
for (const kind of Object.keys(this.current))
|
|
73
|
+
this.current[kind] = 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function zeroUsage() {
|
|
77
|
+
return {
|
|
78
|
+
imageBitmapBytes: 0,
|
|
79
|
+
arrayBufferBytes: 0,
|
|
80
|
+
wasmMemoryBytes: 0,
|
|
81
|
+
inflightChunks: 0,
|
|
82
|
+
temporaryPixels: 0
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=memory-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-budget.js","sourceRoot":"","sources":["../src/memory-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface FuReportClosableResource {
|
|
2
|
+
close(): void;
|
|
3
|
+
}
|
|
4
|
+
export declare class FuReportStripResourceLru<T extends FuReportClosableResource> {
|
|
5
|
+
private readonly maximumBytes;
|
|
6
|
+
private readonly entries;
|
|
7
|
+
private bytes;
|
|
8
|
+
constructor(maximumBytes: number);
|
|
9
|
+
get(key: string): T | undefined;
|
|
10
|
+
set(key: string, value: T, bytes: number): void;
|
|
11
|
+
clear(): void;
|
|
12
|
+
get size(): number;
|
|
13
|
+
get byteLength(): number;
|
|
14
|
+
private evictOldest;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=resource-lru.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-lru.d.ts","sourceRoot":"","sources":["../src/resource-lru.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,KAAK,IAAI,IAAI,CAAA;CACd;AAOD,qBAAa,wBAAwB,CAAC,CAAC,SAAS,wBAAwB;IAI1D,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,KAAK,CAAI;gBAEY,YAAY,EAAE,MAAM;IAEjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAQ/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAgB/C,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI,MAAM,CAA6B;IAC/C,IAAI,UAAU,IAAI,MAAM,CAAsB;IAE9C,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export class FuReportStripResourceLru {
|
|
2
|
+
maximumBytes;
|
|
3
|
+
entries = new Map();
|
|
4
|
+
bytes = 0;
|
|
5
|
+
constructor(maximumBytes) {
|
|
6
|
+
this.maximumBytes = maximumBytes;
|
|
7
|
+
}
|
|
8
|
+
get(key) {
|
|
9
|
+
const entry = this.entries.get(key);
|
|
10
|
+
if (!entry)
|
|
11
|
+
return undefined;
|
|
12
|
+
this.entries.delete(key);
|
|
13
|
+
this.entries.set(key, entry);
|
|
14
|
+
return entry.value;
|
|
15
|
+
}
|
|
16
|
+
set(key, value, bytes) {
|
|
17
|
+
const previous = this.entries.get(key);
|
|
18
|
+
if (previous) {
|
|
19
|
+
previous.value.close();
|
|
20
|
+
this.bytes -= previous.bytes;
|
|
21
|
+
this.entries.delete(key);
|
|
22
|
+
}
|
|
23
|
+
if (bytes > this.maximumBytes) {
|
|
24
|
+
value.close();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this.entries.set(key, { value, bytes });
|
|
28
|
+
this.bytes += bytes;
|
|
29
|
+
while (this.bytes > this.maximumBytes)
|
|
30
|
+
this.evictOldest();
|
|
31
|
+
}
|
|
32
|
+
clear() {
|
|
33
|
+
for (const entry of this.entries.values())
|
|
34
|
+
entry.value.close();
|
|
35
|
+
this.entries.clear();
|
|
36
|
+
this.bytes = 0;
|
|
37
|
+
}
|
|
38
|
+
get size() { return this.entries.size; }
|
|
39
|
+
get byteLength() { return this.bytes; }
|
|
40
|
+
evictOldest() {
|
|
41
|
+
const first = this.entries.entries().next().value;
|
|
42
|
+
if (!first)
|
|
43
|
+
return;
|
|
44
|
+
first[1].value.close();
|
|
45
|
+
this.bytes -= first[1].bytes;
|
|
46
|
+
this.entries.delete(first[0]);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=resource-lru.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-lru.js","sourceRoot":"","sources":["../src/resource-lru.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,wBAAwB;IAIN;IAHZ,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;IAC9C,KAAK,GAAG,CAAC,CAAA;IAEjB,YAA6B,YAAoB;QAApB,iBAAY,GAAZ,YAAY,CAAQ;IAAG,CAAC;IAErD,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAA;QAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAC5B,OAAO,KAAK,CAAC,KAAK,CAAA;IACpB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ,EAAE,KAAa;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACtC,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;YACtB,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAA;YAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,CAAC;QACD,IAAI,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC9B,KAAK,CAAC,KAAK,EAAE,CAAA;YACb,OAAM;QACR,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QACvC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAA;QACnB,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY;YAAE,IAAI,CAAC,WAAW,EAAE,CAAA;IAC3D,CAAC;IAED,KAAK;QACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAC9D,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAA;QACpB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;IAChB,CAAC;IAED,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA,CAAC,CAAC;IAC/C,IAAI,UAAU,KAAa,OAAO,IAAI,CAAC,KAAK,CAAA,CAAC,CAAC;IAEtC,WAAW;QACjB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAuC,CAAA;QACnF,IAAI,CAAC,KAAK;YAAE,OAAM;QAClB,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QACtB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NativeViewerDocument } from '@qianxiang-ai/fu-report-viewer-engine';
|
|
2
|
+
import type { FuReportImageScope, FuReportRenderSnapshot } from './types.js';
|
|
3
|
+
export interface FuReportSnapshotOptions {
|
|
4
|
+
readonly scope?: FuReportImageScope;
|
|
5
|
+
readonly activeSheetId?: string;
|
|
6
|
+
readonly baseOrigin?: string;
|
|
7
|
+
readonly sheetGap?: number;
|
|
8
|
+
readonly edgePadding?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function createFuReportRenderSnapshot(document: NativeViewerDocument, options?: FuReportSnapshotOptions): FuReportRenderSnapshot;
|
|
11
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,oBAAoB,EAErB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,KAAK,EACV,kBAAkB,EAGlB,sBAAsB,EAIvB,MAAM,YAAY,CAAA;AAGnB,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,kBAAkB,CAAA;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CA6CxB"}
|