@quillmark/wasm 0.130.0 → 0.131.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/CHANGELOG.md +104 -0
- package/README.md +18 -10
- package/THIRD_PARTY_LICENSES.md +18 -17
- package/core/wasm.d.ts +22 -10
- package/core/wasm.js +5 -2
- package/core/wasm_bg.wasm +0 -0
- package/package.json +1 -1
- package/render/wasm.d.ts +49 -12
- package/render/wasm.js +57 -7
- package/render/wasm_bg.wasm +0 -0
- package/render/wasm_bg.wasm.d.ts +2 -1
- package/runtime/runtime.d.ts +34 -0
- package/runtime/runtime.js +62 -8
- package/sbom.cdx.json +183 -101
package/runtime/runtime.js
CHANGED
|
@@ -470,10 +470,22 @@ export class Engine {
|
|
|
470
470
|
*/
|
|
471
471
|
/** load → Promise<build module>, memoized so each build loads once. */
|
|
472
472
|
#modules = new Map();
|
|
473
|
-
/**
|
|
473
|
+
/**
|
|
474
|
+
* load → `{ engine }`, that build's engine instance (the WASM backend
|
|
475
|
+
* registry), or `{ refused }`, the error its construction threw. A refusal
|
|
476
|
+
* is the font library's, which every retry would parse and refuse again.
|
|
477
|
+
*/
|
|
474
478
|
#engines = new Map();
|
|
475
479
|
/** backendId → descriptor `{ load, formats }`. */
|
|
476
480
|
#loaders;
|
|
481
|
+
/**
|
|
482
|
+
* The host's font library, copied at construction and handed to each
|
|
483
|
+
* build's engine as it loads; `null` once every build has had it.
|
|
484
|
+
* @type {Uint8Array[] | null}
|
|
485
|
+
*/
|
|
486
|
+
#fonts;
|
|
487
|
+
/** How many distinct builds the loaders name. */
|
|
488
|
+
#builds;
|
|
477
489
|
/**
|
|
478
490
|
* load → WeakMap<canonical Quill, build-memory clone>, caching the
|
|
479
491
|
* expensive materialization. WeakMap so dropping the canonical quill makes
|
|
@@ -486,10 +498,15 @@ export class Engine {
|
|
|
486
498
|
* `load` must resolve to a READY module: a registrant shipping its own
|
|
487
499
|
* `--target web` build instantiates inside the thunk, and more than one
|
|
488
500
|
* `Engine` may call it, so memoize (the built-ins do, at module scope).
|
|
489
|
-
* @param {{ backends?: Record<string, { load: () => Promise<unknown>, formats: string[] }
|
|
501
|
+
* @param {{ backends?: Record<string, { load: () => Promise<unknown>, formats: string[] }>, fonts?: Uint8Array[] }} [options]
|
|
490
502
|
*/
|
|
491
503
|
constructor(options) {
|
|
492
|
-
rejectUnknownKeys(options, ['backends'], 'Engine options');
|
|
504
|
+
rejectUnknownKeys(options, ['backends', 'fonts'], 'Engine options');
|
|
505
|
+
const fonts = options?.fonts ?? [];
|
|
506
|
+
if (!Array.isArray(fonts) || !fonts.every((font) => font instanceof Uint8Array)) {
|
|
507
|
+
throw new Error('Engine: `fonts` must be an array of Uint8Array.');
|
|
508
|
+
}
|
|
509
|
+
this.#fonts = fonts.map((font) => font.slice());
|
|
493
510
|
const merged = { ...DEFAULT_BACKENDS, ...(options?.backends ?? {}) };
|
|
494
511
|
/** @type {Record<string, { load: () => Promise<unknown>, formats: string[] }>} */
|
|
495
512
|
const loaders = {};
|
|
@@ -497,6 +514,7 @@ export class Engine {
|
|
|
497
514
|
loaders[id] = validateBackend(id, entry);
|
|
498
515
|
}
|
|
499
516
|
this.#loaders = loaders;
|
|
517
|
+
this.#builds = new Set(Object.values(loaders).map((descriptor) => descriptor.load)).size;
|
|
500
518
|
}
|
|
501
519
|
|
|
502
520
|
/**
|
|
@@ -554,12 +572,18 @@ export class Engine {
|
|
|
554
572
|
}
|
|
555
573
|
const mod = await modPromise;
|
|
556
574
|
|
|
557
|
-
let
|
|
558
|
-
if (!
|
|
559
|
-
|
|
560
|
-
|
|
575
|
+
let built = this.#engines.get(load);
|
|
576
|
+
if (!built) {
|
|
577
|
+
try {
|
|
578
|
+
built = { engine: new mod.Engine(this.#fonts) };
|
|
579
|
+
} catch (refused) {
|
|
580
|
+
built = { refused };
|
|
581
|
+
}
|
|
582
|
+
this.#engines.set(load, built);
|
|
583
|
+
if (this.#engines.size === this.#builds) this.#fonts = null;
|
|
561
584
|
}
|
|
562
|
-
|
|
585
|
+
if ('refused' in built) throw built.refused;
|
|
586
|
+
return { mod, engine: built.engine };
|
|
563
587
|
}
|
|
564
588
|
|
|
565
589
|
/**
|
|
@@ -658,6 +682,36 @@ export class Engine {
|
|
|
658
682
|
);
|
|
659
683
|
}
|
|
660
684
|
|
|
685
|
+
/**
|
|
686
|
+
* Run `fn` against `quill`'s build-memory clone, `quill` snapshotted before
|
|
687
|
+
* the first await as `#withClones` snapshots it.
|
|
688
|
+
* @param {string} method the caller's name, for the rejection message
|
|
689
|
+
* @param {Quill} quill
|
|
690
|
+
* @param {(ctx: { engine: any, quill: any }) => any} fn
|
|
691
|
+
*/
|
|
692
|
+
async #withQuill(method, quill, fn) {
|
|
693
|
+
const backendId = this.#backendOf(quill, method);
|
|
694
|
+
const quillTree = this.#quillClones.get(this.#descriptorFor(backendId).load)?.has(quill)
|
|
695
|
+
? null
|
|
696
|
+
: quill.toTree();
|
|
697
|
+
const { mod, engine } = await this.#resolveBackend(backendId);
|
|
698
|
+
try {
|
|
699
|
+
return fn({ engine, quill: this.#cachedQuillClone(mod, backendId, quill, quillTree) });
|
|
700
|
+
} catch (err) {
|
|
701
|
+
throw backendTrap(err);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* @param {Quill} quill
|
|
707
|
+
* @returns {Promise<import('./runtime.d.ts').FontFace[]>}
|
|
708
|
+
*/
|
|
709
|
+
async fontFaces(quill) {
|
|
710
|
+
return this.#withQuill('engine.fontFaces(quill)', quill, ({ engine, quill: q }) =>
|
|
711
|
+
typeof engine.fontFaces === 'function' ? engine.fontFaces(q) : []
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
|
|
661
715
|
/**
|
|
662
716
|
* @param {Quill} quill
|
|
663
717
|
* @returns {Promise<void>}
|