three-text 0.4.4 → 0.4.5

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/README.md CHANGED
@@ -195,6 +195,12 @@ self.onmessage = (e) => {
195
195
 
196
196
  The library will prioritize the buffer if both a path and a buffer have been set
197
197
 
198
+ #### Platform-specific notes
199
+
200
+ **NW.js with CommonJS:** If using `require()` to load the CJS build in NW.js, use Option 2 (buffer-based loading). NW.js's [dual-context architecture](https://docs.nwjs.io/For%20Users/Advanced/JavaScript%20Contexts%20in%20NW.js/#separate-context-mode) causes path resolution issues in this specific scenario. ESM imports and bundled code work normally
201
+
202
+ **Electron with `file://` protocol:** If loading HTML directly from the filesystem (not via a dev server), use Option 2 (buffer-based loading) or enable `nodeIntegration` in your BrowserWindow
203
+
198
204
  ### Hyphenation patterns
199
205
 
200
206
  **For ES Modules (recommended):** Import and register only the languages you need:
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * three-text v0.4.4
2
+ * three-text v0.4.5
3
3
  * Copyright (C) 2025 Countertype LLC
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
@@ -2212,7 +2212,6 @@ async function loadPattern(language, patternsPath) {
2212
2212
  }
2213
2213
  }
2214
2214
 
2215
- // Bector and bounding box types for core
2216
2215
  // 2D Vector
