@vyaz/core 0.0.3 → 0.0.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vyaz/core",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -6,10 +6,11 @@
6
6
  * import { systemFontRegistry } from './SystemFontRegistry.js';
7
7
  * await systemFontRegistry.scan();
8
8
  * console.log(systemFontRegistry.getRegisteredFamilies());
9
+ *
10
+ * ⚠️ Node.js built-in module imports are dynamic (lazy) to avoid
11
+ * Vite/Webpack externalization errors in browser builds.
9
12
  */
10
13
 
11
- import { readFileSync } from 'node:fs';
12
- import getSystemFonts from 'get-system-fonts';
13
14
  import { fontMetricsProvider } from './FontMetricsProvider.js';
14
15
 
15
16
  interface ScanResult {
@@ -86,6 +87,15 @@ export class SystemFontRegistry {
86
87
  * @returns stats about what was found and registered
87
88
  */
88
89
  async scan(): Promise<ScanResult> {
90
+ // Dynamic imports — hidden from bundler static analysis.
91
+ // Only resolves on Node.js. No-op in browser.
92
+ const [{ readFileSync }, getSystemFontsModule] = await Promise.all([
93
+ // @ts-ignore — 'node:fs' is a Node.js built-in; not resolvable with moduleResolution:bundler.
94
+ import('node:fs'),
95
+ import('get-system-fonts') as any,
96
+ ]);
97
+ const getSystemFonts = (getSystemFontsModule.default || getSystemFontsModule) as (opts?: any) => Promise<string[]>;
98
+
89
99
  const paths: string[] = await getSystemFonts();
90
100
  let registered = 0;
91
101
 
@@ -9,20 +9,40 @@
9
9
  *
10
10
  * Exports enableOfficeTextMeasure / disableOfficeTextMeasure —
11
11
  * ctx.measureText override for fontkit-based measurements in Office mode.
12
+ *
13
+ * ⚠️ All Node.js built-in module imports are dynamic (lazy) to avoid
14
+ * Vite/Webpack externalization errors in browser builds.
12
15
  */
13
- import { createRequire } from 'module';
14
16
 
15
- // ⚠️ Dynamic import prevents esbuild from resolving @napi-rs/canvas at bundle time.
16
- // This module is a native Node.js addon. In the browser, Canvas APIs are already available.
17
+ // ── Lazy Node.js module loader ─────────────────────────────────────
18
+ // Dynamic import('module') hidden from bundler static analysis.
19
+ // Only resolves on Node.js / Bun. No-op in browser.
20
+ // Use 'any' for process to avoid requiring @types/node in browser contexts.
21
+ const _process: any = typeof globalThis !== 'undefined'
22
+ ? (globalThis as any).process
23
+ : undefined;
24
+
25
+ let _require: ((id: string) => any) | null = null;
17
26
  let _createCanvas: ((w: number, h: number) => any) | null = null;
18
27
 
19
- const _require = createRequire(import.meta.url);
20
- try {
21
- const mod: any = _require('@napi-rs/canvas');
22
- _createCanvas = mod.createCanvas;
23
- } catch {
24
- // Browser — document.createElement('canvas') is available natively, no polyfill needed
25
- _createCanvas = null;
28
+ async function _initNodeDeps(): Promise<void> {
29
+ try {
30
+ // @ts-ignore 'module' is a Node.js built-in; not resolvable with moduleResolution:bundler.
31
+ // This dynamic import is guarded by a runtime check and never executes in browser.
32
+ const m: any = await import('module');
33
+ _require = m.createRequire(import.meta.url);
34
+ const canvas: any = _require!('@napi-rs/canvas');
35
+ _createCanvas = canvas.createCanvas;
36
+ } catch {
37
+ // Browser or server without @napi-rs/canvas
38
+ _createCanvas = null;
39
+ }
40
+ }
41
+
42
+ // ESM top-level await — guarded by runtime check so bundlers don't
43
+ // attempt to resolve 'module' at compile time.
44
+ if (_process && (_process.versions?.node || _process.versions?.bun)) {
45
+ await _initNodeDeps();
26
46
  }
27
47
 
28
48
  // ── Polyfill document.createElement('canvas') ────────────────────────────
@@ -174,6 +194,7 @@ function createEmptyMetrics(): TextMetrics {
174
194
  * No-op in browser or when @napi-rs/canvas is not available.
175
195
  */
176
196
  export function registerCanvasFont(fontPath: string, family: string): void {
197
+ if (!_require) return; // @napi-rs/canvas not available
177
198
  try {
178
199
  const mod = _require('@napi-rs/canvas');
179
200
  if (mod?.registerFont) {