@vyaz/core 0.0.10 → 0.0.11

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.
@@ -18200,12 +18200,31 @@ function normaliseWeight(weight) {
18200
18200
  return mapped;
18201
18201
  return weight;
18202
18202
  }
18203
- function cacheKey2(family, weight, style) {
18204
- return `${family}_${normaliseWeight(weight)}_${style}`;
18203
+ function weightToNumber(weight) {
18204
+ const num = parseInt(weight, 10);
18205
+ return isNaN(num) ? 400 : num;
18206
+ }
18207
+ function variantKey(weight, style) {
18208
+ return `${normaliseWeight(weight)}_${style}`;
18209
+ }
18210
+ function nearestWeight(registeredWeights, requested) {
18211
+ if (registeredWeights.length === 0)
18212
+ return null;
18213
+ let best = registeredWeights[0];
18214
+ let bestDist = Math.abs(best - requested);
18215
+ for (let i = 1;i < registeredWeights.length; i++) {
18216
+ const w = registeredWeights[i];
18217
+ const dist = Math.abs(w - requested);
18218
+ if (dist < bestDist || dist === bestDist && w > best) {
18219
+ best = w;
18220
+ bestDist = dist;
18221
+ }
18222
+ }
18223
+ return best;
18205
18224
  }
18206
18225
 
18207
18226
  class FontMetricsProvider {
18208
- cache = new Map;
18227
+ registry = new Map;
18209
18228
  metricsCache = new Map;
18210
18229
  mode = "browser";
18211
18230
  pendingRegistrations = new Set;
@@ -18229,7 +18248,7 @@ class FontMetricsProvider {
18229
18248
  this.mode = mode;
18230
18249
  this.metricsCache.clear();
18231
18250
  if (mode === "office") {
18232
- enableOfficeTextMeasure(this.cache);
18251
+ enableOfficeTextMeasure(this._flattenCache());
18233
18252
  } else {
18234
18253
  disableOfficeTextMeasure();
18235
18254
  }
@@ -18237,6 +18256,15 @@ class FontMetricsProvider {
18237
18256
  getMode() {
18238
18257
  return this.mode;
18239
18258
  }
18259
+ _flattenCache() {
18260
+ const flat = new Map;
18261
+ for (const [family, variants] of this.registry) {
18262
+ for (const [vKey, font] of variants) {
18263
+ flat.set(`${family}_${vKey}`, font);
18264
+ }
18265
+ }
18266
+ return flat;
18267
+ }
18240
18268
  async registerFont(family, options, source, sourcePath) {
18241
18269
  const promise = this._registerFontInternal(family, options, source, sourcePath);
18242
18270
  this.pendingRegistrations.add(promise);
@@ -18254,9 +18282,18 @@ class FontMetricsProvider {
18254
18282
  source = await getFontBuffer2(source);
18255
18283
  }
18256
18284
  const font = await createFontFace2(source);
18257
- const key = cacheKey2(family, options.weight || "normal", options.style || "normal");
18258
- this.cache.set(key, font);
18259
- this.metricsCache.delete(key);
18285
+ const w = options.weight || "normal";
18286
+ const s = options.style || "normal";
18287
+ const vKey = variantKey(w, s);
18288
+ if (!this.registry.has(family)) {
18289
+ this.registry.set(family, new Map);
18290
+ }
18291
+ this.registry.get(family).set(vKey, font);
18292
+ for (const key of this.metricsCache.keys()) {
18293
+ if (key.startsWith(family)) {
18294
+ this.metricsCache.delete(key);
18295
+ }
18296
+ }
18260
18297
  if (sourcePath) {
18261
18298
  registerCanvasFont2(sourcePath, family);
18262
18299
  }
@@ -18264,22 +18301,88 @@ class FontMetricsProvider {
18264
18301
  async waitForPendingRegistrations() {
18265
18302
  await Promise.all(this.pendingRegistrations);
18266
18303
  }
18304
+ getRegisteredFamilies() {
18305
+ return Array.from(this.registry.keys());
18306
+ }
18307
+ getFamilyVariants(family) {
18308
+ const variants = this.registry.get(family);
18309
+ return variants ? Array.from(variants.keys()) : [];
18310
+ }
18267
18311
  getFont(family, weight = "normal", style = "normal") {
18268
- const key = cacheKey2(family, weight, style);
18269
- return this.cache.get(key);
18312
+ const resolved = this._resolveFont(family, weight, style);
18313
+ if (!resolved)
18314
+ return;
18315
+ return resolved.font;
18316
+ }
18317
+ _resolveFont(family, weight, style) {
18318
+ const variants = this.registry.get(family);
18319
+ if (!variants || variants.size === 0)
18320
+ return null;
18321
+ const normalisedW = normaliseWeight(weight);
18322
+ const normalisedS = style;
18323
+ let key = variantKey(normalisedW, normalisedS);
18324
+ let font = variants.get(key);
18325
+ if (font)
18326
+ return { font, resolvedWeight: normalisedW, resolvedStyle: normalisedS };
18327
+ if (normalisedS === "italic") {
18328
+ key = variantKey(normalisedW, "normal");
18329
+ font = variants.get(key);
18330
+ if (font)
18331
+ return { font, resolvedWeight: normalisedW, resolvedStyle: "normal" };
18332
+ }
18333
+ const sameStyleWeights = [];
18334
+ for (const vKey of variants.keys()) {
18335
+ const [_w, _s] = vKey.split("_");
18336
+ if (_s === normalisedS) {
18337
+ sameStyleWeights.push(weightToNumber(_w));
18338
+ }
18339
+ }
18340
+ const sameStyleNearest = nearestWeight(sameStyleWeights, weightToNumber(normalisedW));
18341
+ if (sameStyleNearest !== null) {
18342
+ key = variantKey(String(sameStyleNearest), normalisedS);
18343
+ font = variants.get(key);
18344
+ if (font)
18345
+ return { font, resolvedWeight: String(sameStyleNearest), resolvedStyle: normalisedS };
18346
+ }
18347
+ if (normalisedS === "italic") {
18348
+ const normalWeights = [];
18349
+ for (const vKey of variants.keys()) {
18350
+ const [_w, _s] = vKey.split("_");
18351
+ if (_s === "normal") {
18352
+ normalWeights.push(weightToNumber(_w));
18353
+ }
18354
+ }
18355
+ const normalNearest = nearestWeight(normalWeights, weightToNumber(normalisedW));
18356
+ if (normalNearest !== null) {
18357
+ key = variantKey(String(normalNearest), "normal");
18358
+ font = variants.get(key);
18359
+ if (font)
18360
+ return { font, resolvedWeight: String(normalNearest), resolvedStyle: "normal" };
18361
+ }
18362
+ }
18363
+ const firstKey = variants.keys().next().value;
18364
+ if (firstKey) {
18365
+ font = variants.get(firstKey);
18366
+ if (font) {
18367
+ const [_w, _s] = firstKey.split("_");
18368
+ return { font, resolvedWeight: _w, resolvedStyle: _s };
18369
+ }
18370
+ }
18371
+ return null;
18270
18372
  }
18271
18373
  getMetrics(fontFamily, fontSize, weight = "normal", style = "normal") {
18272
18374
  const _process2 = typeof globalThis !== "undefined" ? globalThis.process : undefined;
18273
18375
  if (this.pendingRegistrations.size > 0 && _process2?.env?.NODE_ENV !== "production") {
18274
18376
  console.warn("[vyaz] getMetrics() called while registerFont() promises are still pending. Wait for registerFont() to resolve before layout to avoid inaccurate metrics. Use fontMetricsProvider.waitForPendingRegistrations() if needed.");
18275
18377
  }
18276
- const key = cacheKey2(fontFamily, weight, style);
18277
- const metricsKey = `${key}_${fontSize}_${this.mode}`;
18378
+ const normalisedW = normaliseWeight(weight);
18379
+ const metricsKey = `${fontFamily}_${normalisedW}_${style}_${fontSize}_${this.mode}`;
18278
18380
  const cached = this.metricsCache.get(metricsKey);
18279
18381
  if (cached)
18280
18382
  return cached;
18281
- const font = this.cache.get(key);
18282
- if (font) {
18383
+ const resolved = this._resolveFont(fontFamily, weight, style);
18384
+ if (resolved) {
18385
+ const font = resolved.font;
18283
18386
  const scale = fontSize / font.unitsPerEm;
18284
18387
  let ascent;
18285
18388
  let descent;
@@ -18303,7 +18406,7 @@ class FontMetricsProvider {
18303
18406
  this.metricsCache.set(metricsKey, metrics);
18304
18407
  return metrics;
18305
18408
  }
18306
- if (this.cache.size > 0) {
18409
+ if (this.registry.has(fontFamily)) {
18307
18410
  throw new FontNotFoundError(fontFamily, weight, style);
18308
18411
  }
18309
18412
  if (typeof document !== "undefined") {
@@ -24368,15 +24471,15 @@ function isLineStartCursor(cursor) {
24368
24471
  return cursor.segmentIndex === 0 && cursor.graphemeIndex === 0;
24369
24472
  }
24370
24473
  function getCollapsedSpaceWidth(font, letterSpacing, cache) {
24371
- const cacheKey3 = `${font}\x00${letterSpacing}`;
24372
- const cached = cache.get(cacheKey3);
24474
+ const cacheKey2 = `${font}\x00${letterSpacing}`;
24475
+ const cached = cache.get(cacheKey2);
24373
24476
  if (cached !== undefined)
24374
24477
  return cached;
24375
24478
  const options = letterSpacing === 0 ? undefined : { letterSpacing };
24376
24479
  const joinedWidth = measureNaturalWidth(prepareWithSegments("A A", font, options));
24377
24480
  const compactWidth = measureNaturalWidth(prepareWithSegments("AA", font, options));
24378
24481
  const collapsedWidth = Math.max(0, joinedWidth - compactWidth);
24379
- cache.set(cacheKey3, collapsedWidth);
24482
+ cache.set(cacheKey2, collapsedWidth);
24380
24483
  return collapsedWidth;
24381
24484
  }
24382
24485
  function prepareWholeItemLine(prepared) {
@@ -24621,11 +24724,11 @@ class ParagraphLayoutEngine {
24621
24724
  layout(paragraph, maxWidth, yOffset = 0, fontProvider, listStyle, listIndex, listMarkerWidth) {
24622
24725
  const provider = fontProvider || fontMetricsProvider;
24623
24726
  const items = compileParagraph(paragraph);
24624
- const cacheKey3 = JSON.stringify(paragraph);
24625
- let prepared = this.preparedCache.get(cacheKey3);
24727
+ const cacheKey2 = JSON.stringify(paragraph);
24728
+ let prepared = this.preparedCache.get(cacheKey2);
24626
24729
  if (!prepared) {
24627
24730
  prepared = prepareRichInline(items);
24628
- this.preparedCache.set(cacheKey3, prepared);
24731
+ this.preparedCache.set(cacheKey2, prepared);
24629
24732
  }
24630
24733
  const effectiveMaxWidth = paragraph.style.whiteSpace === "nowrap" ? Infinity : maxWidth;
24631
24734
  const pretextLines = [];
package/dist/index.js CHANGED
@@ -497,12 +497,31 @@ function normaliseWeight(weight) {
497
497
  return mapped;
498
498
  return weight;
499
499
  }
500
- function cacheKey2(family, weight, style) {
501
- return `${family}_${normaliseWeight(weight)}_${style}`;
500
+ function weightToNumber(weight) {
501
+ const num = parseInt(weight, 10);
502
+ return isNaN(num) ? 400 : num;
503
+ }
504
+ function variantKey(weight, style) {
505
+ return `${normaliseWeight(weight)}_${style}`;
506
+ }
507
+ function nearestWeight(registeredWeights, requested) {
508
+ if (registeredWeights.length === 0)
509
+ return null;
510
+ let best = registeredWeights[0];
511
+ let bestDist = Math.abs(best - requested);
512
+ for (let i = 1;i < registeredWeights.length; i++) {
513
+ const w = registeredWeights[i];
514
+ const dist = Math.abs(w - requested);
515
+ if (dist < bestDist || dist === bestDist && w > best) {
516
+ best = w;
517
+ bestDist = dist;
518
+ }
519
+ }
520
+ return best;
502
521
  }
503
522
 
504
523
  class FontMetricsProvider {
505
- cache = new Map;
524
+ registry = new Map;
506
525
  metricsCache = new Map;
507
526
  mode = "browser";
508
527
  pendingRegistrations = new Set;
@@ -526,7 +545,7 @@ class FontMetricsProvider {
526
545
  this.mode = mode;
527
546
  this.metricsCache.clear();
528
547
  if (mode === "office") {
529
- enableOfficeTextMeasure(this.cache);
548
+ enableOfficeTextMeasure(this._flattenCache());
530
549
  } else {
531
550
  disableOfficeTextMeasure();
532
551
  }
@@ -534,6 +553,15 @@ class FontMetricsProvider {
534
553
  getMode() {
535
554
  return this.mode;
536
555
  }
556
+ _flattenCache() {
557
+ const flat = new Map;
558
+ for (const [family, variants] of this.registry) {
559
+ for (const [vKey, font] of variants) {
560
+ flat.set(`${family}_${vKey}`, font);
561
+ }
562
+ }
563
+ return flat;
564
+ }
537
565
  async registerFont(family, options, source, sourcePath) {
538
566
  const promise = this._registerFontInternal(family, options, source, sourcePath);
539
567
  this.pendingRegistrations.add(promise);
@@ -551,9 +579,18 @@ class FontMetricsProvider {
551
579
  source = await getFontBuffer2(source);
552
580
  }
553
581
  const font = await createFontFace2(source);
554
- const key = cacheKey2(family, options.weight || "normal", options.style || "normal");
555
- this.cache.set(key, font);
556
- this.metricsCache.delete(key);
582
+ const w = options.weight || "normal";
583
+ const s = options.style || "normal";
584
+ const vKey = variantKey(w, s);
585
+ if (!this.registry.has(family)) {
586
+ this.registry.set(family, new Map);
587
+ }
588
+ this.registry.get(family).set(vKey, font);
589
+ for (const key of this.metricsCache.keys()) {
590
+ if (key.startsWith(family)) {
591
+ this.metricsCache.delete(key);
592
+ }
593
+ }
557
594
  if (sourcePath) {
558
595
  registerCanvasFont2(sourcePath, family);
559
596
  }
@@ -561,22 +598,88 @@ class FontMetricsProvider {
561
598
  async waitForPendingRegistrations() {
562
599
  await Promise.all(this.pendingRegistrations);
563
600
  }
601
+ getRegisteredFamilies() {
602
+ return Array.from(this.registry.keys());
603
+ }
604
+ getFamilyVariants(family) {
605
+ const variants = this.registry.get(family);
606
+ return variants ? Array.from(variants.keys()) : [];
607
+ }
564
608
  getFont(family, weight = "normal", style = "normal") {
565
- const key = cacheKey2(family, weight, style);
566
- return this.cache.get(key);
609
+ const resolved = this._resolveFont(family, weight, style);
610
+ if (!resolved)
611
+ return;
612
+ return resolved.font;
613
+ }
614
+ _resolveFont(family, weight, style) {
615
+ const variants = this.registry.get(family);
616
+ if (!variants || variants.size === 0)
617
+ return null;
618
+ const normalisedW = normaliseWeight(weight);
619
+ const normalisedS = style;
620
+ let key = variantKey(normalisedW, normalisedS);
621
+ let font = variants.get(key);
622
+ if (font)
623
+ return { font, resolvedWeight: normalisedW, resolvedStyle: normalisedS };
624
+ if (normalisedS === "italic") {
625
+ key = variantKey(normalisedW, "normal");
626
+ font = variants.get(key);
627
+ if (font)
628
+ return { font, resolvedWeight: normalisedW, resolvedStyle: "normal" };
629
+ }
630
+ const sameStyleWeights = [];
631
+ for (const vKey of variants.keys()) {
632
+ const [_w, _s] = vKey.split("_");
633
+ if (_s === normalisedS) {
634
+ sameStyleWeights.push(weightToNumber(_w));
635
+ }
636
+ }
637
+ const sameStyleNearest = nearestWeight(sameStyleWeights, weightToNumber(normalisedW));
638
+ if (sameStyleNearest !== null) {
639
+ key = variantKey(String(sameStyleNearest), normalisedS);
640
+ font = variants.get(key);
641
+ if (font)
642
+ return { font, resolvedWeight: String(sameStyleNearest), resolvedStyle: normalisedS };
643
+ }
644
+ if (normalisedS === "italic") {
645
+ const normalWeights = [];
646
+ for (const vKey of variants.keys()) {
647
+ const [_w, _s] = vKey.split("_");
648
+ if (_s === "normal") {
649
+ normalWeights.push(weightToNumber(_w));
650
+ }
651
+ }
652
+ const normalNearest = nearestWeight(normalWeights, weightToNumber(normalisedW));
653
+ if (normalNearest !== null) {
654
+ key = variantKey(String(normalNearest), "normal");
655
+ font = variants.get(key);
656
+ if (font)
657
+ return { font, resolvedWeight: String(normalNearest), resolvedStyle: "normal" };
658
+ }
659
+ }
660
+ const firstKey = variants.keys().next().value;
661
+ if (firstKey) {
662
+ font = variants.get(firstKey);
663
+ if (font) {
664
+ const [_w, _s] = firstKey.split("_");
665
+ return { font, resolvedWeight: _w, resolvedStyle: _s };
666
+ }
667
+ }
668
+ return null;
567
669
  }
568
670
  getMetrics(fontFamily, fontSize, weight = "normal", style = "normal") {
569
671
  const _process2 = typeof globalThis !== "undefined" ? globalThis.process : undefined;
570
672
  if (this.pendingRegistrations.size > 0 && _process2?.env?.NODE_ENV !== "production") {
571
673
  console.warn("[vyaz] getMetrics() called while registerFont() promises are still pending. Wait for registerFont() to resolve before layout to avoid inaccurate metrics. Use fontMetricsProvider.waitForPendingRegistrations() if needed.");
572
674
  }
573
- const key = cacheKey2(fontFamily, weight, style);
574
- const metricsKey = `${key}_${fontSize}_${this.mode}`;
675
+ const normalisedW = normaliseWeight(weight);
676
+ const metricsKey = `${fontFamily}_${normalisedW}_${style}_${fontSize}_${this.mode}`;
575
677
  const cached = this.metricsCache.get(metricsKey);
576
678
  if (cached)
577
679
  return cached;
578
- const font = this.cache.get(key);
579
- if (font) {
680
+ const resolved = this._resolveFont(fontFamily, weight, style);
681
+ if (resolved) {
682
+ const font = resolved.font;
580
683
  const scale = fontSize / font.unitsPerEm;
581
684
  let ascent;
582
685
  let descent;
@@ -600,7 +703,7 @@ class FontMetricsProvider {
600
703
  this.metricsCache.set(metricsKey, metrics);
601
704
  return metrics;
602
705
  }
603
- if (this.cache.size > 0) {
706
+ if (this.registry.has(fontFamily)) {
604
707
  throw new FontNotFoundError(fontFamily, weight, style);
605
708
  }
606
709
  if (typeof document !== "undefined") {
@@ -1170,11 +1273,11 @@ class ParagraphLayoutEngine {
1170
1273
  layout(paragraph, maxWidth, yOffset = 0, fontProvider, listStyle, listIndex, listMarkerWidth) {
1171
1274
  const provider = fontProvider || fontMetricsProvider;
1172
1275
  const items = compileParagraph(paragraph);
1173
- const cacheKey3 = JSON.stringify(paragraph);
1174
- let prepared = this.preparedCache.get(cacheKey3);
1276
+ const cacheKey2 = JSON.stringify(paragraph);
1277
+ let prepared = this.preparedCache.get(cacheKey2);
1175
1278
  if (!prepared) {
1176
1279
  prepared = prepareRichInline(items);
1177
- this.preparedCache.set(cacheKey3, prepared);
1280
+ this.preparedCache.set(cacheKey2, prepared);
1178
1281
  }
1179
1282
  const effectiveMaxWidth = paragraph.style.whiteSpace === "nowrap" ? Infinity : maxWidth;
1180
1283
  const pretextLines = [];
@@ -2,63 +2,69 @@
2
2
  * FontMetricsProvider.ts — isomorphic font metrics provider.
3
3
  *
4
4
  * Strategy (priority):
5
- * 1. FontEngine (fontkit) — from registered buffer
6
- * - 'browser' mode: hhea.ascender / hhea.descender
7
- * - 'office' mode: OS/2.usWinAscent / OS/2.usWinDescent
5
+ * 1. FontEngine (fontkit) — from registered buffer, with smart weight fallback
8
6
  * 2. Canvas TextMetrics (browser fallback when fontkit unavailable)
9
7
  *
10
- * Uses FontEngine as the single entry point for all fontkit operations.
8
+ * Key features:
9
+ * - Nested registry: family → variants (weight + style)
10
+ * - Smart weight fallback: if exact weight not found, picks closest
11
+ * - Style fallback: if exact style not found, falls back to 'normal'
12
+ * - Tracks pending registrations to warn about race conditions
13
+ * - Reusable off-screen canvas for Canvas TextMetrics fallback
11
14
  */
12
15
  import type { FontMetrics, IFontMetricsProvider } from '../types/FontTypes.js';
13
16
  import type { FontFace } from './FontEngine.js';
14
17
  /**
15
18
  * Factor used when a glyph is not found in the font.
16
19
  * Multiplied by fontSize to estimate the missing glyph width.
17
- * Used across all measurement code paths (ParagraphLayoutEngine, canvas-polyfill).
18
20
  */
19
21
  export declare const MISSING_GLYPH_FACTOR = 0.5;
20
22
  export declare class FontMetricsProvider implements IFontMetricsProvider {
21
- /** Map<string, FontFace> — font engine font face cache */
22
- private cache;
23
+ /**
24
+ * Nested registry: family → variantKey → FontFace.
25
+ * Example:
26
+ * "Roboto" → { "400_normal": FontFace, "700_normal": FontFace, "400_italic": FontFace }
27
+ */
28
+ private registry;
29
+ /** Metrics cache keyed by variantKey_fontSize_mode */
23
30
  private metricsCache;
24
31
  private mode;
25
- /** Set of in-flight registerFont() promises for race-condition guarding */
26
32
  private pendingRegistrations;
27
33
  private _measureCanvas;
28
34
  private _measureCtx;
29
- /** Get or create a reusable canvas context for Canvas TextMetrics. */
30
35
  private _getMeasureContext;
31
36
  setMode(mode: 'browser' | 'office'): void;
32
37
  getMode(): 'browser' | 'office';
33
38
  /**
34
- * Register a binary font for use with fontkit.
35
- *
36
- * In both Node.js and browser the font is loaded via FontEngine.
37
- * In the browser the caller must provide font bytes (e.g. fetched via
38
- * `getFontBuffer()` from `../utils/font.js`).
39
- *
40
- * Tracks pending registrations to detect race conditions where
41
- * getMetrics() is called before registration completes.
42
- *
43
- * @param source Font file bytes (ArrayBuffer / Uint8Array), or a URL string
44
- * @param sourcePath Optional filesystem path (used for @napi-rs/canvas in Node.js)
39
+ * Flatten the nested registry into a single map for office mode.
40
+ * Office mode needs key → FontFace lookup by family_weight_style.
45
41
  */
42
+ private _flattenCache;
46
43
  registerFont(family: string, options: {
47
44
  weight?: string;
48
45
  style?: string;
49
46
  }, source: string | ArrayBuffer | Uint8Array, sourcePath?: string): Promise<void>;
50
- /** Internal registration logic — not tracked, exposed for direct use if needed. */
51
47
  private _registerFontInternal;
48
+ waitForPendingRegistrations(): Promise<void>;
52
49
  /**
53
- * Wait for all in-flight font registrations to complete.
54
- * Useful after a batch of registerFont() calls before layout.
50
+ * List all families registered in the provider.
55
51
  */
56
- waitForPendingRegistrations(): Promise<void>;
52
+ getRegisteredFamilies(): string[];
57
53
  /**
58
- * Get font engine FontFace object for per-character calculations.
59
- * Returns undefined if font is not registered.
54
+ * Get all variant keys registered for a given family.
55
+ * Returns empty array if family not found.
56
+ */
57
+ getFamilyVariants(family: string): string[];
58
+ /**
59
+ * Get font engine FontFace for per-character calculations.
60
+ * Uses the same smart fallback logic as getMetrics().
60
61
  */
61
62
  getFont(family: string, weight?: string, style?: string): FontFace | undefined;
63
+ /**
64
+ * Resolve a font request with fallback.
65
+ * Returns { font, resolvedWeight, resolvedStyle } or null.
66
+ */
67
+ private _resolveFont;
62
68
  getMetrics(fontFamily: string, fontSize: number, weight?: string, style?: string): FontMetrics;
63
69
  }
64
70
  /** Singleton */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vyaz/core",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",