@symbiote-native/font 0.1.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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +210 -0
  3. package/build/angular/index.d.ts +2 -0
  4. package/build/angular/index.js +4 -0
  5. package/build/angular/services/fonts.service/index.d.ts +8 -0
  6. package/build/angular/services/fonts.service/index.js +64 -0
  7. package/build/core/font-loader.d.ts +4 -0
  8. package/build/core/font-loader.js +30 -0
  9. package/build/core/font-utils.d.ts +14 -0
  10. package/build/core/font-utils.js +16 -0
  11. package/build/core/font.d.ts +11 -0
  12. package/build/core/font.js +94 -0
  13. package/build/core/index.d.ts +5 -0
  14. package/build/core/index.js +3 -0
  15. package/build/core/memory.d.ts +6 -0
  16. package/build/core/memory.js +30 -0
  17. package/build/core/native-modules.d.ts +24 -0
  18. package/build/core/native-modules.js +7 -0
  19. package/build/core/types.d.ts +18 -0
  20. package/build/core/types.js +9 -0
  21. package/build/react/hooks/use-fonts/index.d.ts +2 -0
  22. package/build/react/hooks/use-fonts/index.js +28 -0
  23. package/build/react/index.d.ts +2 -0
  24. package/build/react/index.js +3 -0
  25. package/build/solid/index.d.ts +2 -0
  26. package/build/solid/index.js +5 -0
  27. package/build/solid/primitives/create-fonts.d.ts +6 -0
  28. package/build/solid/primitives/create-fonts.js +12 -0
  29. package/build/svelte/index.d.ts +2 -0
  30. package/build/svelte/index.js +5 -0
  31. package/build/svelte/runes/use-fonts.svelte.d.ts +5 -0
  32. package/build/svelte/runes/use-fonts.svelte.js +24 -0
  33. package/build/vue/composables/use-fonts/index.d.ts +6 -0
  34. package/build/vue/composables/use-fonts/index.js +18 -0
  35. package/build/vue/index.d.ts +2 -0
  36. package/build/vue/index.js +3 -0
  37. package/build-ngc/angular/index.d.ts +2 -0
  38. package/build-ngc/angular/index.js +5 -0
  39. package/build-ngc/angular/index.js.map +1 -0
  40. package/build-ngc/angular/services/fonts.service/index.d.ts +11 -0
  41. package/build-ngc/angular/services/fonts.service/index.js +24 -0
  42. package/build-ngc/angular/services/fonts.service/index.js.map +1 -0
  43. package/build-ngc/core/font-loader.d.ts +4 -0
  44. package/build-ngc/core/font-loader.js +31 -0
  45. package/build-ngc/core/font-loader.js.map +1 -0
  46. package/build-ngc/core/font-utils.d.ts +14 -0
  47. package/build-ngc/core/font-utils.js +17 -0
  48. package/build-ngc/core/font-utils.js.map +1 -0
  49. package/build-ngc/core/font.d.ts +11 -0
  50. package/build-ngc/core/font.js +95 -0
  51. package/build-ngc/core/font.js.map +1 -0
  52. package/build-ngc/core/index.d.ts +5 -0
  53. package/build-ngc/core/index.js +4 -0
  54. package/build-ngc/core/index.js.map +1 -0
  55. package/build-ngc/core/memory.d.ts +6 -0
  56. package/build-ngc/core/memory.js +31 -0
  57. package/build-ngc/core/memory.js.map +1 -0
  58. package/build-ngc/core/native-modules.d.ts +24 -0
  59. package/build-ngc/core/native-modules.js +8 -0
  60. package/build-ngc/core/native-modules.js.map +1 -0
  61. package/build-ngc/core/types.d.ts +18 -0
  62. package/build-ngc/core/types.js +10 -0
  63. package/build-ngc/core/types.js.map +1 -0
  64. package/native-link.json +17 -0
  65. package/package.json +151 -0
  66. package/src/angular/index.ts +4 -0
  67. package/src/angular/services/fonts.service/index.ts +21 -0
  68. package/src/core/font-loader.ts +44 -0
  69. package/src/core/font-utils.ts +39 -0
  70. package/src/core/font.ts +150 -0
  71. package/src/core/index.ts +18 -0
  72. package/src/core/memory.ts +39 -0
  73. package/src/core/native-modules.ts +45 -0
  74. package/src/core/types.ts +25 -0
  75. package/src/react/hooks/use-fonts/index.ts +36 -0
  76. package/src/react/index.ts +4 -0
  77. package/src/solid/index.ts +6 -0
  78. package/src/solid/primitives/create-fonts.ts +18 -0
  79. package/src/svelte/index.ts +6 -0
  80. package/src/svelte/runes/use-fonts.svelte.ts +30 -0
  81. package/src/svelte/svelte-ambient.d.ts +3 -0
  82. package/src/vue/composables/use-fonts/index.ts +24 -0
  83. package/src/vue/index.ts +4 -0
