goatdee-canvas 0.0.79 → 0.0.80

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.
Binary file
package/dist/index.cjs CHANGED
@@ -6240,6 +6240,7 @@ const TGFXBind = (module) => {
6240
6240
  setTGFXModule(module);
6241
6241
  module.module = module;
6242
6242
  module.ScalerContext = ScalerContext;
6243
+ module.PathRasterizer = PathRasterizer;
6243
6244
  module.WebMask = PathRasterizer;
6244
6245
  module.Matrix = Matrix;
6245
6246
  module.tgfx = { ...tgfx };
@@ -6604,27 +6605,21 @@ const DEFAULT_EXPORT_OPTIONS = {
6604
6605
  quality: 1,
6605
6606
  };
6606
6607
  /**
6607
- * 单线程 wasm 入口:同时显式引用 `.js` 和 `.wasm`,让 bundler 都 emit 为静态资源。
6608
+ * 单线程 wasm 二进制入口:
6608
6609
  *
6609
- * - 生产产物 `goatdee-canvas/dist/`:rollup `copy-wasm` 插件已把两个文件同步到
6610
+ * - 生产产物 `goatdee-canvas/dist/`:rollup `copy-wasm` 插件已把 `.wasm` 同步到
6610
6611
  * `dist/wasm-single/`,`import.meta.url` 指向 `dist/index.js`,相对解析正好命中;
6611
6612
  * 消费者的 bundler(webpack/vite/rspack 等)按 `new URL(..., import.meta.url)`
6612
- * 模式把两份资源都 emit 为带 hash 的静态资源。
6613
+ * 模式 emit 为带 hash 的静态资源。
6613
6614
  * - monorepo dev:源码不存在该目录,由 `apps/demo/vite.config.ts` 的 dev middleware
6614
- * 把任何 `wasm-single/ZHCanvasCoreSingle.*` 请求转发到 `packages/infinite-canvas-single/wasm/`。
6615
- *
6616
- * ⚠️ 必须同时声明 `.wasm` 的 `new URL` 引用,否则消费者 bundler 只 emit `.js`,
6617
- * Emscripten 运行时按 sibling 路径 fetch wasm 会拿到 SPA fallback 的 HTML,
6618
- * 报 "expected magic word 00 61 73 6d, found 3c 21 44 4f"。
6615
+ * `wasm-single/ZHCanvasCoreSingle.wasm` 请求转发到 `packages/infinite-canvas-single/wasm/`。
6619
6616
  *
6617
+ * glue `.js` 已在 worker IIFE 字符串内 inline,不再需要独立 emit。
6620
6618
  * 解析失败则返回 null,自动 fallback 到主线程同步导出。
6621
6619
  */
6622
- function resolveWasmUrls() {
6620
+ function resolveWasmBinaryUrl() {
6623
6621
  try {
6624
- return {
6625
- jsUrl: new URL('./wasm-single/ZHCanvasCoreSingle.js', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).href,
6626
- wasmBinaryUrl: new URL('./wasm-single/ZHCanvasCoreSingle.wasm', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).href,
6627
- };
6622
+ return new URL('./wasm-single/ZHCanvasCoreSingle.wasm', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).href;
6628
6623
  }
6629
6624
  catch (_a) {
6630
6625
  return null;
@@ -6637,8 +6632,12 @@ class ExportImageClient {
6637
6632
  this.nextReqId_ = 1;
6638
6633
  this.pending_ = new Map();
6639
6634
  this.initPromise_ = null;
6640
- // wasm 入口固定为 goatdee-canvas 自带的单线程产物;解析失败时 null,自动回主线程导出。
6641
- this.wasmUrls_ = resolveWasmUrls();
6635
+ // export 排队:并发请求会被 worker wasm 拒返空串 manager 回退主线程;主线程
6636
+ // pool 新建 BaseCanvas 会夺走 emscripten current ctx,让主 canvas render 报
6637
+ // INVALID_OPERATION "object does not belong to this context"。
6638
+ this.exportQueue_ = Promise.resolve();
6639
+ // wasm 二进制 URL 由 bundler 按 `new URL(..., import.meta.url)` 模式 emit;解析失败时 null,自动回主线程导出。
6640
+ this.wasmBinaryUrl_ = resolveWasmBinaryUrl();
6642
6641
  this.sessionLicense_ = null;
6643
6642
  this.fonts_ = null;
6644
6643
  // 已传给 worker 的图片 src,避免重复传输大 ArrayBuffer
@@ -6671,7 +6670,7 @@ class ExportImageClient {
6671
6670
  }
6672
6671
  }
6673
6672
  isConfigured() {
6674
- return !!(this.wasmUrls_ &&
6673
+ return !!(this.wasmBinaryUrl_ &&
6675
6674
  this.sessionLicense_ &&
6676
6675
  this.fonts_ &&
6677
6676
  this.fonts_.length > 0);
@@ -6694,13 +6693,28 @@ class ExportImageClient {
6694
6693
  // ── 导出 ────────────────────────────────────────────────────────────────
6695
6694
  /** 通过 worker 把 JSON 渲染为 dataURL。失败抛 Error,调用方负责 fallback。 */
6696
6695
  async export(objects, options = {}) {
6697
- var _a, _b, _c;
6698
6696
  if (!this.isConfigured()) {
6699
6697
  throw new Error('export worker not configured');
6700
6698
  }
6701
6699
  if (!objects || objects.length === 0) {
6702
6700
  return '';
6703
6701
  }
6702
+ // 排队:等上一个 export 完成再发新的,确保 worker wasm 串行执行(见 exportQueue_ 注释)
6703
+ const prev = this.exportQueue_;
6704
+ let releaseQueue;
6705
+ this.exportQueue_ = new Promise((resolve) => {
6706
+ releaseQueue = resolve;
6707
+ });
6708
+ try {
6709
+ await prev.catch(() => undefined);
6710
+ return await this.doExport(objects, options);
6711
+ }
6712
+ finally {
6713
+ releaseQueue();
6714
+ }
6715
+ }
6716
+ async doExport(objects, options) {
6717
+ var _a, _b, _c;
6704
6718
  await this.ensureInit();
6705
6719
  const images = await this.collectImageBuffers(objects);
6706
6720
  const optionsStr = JSON.stringify({
@@ -6726,7 +6740,7 @@ class ExportImageClient {
6726
6740
  this.worker_ = this.createWorker();
6727
6741
  this.bindMessageHandler(this.worker_);
6728
6742
  }
6729
- const { jsUrl: wasmUrl, wasmBinaryUrl } = this.wasmUrls_;
6743
+ const wasmBinaryUrl = this.wasmBinaryUrl_;
6730
6744
  const sessionLicense = this.sessionLicense_;
6731
6745
  // 拷贝后再 transfer:避免 postMessage transfer 把 manager 里缓存的 buffer detach,
6732
6746
  // 否则 worker reset 后无法再次 INIT。
@@ -6734,7 +6748,7 @@ class ExportImageClient {
6734
6748
  name: f.name,
6735
6749
  buffer: f.buffer.slice(0),
6736
6750
  }));
6737
- this.initPromise_ = this.postRequest({ type: 'INIT', wasmUrl, wasmBinaryUrl, sessionLicense, fonts }, fonts.map((f) => f.buffer))
6751
+ this.initPromise_ = this.postRequest({ type: 'INIT', wasmBinaryUrl, sessionLicense, fonts }, fonts.map((f) => f.buffer))
6738
6752
  .then(() => undefined)
6739
6753
  .catch((e) => {
6740
6754
  this.initPromise_ = null;