2217
2216
  class Vec2 {
2218
2217
  constructor(x = 0, y = 0) {
@@ -4811,6 +4810,41 @@ class TextShaper {
4811
4810
  }
4812
4811
  }
4813
4812
 
4813
+ // Fetch with fs fallback for Electron file:// and Node.js environments
4814
+ async function loadBinary(filePath) {
4815
+ try {
4816
+ const res = await fetch(filePath);
4817
+ if (!res.ok) {
4818
+ throw new Error(`HTTP ${res.status}`);
4819
+ }
4820
+ return await res.arrayBuffer();
4821
+ }
4822
+ catch (fetchError) {
4823
+ const req = globalThis.require;
4824
+ if (typeof req !== 'function') {
4825
+ throw new Error(`Failed to fetch ${filePath}: ${fetchError}`);
4826
+ }
4827
+ try {
4828
+ const fs = req('fs');
4829
+ const nodePath = req('path');
4830
+ // file:// URLs need path resolution relative to the HTML document
4831
+ let resolvedPath = filePath;
4832
+ if (typeof window !== 'undefined' &&
4833
+ window.location?.protocol === 'file:') {
4834
+ const dir = nodePath.dirname(window.location.pathname);
4835
+ resolvedPath = nodePath.join(dir, filePath);
4836
+ }
4837
+ const buffer = fs.readFileSync(resolvedPath);
4838
+ if (buffer instanceof ArrayBuffer)
4839
+ return buffer;
4840
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
4841
+ }
4842
+ catch (fsError) {
4843
+ throw new Error(`Failed to load ${filePath}: fetch failed (${fetchError}), fs.readFileSync failed (${fsError})`);
4844
+ }
4845
+ }
4846
+ }
4847
+
4814
4848
  var hb = {exports: {}};
4815
4849
 
4816
4850
  var fs = {};
@@ -5401,11 +5435,9 @@ try {
5401
5435
  var hbjsExports = hbjs$2.exports;
5402
5436
  var hbjs$1 = /*@__PURE__*/getDefaultExportFromCjs(hbjsExports);
5403
5437
 
5404
- // These will be bundled by Rollup
5405
- // @ts-expect-error - no declarations for harfbuzzjs/hb.js
5406
5438
  let harfbuzzPromise = null;
5407
5439
  let wasmPath = null;
5408
- let wasmBuffer = null; // Add buffer option
5440
+ let wasmBuffer = null;
5409
5441
  const HarfBuzzLoader = {
5410
5442
  setWasmPath(path) {
5411
5443
  wasmPath = path;
@@ -5428,12 +5460,7 @@ const HarfBuzzLoader = {
5428
5460
  moduleConfig.wasmBinary = wasmBuffer;
5429
5461
  }
5430
5462
  else if (wasmPath) {
5431
- moduleConfig.locateFile = (path, scriptDirectory) => {
5432
- if (path.endsWith('.wasm')) {
5433
- return wasmPath;
5434
- }
5435
- return scriptDirectory + path;
5436
- };
5463
+ moduleConfig.wasmBinary = await loadBinary(wasmPath);
5437
5464
  }
5438
5465
  else {
5439
5466
  throw new Error('HarfBuzz WASM path or buffer must be set before initialization.');
@@ -5730,14 +5757,7 @@ class Text {
5730
5757
  Text.hbInitPromise = HarfBuzzLoader.getHarfBuzz();
5731
5758
  }
5732
5759
  await Text.hbInitPromise;
5733
- const fontBuffer = typeof fontSrc === 'string'
5734
- ? await fetch(fontSrc).then((res) => {
5735
- if (!res.ok) {
5736
- throw new Error(`Failed to load font from ${fontSrc}: HTTP ${res.status} ${res.statusText}`);
5737
- }
5738
- return res.arrayBuffer();
5739
- })
5740
- : fontSrc;
5760
+ const fontBuffer = typeof fontSrc === 'string' ? await loadBinary(fontSrc) : fontSrc;
5741
5761
  try {
5742
5762
  if (this.loadedFont) {
5743
5763
  this.destroy();
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * three-text v0.4.4
2
+ * three-text v0.4.5
3
3
  * Copyright (C) 2025 Countertype LLC
4
4
  *
5
5
  * This program is free software: you can redistribute it and/or modify
@@ -2209,7 +2209,6 @@ async function loadPattern(language, patternsPath) {
2209
2209
  }
2210
2210
  }
2211
2211
 
2212
- // Bector and bounding box types for core
2213
2212
  // 2D Vector
2214
2213
  class Vec2 {
2215
2214
  constructor(x = 0, y = 0) {
@@ -4808,6 +4807,41 @@ class TextShaper {
4808
4807
  }
4809
4808
  }
4810
4809
 
4810
+ // Fetch with fs fallback for Electron file:// and Node.js environments
4811
+ async function loadBinary(filePath) {
4812
+ try {
4813
+ const res = await fetch(filePath);
4814
+ if (!res.ok) {
4815
+ throw new Error(`HTTP ${res.status}`);
4816
+ }
4817
+ return await res.arrayBuffer();
4818
+ }
4819
+ catch (fetchError) {
4820
+ const req = globalThis.require;
4821
+ if (typeof req !== 'function') {
4822
+ throw new Error(`Failed to fetch ${filePath}: ${fetchError}`);
4823
+ }
4824
+ try {
4825
+ const fs = req('fs');
4826
+ const nodePath = req('path');
4827
+ // file:// URLs need path resolution relative to the HTML document
4828
+ let resolvedPath = filePath;
4829
+ if (typeof window !== 'undefined' &&
4830
+ window.location?.protocol === 'file:') {
4831
+ const dir = nodePath.dirname(window.location.pathname);
4832
+ resolvedPath = nodePath.join(dir, filePath);
4833
+ }
4834
+ const buffer = fs.readFileSync(resolvedPath);
4835
+ if (buffer instanceof ArrayBuffer)
4836
+ return buffer;
4837
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
4838
+ }
4839
+ catch (fsError) {
4840
+ throw new Error(`Failed to load ${filePath}: fetch failed (${fetchError}), fs.readFileSync failed (${fsError})`);
4841
+ }
4842
+ }
4843
+ }
4844
+
4811
4845
  var hb = {exports: {}};
4812
4846
 
4813
4847
  var fs = {};
@@ -5398,11 +5432,9 @@ try {
5398
5432
  var hbjsExports = hbjs$2.exports;
5399
5433
  var hbjs$1 = /*@__PURE__*/getDefaultExportFromCjs(hbjsExports);
5400
5434
 
5401
- // These will be bundled by Rollup
5402
- // @ts-expect-error - no declarations for harfbuzzjs/hb.js
5403
5435
  let harfbuzzPromise = null;
5404
5436
  let wasmPath = null;
5405
- let wasmBuffer = null; // Add buffer option
5437
+ let wasmBuffer = null;
5406
5438
  const HarfBuzzLoader = {
5407
5439
  setWasmPath(path) {
5408
5440
  wasmPath = path;
@@ -5425,12 +5457,7 @@ const HarfBuzzLoader = {
5425
5457
  moduleConfig.wasmBinary = wasmBuffer;
5426
5458
  }
5427
5459
  else if (wasmPath) {
5428
- moduleConfig.locateFile = (path, scriptDirectory) => {
5429
- if (path.endsWith('.wasm')) {
5430
- return wasmPath;
5431
- }
5432
- return scriptDirectory + path;
5433
- };
5460
+ moduleConfig.wasmBinary = await loadBinary(wasmPath);
5434
5461
  }
5435
5462
  else {
5436
5463
  throw new Error('HarfBuzz WASM path or buffer must be set before initialization.');
@@ -5727,14 +5754,7 @@ class Text {
5727
5754
  Text.hbInitPromise = HarfBuzzLoader.getHarfBuzz();
5728
5755
  }
5729
5756
  await Text.hbInitPromise;
5730
- const fontBuffer = typeof fontSrc === 'string'
5731
- ? await fetch(fontSrc).then((res) => {
5732
- if (!res.ok) {
5733
- throw new Error(`Failed to load font from ${fontSrc}: HTTP ${res.status} ${res.statusText}`);
5734
- }
5735
- return res.arrayBuffer();
5736
- })
5737
- : fontSrc;
5757
+ const fontBuffer = typeof fontSrc === 'string' ? await loadBinary(fontSrc) : fontSrc;
5738
5758
  try {
5739
5759
  if (this.loadedFont) {
5740
5760
  this.destroy();