@@ -0,0 +1,5 @@
1
+ // @symbiote-native/font/solid: the Solid entry over the framework-agnostic core — mirrors the
2
+ // lifecycle-bucket naming convention of adapters/solid/src/primitives (never `hooks`/
3
+ // `composables`/`runes`, those are React's, Vue's and Svelte's terms).
4
+ export { createFonts } from './primitives/create-fonts.js';
5
+ export * from '../core/index.js';
@@ -0,0 +1,6 @@
1
+ import { type Accessor } from 'solid-js';
2
+ import { type FontSource } from '../../core';
3
+ export declare function createFonts(map: string | Record<string, FontSource>): {
4
+ loaded: Accessor<boolean>;
5
+ error: Accessor<Error | null>;
6
+ };
@@ -0,0 +1,12 @@
1
+ // createFonts — the Solid twin of React's useFonts hook, over the framework-agnostic core
2
+ // (core/font.ts). Loads once from the primitive body, matching upstream's own contract.
3
+ import { createSignal } from 'solid-js';
4
+ import { isFontMapLoaded, loadAsync } from '../../core/index.js';
5
+ export function createFonts(map) {
6
+ const [loaded, setLoaded] = createSignal(isFontMapLoaded(map));
7
+ const [error, setError] = createSignal(null);
8
+ loadAsync(map)
9
+ .then(() => setLoaded(true))
10
+ .catch(setError);
11
+ return { loaded, error };
12
+ }
@@ -0,0 +1,2 @@
1
+ export { useFonts } from './runes/use-fonts.svelte';
2
+ export * from '../core';
@@ -0,0 +1,5 @@
1
+ // @symbiote-native/font/svelte: the Svelte entry over the framework-agnostic core — mirrors the
2
+ // lifecycle-bucket naming convention of adapters/svelte/src/runes (never `hooks`/`composables`,
3
+ // those are React's and Vue's terms).
4
+ export { useFonts } from './runes/use-fonts.svelte';
5
+ export * from '../core/index.js';
@@ -0,0 +1,5 @@
1
+ import { type FontSource } from '../../core';
2
+ export declare function useFonts(map: string | Record<string, FontSource>): {
3
+ readonly loaded: boolean;
4
+ readonly error: Error | null;
5
+ };
@@ -0,0 +1,24 @@
1
+ // Svelte lifecycle wiring over the framework-agnostic core (core/font.ts). Loads once per
2
+ // mount, matching upstream's own useFonts contract (a changed font map is not reloaded).
3
+ import { isFontMapLoaded, loadAsync } from '../../core/index.js';
4
+ export function useFonts(map) {
5
+ let loaded = $state(isFontMapLoaded(map));
6
+ let error = $state(null);
7
+ $effect(() => {
8
+ loadAsync(map)
9
+ .then(() => {
10
+ loaded = true;
11
+ })
12
+ .catch((err) => {
13
+ error = err;
14
+ });
15
+ });
16
+ return {
17
+ get loaded() {
18
+ return loaded;
19
+ },
20
+ get error() {
21
+ return error;
22
+ },
23
+ };
24
+ }
@@ -0,0 +1,6 @@
1
+ import { type Ref } from '@vue/runtime-core';
2
+ import { type FontSource } from '../../../core';
3
+ export declare function useFonts(map: string | Record<string, FontSource>): {
4
+ loaded: Ref<boolean>;
5
+ error: Ref<Error | null>;
6
+ };
@@ -0,0 +1,18 @@
1
+ // Vue lifecycle wiring over the framework-agnostic core (core/font.ts). Loads once on mount,
2
+ // matching upstream's own useFonts contract (a changed font map prop is not reloaded).
3
+ import { onMounted, ref } from '@vue/runtime-core';
4
+ import { isFontMapLoaded, loadAsync } from '../../../core/index.js';
5
+ export function useFonts(map) {
6
+ const loaded = ref(isFontMapLoaded(map));
7
+ const error = ref(null);
8
+ onMounted(() => {
9
+ loadAsync(map)
10
+ .then(() => {
11
+ loaded.value = true;
12
+ })
13
+ .catch((err) => {
14
+ error.value = err;
15
+ });
16
+ });
17
+ return { loaded, error };
18
+ }
@@ -0,0 +1,2 @@
1
+ export { useFonts } from './composables/use-fonts';
2
+ export * from '../core';
@@ -0,0 +1,3 @@
1
+ // @symbiote-native/font/vue: the Vue entry over the framework-agnostic core.
2
+ export { useFonts } from './composables/use-fonts/index.js';
3
+ export * from '../core/index.js';
@@ -0,0 +1,2 @@
1
+ export { FontsService } from './services/fonts.service';
2
+ export * from '../core';
@@ -0,0 +1,5 @@
1
+ // FontsService is the Angular-only lifecycle half; the loading/caching logic all lives in
2
+ // core, shared with React/Vue/Svelte/Solid.
3
+ export { FontsService } from './services/fonts.service';
4
+ export * from '../core';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/angular/index.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,4CAA4C;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,cAAc,SAAS,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type Signal } from '@angular/core';
2
+ import { type FontSource } from '../../../core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FontsService {
5
+ connect(map: string | Record<string, FontSource>): {
6
+ loaded: Signal<boolean>;
7
+ error: Signal<Error | null>;
8
+ };
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<FontsService, never>;
10
+ static ɵprov: i0.ɵɵInjectableDeclaration<FontsService>;
11
+ }
@@ -0,0 +1,24 @@
1
+ import { Injectable, signal } from '@angular/core';
2
+ import { isFontMapLoaded, loadAsync } from '../../../core';
3
+ import * as i0 from "@angular/core";
4
+ // Angular twin of React's useFonts hook and Vue's useFonts composable — connect(map) returns
5
+ // a Signal pair, e.g. `readonly fonts = inject(FontsService).connect({ Inter: require('...') })`.
6
+ export class FontsService {
7
+ connect(map) {
8
+ const loaded = signal(isFontMapLoaded(map), /* @ts-ignore */
9
+ ...(ngDevMode ? [{ debugName: "loaded" }] : /* istanbul ignore next */ []));
10
+ const error = signal(null, /* @ts-ignore */
11
+ ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
12
+ loadAsync(map)
13
+ .then(() => loaded.set(true))
14
+ .catch((err) => error.set(err));
15
+ return { loaded: loaded.asReadonly(), error: error.asReadonly() };
16
+ }
17
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FontsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
18
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FontsService, providedIn: 'root' });
19
+ }
20
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FontsService, decorators: [{
21
+ type: Injectable,
22
+ args: [{ providedIn: 'root' }]
23
+ }] });
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/angular/services/fonts.service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,SAAS,EAAmB,MAAM,eAAe,CAAC;;AAE5E,6FAA6F;AAC7F,kGAAkG;AAElG,MAAM,OAAO,YAAY;IACvB,OAAO,CAAC,GAAwC;QAI9C,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC;mFAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAe,IAAI;kFAAC,CAAC;QAEzC,SAAS,CAAC,GAAG,CAAC;aACX,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aAC5B,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;IACpE,CAAC;uGAbU,YAAY;2GAAZ,YAAY,cADC,MAAM;;2FACnB,YAAY;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE"}
@@ -0,0 +1,4 @@
1
+ import { Asset } from '@symbiote-native/asset';
2
+ import type { FontResource, FontSource } from './types';
3
+ export declare function getAssetForSource(source: FontSource): Asset | FontResource;
4
+ export declare function loadSingleFontAsync(name: string, input: Asset | FontResource): Promise<void>;
@@ -0,0 +1,31 @@
1
+ // Ported from expo-font/src/FontLoader.ts (sdk-57), resolving through @symbiote-native/asset's
2
+ // Asset class (this repo's own expo-asset port) instead of importing expo-asset directly.
3
+ import { Asset } from '@symbiote-native/asset';
4
+ import { CodedError } from 'expo-modules-core';
5
+ import { expoFontLoader } from './native-modules';
6
+ export function getAssetForSource(source) {
7
+ if (source instanceof Asset) {
8
+ return source;
9
+ }
10
+ if (typeof source === 'string') {
11
+ return Asset.fromURI(source);
12
+ }
13
+ if (typeof source === 'number') {
14
+ return Asset.fromModule(source);
15
+ }
16
+ if (typeof source === 'object' && typeof source.uri !== 'undefined') {
17
+ return getAssetForSource(source.uri);
18
+ }
19
+ return source;
20
+ }
21
+ export async function loadSingleFontAsync(name, input) {
22
+ if (!(input instanceof Asset)) {
23
+ throw new CodedError('ERR_FONT_SOURCE', '`loadSingleFontAsync` expected a resource of type `Asset` from @symbiote-native/asset');
24
+ }
25
+ await input.downloadAsync();
26
+ if (!input.downloaded || !input.localUri) {
27
+ throw new CodedError('ERR_DOWNLOAD', `Failed to download asset for font "${name}"`);
28
+ }
29
+ await expoFontLoader.loadAsync(name, input.localUri);
30
+ }
31
+ //# sourceMappingURL=font-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-loader.js","sourceRoot":"","sources":["../../src/core/font-loader.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,0FAA0F;AAC1F,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;QACpE,OAAO,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,KAA2B;IAE3B,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,IAAI,UAAU,CAClB,cAAc,EACd,sCAAsC,IAAI,GAAG,CAC9C,CAAC;IACJ,CAAC;IACD,MAAM,cAAc,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type IRenderToImageOptions = {
2
+ fontFamily?: string;
3
+ size?: number;
4
+ color?: string;
5
+ lineHeight?: number;
6
+ };
7
+ export type IRenderToImageResult = {
8
+ uri: string;
9
+ width: number;
10
+ height: number;
11
+ scale: number;
12
+ };
13
+ /** @platform android @platform ios */
14
+ export declare function renderToImageAsync(glyphs: string, options?: IRenderToImageOptions): Promise<IRenderToImageResult>;
@@ -0,0 +1,17 @@
1
+ // Ported from expo-font/src/FontUtils.ts (sdk-57).
2
+ import { UnavailabilityError } from 'expo-modules-core';
3
+ import { processColor } from 'react-native';
4
+ import { expoFontUtils } from './native-modules';
5
+ /** @platform android @platform ios */
6
+ export async function renderToImageAsync(glyphs, options) {
7
+ if (!expoFontUtils) {
8
+ throw new UnavailabilityError('expo-font', 'ExpoFontUtils.renderToImageAsync');
9
+ }
10
+ return expoFontUtils.renderToImageAsync(glyphs, {
11
+ ...options,
12
+ color: options?.color
13
+ ? (processColor(options.color) ?? undefined)
14
+ : undefined,
15
+ });
16
+ }
17
+ //# sourceMappingURL=font-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font-utils.js","sourceRoot":"","sources":["../../src/core/font-utils.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAgBjD,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,OAA+B;IAE/B,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,mBAAmB,CAC3B,WAAW,EACX,kCAAkC,CACnC,CAAC;IACJ,CAAC;IAED,OAAO,aAAa,CAAC,kBAAkB,CAAC,MAAM,EAAE;QAC9C,GAAG,OAAO;QACV,KAAK,EAAE,OAAO,EAAE,KAAK;YACnB,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;YAC5C,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { FontSource, UnloadFontOptions } from './types';
2
+ export declare function isLoaded(fontFamily: string): boolean;
3
+ export declare function getLoadedFonts(): string[];
4
+ export declare function isLoading(fontFamily: string): boolean;
5
+ /** Shared seed check for every adapter's `useFonts`/`createFonts` lifecycle wrapper. */
6
+ export declare function isFontMapLoaded(map: string | Record<string, FontSource>): boolean;
7
+ export declare function loadAsync(fontFamilyOrFontMap: string | Record<string, FontSource>, source?: FontSource): Promise<void>;
8
+ /** Always throws on native — ExpoFontLoader has no unload method there, web-only upstream. */
9
+ export declare function unloadAllAsync(): Promise<void>;
10
+ /** Always throws on native — ExpoFontLoader has no unload method there, web-only upstream. */
11
+ export declare function unloadAsync(fontFamilyOrFontMap: string | Record<string, UnloadFontOptions>, options?: UnloadFontOptions): Promise<void>;
@@ -0,0 +1,95 @@
1
+ // Ported from expo-font/src/Font.ts (sdk-57), native-only — drops the web/server branches
2
+ // (isLoaded's web fallback, loadAsync's server pre-render pass, registerStaticFont).
3
+ import { CodedError, UnavailabilityError } from 'expo-modules-core';
4
+ import { getAssetForSource, loadSingleFontAsync } from './font-loader';
5
+ import { isLoadedNative, loadPromises, markLoaded, purgeCache, purgeFontFamilyFromCache, } from './memory';
6
+ import { expoFontLoader } from './native-modules';
7
+ export function isLoaded(fontFamily) {
8
+ return isLoadedNative(fontFamily);
9
+ }
10
+ export function getLoadedFonts() {
11
+ return expoFontLoader.getLoadedFonts();
12
+ }
13
+ export function isLoading(fontFamily) {
14
+ return fontFamily in loadPromises;
15
+ }
16
+ /** Shared seed check for every adapter's `useFonts`/`createFonts` lifecycle wrapper. */
17
+ export function isFontMapLoaded(map) {
18
+ if (typeof map === 'string') {
19
+ return isLoaded(map);
20
+ }
21
+ return Object.keys(map).every(fontFamily => isLoaded(fontFamily));
22
+ }
23
+ export function loadAsync(fontFamilyOrFontMap, source) {
24
+ if (typeof fontFamilyOrFontMap === 'object') {
25
+ if (source) {
26
+ return Promise.reject(new CodedError('ERR_FONT_API', `No fontFamily can be used for the provided source: ${String(source)}. The second argument of loadAsync() can only be used with a string value as the first argument.`));
27
+ }
28
+ const fontMap = fontFamilyOrFontMap;
29
+ const names = Object.keys(fontMap);
30
+ return Promise.all(names.map(name => loadFontInNamespaceAsync(name, fontMap[name]))).then(() => { });
31
+ }
32
+ return loadFontInNamespaceAsync(fontFamilyOrFontMap, source);
33
+ }
34
+ async function loadFontInNamespaceAsync(fontFamily, source) {
35
+ if (!source) {
36
+ throw new CodedError('ERR_FONT_SOURCE', `Cannot load null or undefined font source for fontFamily "${fontFamily}".`);
37
+ }
38
+ if (isLoaded(fontFamily)) {
39
+ return;
40
+ }
41
+ if (Object.hasOwn(loadPromises, fontFamily)) {
42
+ return loadPromises[fontFamily];
43
+ }
44
+ const asset = getAssetForSource(source);
45
+ loadPromises[fontFamily] = (async () => {
46
+ try {
47
+ await loadSingleFontAsync(fontFamily, asset);
48
+ markLoaded(fontFamily);
49
+ }
50
+ finally {
51
+ delete loadPromises[fontFamily];
52
+ }
53
+ })();
54
+ await loadPromises[fontFamily];
55
+ }
56
+ /** Always throws on native — ExpoFontLoader has no unload method there, web-only upstream. */
57
+ export async function unloadAllAsync() {
58
+ if (!expoFontLoader.unloadAllAsync) {
59
+ throw new UnavailabilityError('expo-font', 'unloadAllAsync');
60
+ }
61
+ if (Object.keys(loadPromises).length) {
62
+ throw new CodedError('ERR_UNLOAD', `Cannot unload fonts while they're still loading: ${Object.keys(loadPromises).join(', ')}`);
63
+ }
64
+ purgeCache();
65
+ await expoFontLoader.unloadAllAsync();
66
+ }
67
+ /** Always throws on native — ExpoFontLoader has no unload method there, web-only upstream. */
68
+ export async function unloadAsync(fontFamilyOrFontMap, options) {
69
+ if (!expoFontLoader.unloadAsync) {
70
+ throw new UnavailabilityError('expo-font', 'unloadAsync');
71
+ }
72
+ if (typeof fontFamilyOrFontMap === 'object') {
73
+ if (options) {
74
+ throw new CodedError('ERR_FONT_API', `No fontFamily can be used for the provided options: ${String(options)}. The second argument of unloadAsync() can only be used with a string value as the first argument.`);
75
+ }
76
+ const names = Object.keys(fontFamilyOrFontMap);
77
+ await Promise.all(names.map(name => unloadFontInNamespaceAsync(name, fontFamilyOrFontMap[name])));
78
+ return;
79
+ }
80
+ return unloadFontInNamespaceAsync(fontFamilyOrFontMap, options);
81
+ }
82
+ async function unloadFontInNamespaceAsync(fontFamily, options) {
83
+ if (!isLoaded(fontFamily)) {
84
+ return;
85
+ }
86
+ purgeFontFamilyFromCache(fontFamily);
87
+ if (!fontFamily) {
88
+ throw new CodedError('ERR_FONT_FAMILY', 'Cannot unload an empty name');
89
+ }
90
+ if (!expoFontLoader.unloadAsync) {
91
+ throw new UnavailabilityError('expo-font', 'unloadAsync');
92
+ }
93
+ await expoFontLoader.unloadAsync(fontFamily, options);
94
+ }
95
+ //# sourceMappingURL=font.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"font.js","sourceRoot":"","sources":["../../src/core/font.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { isLoaded, getLoadedFonts, isLoading, isFontMapLoaded, loadAsync, unloadAllAsync, unloadAsync, } from './font';
2
+ export { renderToImageAsync } from './font-utils';
3
+ export type { IRenderToImageOptions, IRenderToImageResult } from './font-utils';
4
+ export { FontDisplay } from './types';
5
+ export type { FontResource, FontSource, UnloadFontOptions, UseFontsResult, } from './types';
@@ -0,0 +1,4 @@
1
+ export { isLoaded, getLoadedFonts, isLoading, isFontMapLoaded, loadAsync, unloadAllAsync, unloadAsync, } from './font';
2
+ export { renderToImageAsync } from './font-utils';
3
+ export { FontDisplay } from './types';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,cAAc,EACd,SAAS,EACT,eAAe,EACf,SAAS,EACT,cAAc,EACd,WAAW,GACZ,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const loadPromises: Record<string, Promise<void>>;
2
+ export declare function markLoaded(fontFamily: string): void;
3
+ export declare function isLoadedInCache(fontFamily: string): boolean;
4
+ export declare function isLoadedNative(fontFamily: string): boolean;
5
+ export declare function purgeFontFamilyFromCache(fontFamily: string): void;
6
+ export declare function purgeCache(): void;
@@ -0,0 +1,31 @@
1
+ // Ported verbatim from expo-font/src/memory.ts (sdk-57) — no web/server branch to drop, this
2
+ // module was already native-agnostic.
3
+ import { expoFontLoader } from './native-modules';
4
+ export const loadPromises = {};
5
+ let cache = {};
6
+ export function markLoaded(fontFamily) {
7
+ cache[fontFamily] = true;
8
+ }
9
+ export function isLoadedInCache(fontFamily) {
10
+ return fontFamily in cache;
11
+ }
12
+ export function isLoadedNative(fontFamily) {
13
+ if (isLoadedInCache(fontFamily)) {
14
+ return true;
15
+ }
16
+ const loadedNativeFonts = expoFontLoader.getLoadedFonts();
17
+ if (!loadedNativeFonts?.length) {
18
+ return false;
19
+ }
20
+ loadedNativeFonts.forEach(font => {
21
+ cache[font] = true;
22
+ });
23
+ return fontFamily in cache;
24
+ }
25
+ export function purgeFontFamilyFromCache(fontFamily) {
26
+ delete cache[fontFamily];
27
+ }
28
+ export function purgeCache() {
29
+ cache = {};
30
+ }
31
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/core/memory.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,sCAAsC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,MAAM,YAAY,GAAkC,EAAE,CAAC;AAE9D,IAAI,KAAK,GAA4B,EAAE,CAAC;AAExC,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,KAAK,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO,UAAU,IAAI,KAAK,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,IAAI,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,iBAAiB,GAAG,cAAc,CAAC,cAAc,EAAE,CAAC;IAC1D,IAAI,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,IAAI,KAAK,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,UAAkB;IACzD,OAAO,KAAK,CAAC,UAAU,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,KAAK,GAAG,EAAE,CAAC;AACb,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { ProcessedColorValue } from 'react-native';
2
+ import type { UnloadFontOptions } from './types';
3
+ export type INativeFontLoaderModule = {
4
+ getLoadedFonts(): string[];
5
+ loadAsync(fontFamilyName: string, localUri: string): Promise<void>;
6
+ unloadAllAsync?(): Promise<void>;
7
+ unloadAsync?(fontFamilyName: string, options?: UnloadFontOptions): Promise<void>;
8
+ };
9
+ export type INativeRenderToImageOptions = {
10
+ fontFamily?: string;
11
+ size?: number;
12
+ color?: ProcessedColorValue;
13
+ lineHeight?: number;
14
+ };
15
+ export type INativeFontUtilsModule = {
16
+ renderToImageAsync(glyphs: string, options?: INativeRenderToImageOptions): Promise<{
17
+ uri: string;
18
+ width: number;
19
+ height: number;
20
+ scale: number;
21
+ }>;
22
+ };
23
+ export declare const expoFontLoader: INativeFontLoaderModule;
24
+ export declare const expoFontUtils: INativeFontUtilsModule | null;
@@ -0,0 +1,8 @@
1
+ import { requireNativeModule, requireOptionalNativeModule, } from 'expo-modules-core';
2
+ const EXPO_FONT_LOADER_MODULE_NAME = 'ExpoFontLoader';
3
+ const EXPO_FONT_UTILS_MODULE_NAME = 'ExpoFontUtils';
4
+ export const expoFontLoader = requireNativeModule(EXPO_FONT_LOADER_MODULE_NAME);
5
+ // Present on both iOS and Android upstream — still optional (matches upstream's own
6
+ // requireOptionalNativeModule) since only web ships without it.
7
+ export const expoFontUtils = requireOptionalNativeModule(EXPO_FONT_UTILS_MODULE_NAME);
8
+ //# sourceMappingURL=native-modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-modules.js","sourceRoot":"","sources":["../../src/core/native-modules.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AA6B3B,MAAM,4BAA4B,GAAG,gBAAgB,CAAC;AACtD,MAAM,2BAA2B,GAAG,eAAe,CAAC;AAEpD,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAC/C,4BAA4B,CAC7B,CAAC;AAEF,oFAAoF;AACpF,gEAAgE;AAChE,MAAM,CAAC,MAAM,aAAa,GACxB,2BAA2B,CACzB,2BAA2B,CAC5B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Asset } from '@symbiote-native/asset';
2
+ /** @platform web — has no effect on native, kept for API-surface parity with upstream. */
3
+ export declare enum FontDisplay {
4
+ AUTO = "auto",
5
+ SWAP = "swap",
6
+ BLOCK = "block",
7
+ FALLBACK = "fallback",
8
+ OPTIONAL = "optional"
9
+ }
10
+ export type FontResource = {
11
+ uri?: string | number;
12
+ display?: FontDisplay;
13
+ default?: string;
14
+ testString?: string;
15
+ };
16
+ export type FontSource = string | number | Asset | FontResource;
17
+ export type UnloadFontOptions = Pick<FontResource, 'display'>;
18
+ export type UseFontsResult = readonly [loaded: boolean, error: Error | null];
@@ -0,0 +1,10 @@
1
+ /** @platform web — has no effect on native, kept for API-surface parity with upstream. */
2
+ export var FontDisplay;
3
+ (function (FontDisplay) {
4
+ FontDisplay["AUTO"] = "auto";
5
+ FontDisplay["SWAP"] = "swap";
6
+ FontDisplay["BLOCK"] = "block";
7
+ FontDisplay["FALLBACK"] = "fallback";
8
+ FontDisplay["OPTIONAL"] = "optional";
9
+ })(FontDisplay || (FontDisplay = {}));
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAIA,0FAA0F;AAC1F,MAAM,CAAN,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,4BAAa,CAAA;IACb,8BAAe,CAAA;IACf,oCAAqB,CAAA;IACrB,oCAAqB,CAAA;AACvB,CAAC,EANW,WAAW,KAAX,WAAW,QAMtB"}
@@ -0,0 +1,17 @@
1
+ {
2
+ "android": {
3
+ "gradleProjectName": "expo-font",
4
+ "modules": [
5
+ {
6
+ "importPath": "expo.modules.font.FontLoaderModule",
7
+ "className": "FontLoaderModule",
8
+ "nativeName": "ExpoFontLoader"
9
+ },
10
+ {
11
+ "importPath": "expo.modules.font.FontUtilsModule",
12
+ "className": "FontUtilsModule",
13
+ "nativeName": "ExpoFontUtils"
14
+ }
15
+ ]
16
+ }
17
+ }