@glissade/core 0.13.0 → 0.14.0-pre.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/dist/i18n.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import { l as Timeline } from "./timeline.js";
2
+
3
+ //#region src/i18n.d.ts
4
+ /** A locale's id manifest: the message ids it declares (narrate owns producing it). */
5
+ interface LocaleManifest {
6
+ locale: string;
7
+ ids: readonly string[];
8
+ }
9
+ declare class ParityError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /**
13
+ * Assert every supplied locale declares the SAME id set — the cross-language
14
+ * analogue of `narration().require`. Throws a `ParityError` listing, per locale,
15
+ * every id that is MISSING (present in the union but not this locale) or EXTRA
16
+ * (present here but in no shared reference). A pure function of its inputs — no
17
+ * time, no filesystem. The reference set is the UNION of every locale's ids, so
18
+ * the report names each gap exactly once per affected locale.
19
+ *
20
+ * Ship-alone-able: the smallest blast radius of the four pieces. One manifest
21
+ * (or zero) is trivially in parity.
22
+ */
23
+ declare function requireParity(...manifests: LocaleManifest[]): void;
24
+ /** A flat message table: id → localized string (the `messages.<locale>.json` shape). */
25
+ type MessageTable = Record<string, string>;
26
+ interface LocalizeOptions {
27
+ /** the locale being resolved (carried for error context only; no behavior depends on it). */
28
+ locale: string;
29
+ }
30
+ declare class LocalizationError extends Error {
31
+ constructor(message: string);
32
+ }
33
+ /**
34
+ * Resolve a timeline document against a message `table`, returning a NEW doc
35
+ * (the input is never mutated). For every STRING track whose target node-id is a
36
+ * key in `table` — caption + narration-derived text tracks live in the doc as
37
+ * exactly these string tracks — every key's `value` is replaced with the table's
38
+ * localized string. Tracks whose node-id is absent from the table pass through
39
+ * untouched, byte-identical.
40
+ *
41
+ * Pure: no playhead, no time, no filesystem. The base-locale table (or an empty
42
+ * table) leaves the doc structurally identical to the input.
43
+ */
44
+ declare function localize(doc: Timeline, table: MessageTable, _opts: LocalizeOptions): Timeline;
45
+ /**
46
+ * Install the ambient message table consulted by `t()`. Called ONCE before
47
+ * scene construction (the render entry injects it from `--locale`). Pass
48
+ * `undefined` to clear it (the base-locale / no-flag path leaves it unset).
49
+ */
50
+ declare function setMessageTable(table: MessageTable | undefined): void;
51
+ /** The currently installed ambient message table (undefined when none is set). */
52
+ declare function getMessageTable(): MessageTable | undefined;
53
+ /**
54
+ * Resolve a free-standing message `id` against the ambient table — build-time
55
+ * sugar for static Text-node text (text that is NOT animated by a doc track,
56
+ * so `localize()` can't reach it): `new Text({ text: t('hero.title') })`.
57
+ *
58
+ * HARD-FAILS (throws) on an unknown id, mirroring `require()` — a stale or
59
+ * mistyped id is a build error, never a silent empty string. When NO ambient
60
+ * table is installed (the base / no-flag path), `t(id)` returns `id` verbatim,
61
+ * so an un-localized build renders its keys as authored and stays byte-identical.
62
+ */
63
+ declare function t(id: string): string;
64
+ //#endregion
65
+ export { LocaleManifest, LocalizationError, LocalizeOptions, MessageTable, ParityError, getMessageTable, localize, requireParity, setMessageTable, t };
package/dist/i18n.js ADDED
@@ -0,0 +1,111 @@
1
+ //#region src/i18n.ts
2
+ var ParityError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "ParityError";
6
+ }
7
+ };
8
+ /**
9
+ * Assert every supplied locale declares the SAME id set — the cross-language
10
+ * analogue of `narration().require`. Throws a `ParityError` listing, per locale,
11
+ * every id that is MISSING (present in the union but not this locale) or EXTRA
12
+ * (present here but in no shared reference). A pure function of its inputs — no
13
+ * time, no filesystem. The reference set is the UNION of every locale's ids, so
14
+ * the report names each gap exactly once per affected locale.
15
+ *
16
+ * Ship-alone-able: the smallest blast radius of the four pieces. One manifest
17
+ * (or zero) is trivially in parity.
18
+ */
19
+ function requireParity(...manifests) {
20
+ if (manifests.length < 2) return;
21
+ const union = /* @__PURE__ */ new Set();
22
+ for (const m of manifests) for (const id of m.ids) union.add(id);
23
+ const problems = [];
24
+ for (const m of manifests) {
25
+ const have = new Set(m.ids);
26
+ const missing = [...union].filter((id) => !have.has(id)).sort();
27
+ const extra = [...have].filter((id) => manifests.every((other) => other === m || !other.ids.includes(id))).sort();
28
+ if (missing.length > 0 || extra.length > 0) {
29
+ const parts = [];
30
+ if (missing.length > 0) parts.push(`missing ${missing.map((id) => `'${id}'`).join(", ")}`);
31
+ if (extra.length > 0) parts.push(`extra ${extra.map((id) => `'${id}'`).join(", ")}`);
32
+ problems.push(` ${m.locale}: ${parts.join("; ")}`);
33
+ }
34
+ }
35
+ if (problems.length > 0) throw new ParityError(`locale parity mismatch across ${manifests.length} locales:\n${problems.join("\n")}`);
36
+ }
37
+ var LocalizationError = class extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "LocalizationError";
41
+ }
42
+ };
43
+ /** The node-id of a track target ('<nodeId>/<prop.path>' → '<nodeId>'). */
44
+ function nodeIdOf(target) {
45
+ const slash = target.indexOf("/");
46
+ return slash >= 0 ? target.slice(0, slash) : target;
47
+ }
48
+ /**
49
+ * Resolve a timeline document against a message `table`, returning a NEW doc
50
+ * (the input is never mutated). For every STRING track whose target node-id is a
51
+ * key in `table` — caption + narration-derived text tracks live in the doc as
52
+ * exactly these string tracks — every key's `value` is replaced with the table's
53
+ * localized string. Tracks whose node-id is absent from the table pass through
54
+ * untouched, byte-identical.
55
+ *
56
+ * Pure: no playhead, no time, no filesystem. The base-locale table (or an empty
57
+ * table) leaves the doc structurally identical to the input.
58
+ */
59
+ function localize(doc, table, _opts) {
60
+ let changed = false;
61
+ const tracks = doc.tracks.map((tr) => {
62
+ if (tr.type !== "string") return tr;
63
+ const id = nodeIdOf(tr.target);
64
+ if (!(id in table)) return tr;
65
+ const localized = table[id];
66
+ changed = true;
67
+ return {
68
+ ...tr,
69
+ keys: tr.keys.map((k) => k.value === localized ? k : {
70
+ ...k,
71
+ value: localized
72
+ })
73
+ };
74
+ });
75
+ if (!changed) return { ...doc };
76
+ return {
77
+ ...doc,
78
+ tracks
79
+ };
80
+ }
81
+ let ambientTable;
82
+ /**
83
+ * Install the ambient message table consulted by `t()`. Called ONCE before
84
+ * scene construction (the render entry injects it from `--locale`). Pass
85
+ * `undefined` to clear it (the base-locale / no-flag path leaves it unset).
86
+ */
87
+ function setMessageTable(table) {
88
+ ambientTable = table;
89
+ }
90
+ /** The currently installed ambient message table (undefined when none is set). */
91
+ function getMessageTable() {
92
+ return ambientTable;
93
+ }
94
+ /**
95
+ * Resolve a free-standing message `id` against the ambient table — build-time
96
+ * sugar for static Text-node text (text that is NOT animated by a doc track,
97
+ * so `localize()` can't reach it): `new Text({ text: t('hero.title') })`.
98
+ *
99
+ * HARD-FAILS (throws) on an unknown id, mirroring `require()` — a stale or
100
+ * mistyped id is a build error, never a silent empty string. When NO ambient
101
+ * table is installed (the base / no-flag path), `t(id)` returns `id` verbatim,
102
+ * so an un-localized build renders its keys as authored and stays byte-identical.
103
+ */
104
+ function t(id) {
105
+ if (ambientTable === void 0) return id;
106
+ const value = ambientTable[id];
107
+ if (value === void 0) throw new LocalizationError(`t('${id}'): no message for id '${id}' in the active message table (have: ${Object.keys(ambientTable).map((k) => `'${k}'`).join(", ") || "<empty>"})`);
108
+ return value;
109
+ }
110
+ //#endregion
111
+ export { LocalizationError, ParityError, getMessageTable, localize, requireParity, setMessageTable, t };
package/dist/index.d.ts CHANGED
@@ -102,13 +102,19 @@ declare function setScheduler(next?: Scheduler): Scheduler;
102
102
  declare function batch<T>(fn: () => T): T;
103
103
  //#endregion
104
104
  //#region src/vec2Signal.d.ts
105
+ /** A scalar component signal carrying its bind-time type tag (§2.2). */
106
+ type Vec2Component = BindableSignal<number> & {
107
+ readonly expects: ValueTypeId;
108
+ };
105
109
  interface Vec2Signal extends ReadonlySignal<Vec2> {
106
- readonly x: BindableSignal<number>;
107
- readonly y: BindableSignal<number>;
110
+ readonly x: Vec2Component;
111
+ readonly y: Vec2Component;
108
112
  set(value: Vec2): void;
109
113
  /** Bind the compound level; component bindings on .x/.y override per component. */
110
114
  bindSource(fn: () => Vec2): void;
111
115
  unbindSource(): void;
116
+ /** Bind-time guard (§2.2): the compound accepts only a 'vec2' track. */
117
+ readonly expects: ValueTypeId;
112
118
  }
113
119
  declare function vec2Signal(initial: Vec2 | {
114
120
  x: number;
@@ -285,9 +291,30 @@ declare function createPlayhead(initial?: number): Playhead;
285
291
  declare class UnboundTargetError extends Error {
286
292
  constructor(target: string);
287
293
  }
294
+ /**
295
+ * A track's value type doesn't match the shape of the property it targets — the
296
+ * silent-NaN class (§2.2): e.g. a scalar `number` track bound to a `vec2` prop
297
+ * makes the compound a number, its `.x`/`.y` index it to `undefined`, and the
298
+ * node's matrix goes NaN — the node and its subtree vanish. Caught at BIND time
299
+ * (the track's type is known then), the precedent being UnboundTargetError:
300
+ * mismatched binds are build errors, not silent no-ops.
301
+ */
302
+ declare class BindTypeMismatchError extends Error {
303
+ readonly target: string;
304
+ readonly got: ValueTypeId;
305
+ /** The accepted type(s) — a single id, or the set a polymorphic prop (e.g. `fill`: color|paint) admits. */
306
+ readonly expected: ValueTypeId | readonly ValueTypeId[];
307
+ constructor(target: string, got: ValueTypeId, expected: ValueTypeId | readonly ValueTypeId[]);
308
+ }
288
309
  interface BindTarget {
289
310
  bindSource(fn: () => unknown): void;
290
311
  unbindSource(): void;
312
+ /**
313
+ * The value type this target accepts; a track of any other type is a bind
314
+ * error. An ARRAY for a polymorphic prop that admits more than one type
315
+ * (e.g. a Shape `fill` accepts both `color` and `paint`).
316
+ */
317
+ readonly expects: ValueTypeId | readonly ValueTypeId[];
291
318
  }
292
319
  /** Analytic value/velocity access to one bound target (v2 addendum §B.6). */
293
320
  interface CurveSampler {
@@ -360,4 +387,4 @@ interface CheckpointedSim {
360
387
  }
361
388
  declare function bakeCheckpointed<W, S = W>(cfg: CheckpointedBakeConfig<W, S>): CheckpointedSim;
362
389
  //#endregion
363
- export { type AssetRef, type AudioClip, type BakeConfig, BakeError, type BindTarget, type BindableSignal, type BoundTimeline, type CheckpointedBakeConfig, type CheckpointedSim, type ChildEntry, CircularDependencyError, ColorParseError, type ColorStop, type CompiledTimeline, type CoverageReport, type CurveSampler, DEFAULT_EASE, type DevWarning, type EaseSpec, type EasingFn, type Equals, type FontFaceRef, type FontMode, type FontRegistry, type FontUsage, FontValidationError, type GainEnvelope, type GradientInterpolation, type HandoffKind, type Json, type Key, type KeyOpts, type Marker, type MergeResult, type MeshInterpolation, type MeshPaint, type MeshPoint, type MissingGlyphs, type OkLab, type OrphanReason, type Paint, type PathContour, type PathValue, type Playhead, type Position, PositionError, type ReadonlySignal, type ResolvedFace, type RetargetSpring, type Rgba, type Rng, type Scheduler, type SidecarDoc, type SidecarDocV1, type SidecarOrphan, type SidecarTimelineEntry, type SidecarTrackEntry, SidecarVersionError, type Signal, type SignalOptions, type SpringConfig, type SpringEase, TARGET_PATH, type TargetCarrier, type Timeline, type TimelineBuilder, type TimelineInit, TimelineValidationError, type Track, TrackValidationError, type TweenOpts, type TweenTarget, UnboundTargetError, UnknownEasingError, UnknownValueTypeError, UnresolvableTargetError, type ValidateFontsOptions, type ValueType, type ValueTypeId, ValueTypeInferenceError, type Vec2, type Vec2Signal, WriteDuringEvaluationError, assignKeyIds, audioOffsetSamples, bake, bakeCheckpointed, batch, beginReadPhase, bindTimeline, booleanType, buildFontRegistry, buildTimeline, colorType, compileTimeline, computed, createPlayhead, cubicBezier, cubicBezierDerivative, deleteSidecarTrack, easingDerivatives, easings, emitDevWarning, emptySidecar, endReadPhase, evaluateAt, formatColor, getTimelineCallbacks, getValueType, hashKeys, inReadPhase, inferValueType, isDurationEditable, isEditableNodeId, isExemptFamily, key, lerpColor, mergeSidecar, mergeSidecarDetailed, migrateSidecar, namedEasing, normalizeEditedKeys, numberType, oklabToRgba, paintType, parseCmap, parseColor, pathType, random, registerValueType, resolveEase, resolveEaseDerivative, resolveTweenTarget, rgbaToOklab, sampleTrack, setDevWarning, setScheduler, setSidecarTrack, signal, spring, springEasing, springEasingDerivative, springPresets, springTo, stagger, stringType, synchronousScheduler, targetNodeId, timeline, track, untracked, validateFonts, validateTrack, vec2ArcType, vec2Equals, vec2Signal, vec2Type, velocityAt };
390
+ export { type AssetRef, type AudioClip, type BakeConfig, BakeError, type BindTarget, BindTypeMismatchError, type BindableSignal, type BoundTimeline, type CheckpointedBakeConfig, type CheckpointedSim, type ChildEntry, CircularDependencyError, ColorParseError, type ColorStop, type CompiledTimeline, type CoverageReport, type CurveSampler, DEFAULT_EASE, type DevWarning, type EaseSpec, type EasingFn, type Equals, type FontFaceRef, type FontMode, type FontRegistry, type FontUsage, FontValidationError, type GainEnvelope, type GradientInterpolation, type HandoffKind, type Json, type Key, type KeyOpts, type Marker, type MergeResult, type MeshInterpolation, type MeshPaint, type MeshPoint, type MissingGlyphs, type OkLab, type OrphanReason, type Paint, type PathContour, type PathValue, type Playhead, type Position, PositionError, type ReadonlySignal, type ResolvedFace, type RetargetSpring, type Rgba, type Rng, type Scheduler, type SidecarDoc, type SidecarDocV1, type SidecarOrphan, type SidecarTimelineEntry, type SidecarTrackEntry, SidecarVersionError, type Signal, type SignalOptions, type SpringConfig, type SpringEase, TARGET_PATH, type TargetCarrier, type Timeline, type TimelineBuilder, type TimelineInit, TimelineValidationError, type Track, TrackValidationError, type TweenOpts, type TweenTarget, UnboundTargetError, UnknownEasingError, UnknownValueTypeError, UnresolvableTargetError, type ValidateFontsOptions, type ValueType, type ValueTypeId, ValueTypeInferenceError, type Vec2, type Vec2Component, type Vec2Signal, WriteDuringEvaluationError, assignKeyIds, audioOffsetSamples, bake, bakeCheckpointed, batch, beginReadPhase, bindTimeline, booleanType, buildFontRegistry, buildTimeline, colorType, compileTimeline, computed, createPlayhead, cubicBezier, cubicBezierDerivative, deleteSidecarTrack, easingDerivatives, easings, emitDevWarning, emptySidecar, endReadPhase, evaluateAt, formatColor, getTimelineCallbacks, getValueType, hashKeys, inReadPhase, inferValueType, isDurationEditable, isEditableNodeId, isExemptFamily, key, lerpColor, mergeSidecar, mergeSidecarDetailed, migrateSidecar, namedEasing, normalizeEditedKeys, numberType, oklabToRgba, paintType, parseCmap, parseColor, pathType, random, registerValueType, resolveEase, resolveEaseDerivative, resolveTweenTarget, rgbaToOklab, sampleTrack, setDevWarning, setScheduler, setSidecarTrack, signal, spring, springEasing, springEasingDerivative, springPresets, springTo, stagger, stringType, synchronousScheduler, targetNodeId, timeline, track, untracked, validateFonts, validateTrack, vec2ArcType, vec2Equals, vec2Signal, vec2Type, velocityAt };
package/dist/index.js CHANGED
@@ -348,6 +348,8 @@ function vec2Signal(initial) {
348
348
  const [ix, iy] = Array.isArray(initial) ? initial : [initial.x, initial.y];
349
349
  const x = signal(ix);
350
350
  const y = signal(iy);
351
+ x.expects = "number";
352
+ y.expects = "number";
351
353
  const compound = signal(null, { equals: (a, b) => a === null || b === null ? a === b : a[0] === b[0] && a[1] === b[1] });
352
354
  const baseX = signal(ix);
353
355
  const baseY = signal(iy);
@@ -373,6 +375,7 @@ function vec2Signal(initial) {
373
375
  compound.unbindSource();
374
376
  compound.set(null);
375
377
  };
378
+ sig["expects"] = "vec2";
376
379
  Object.defineProperty(sig, "x", {
377
380
  value: x,
378
381
  enumerable: true
@@ -815,6 +818,30 @@ var UnboundTargetError = class extends Error {
815
818
  }
816
819
  };
817
820
  /**
821
+ * A track's value type doesn't match the shape of the property it targets — the
822
+ * silent-NaN class (§2.2): e.g. a scalar `number` track bound to a `vec2` prop
823
+ * makes the compound a number, its `.x`/`.y` index it to `undefined`, and the
824
+ * node's matrix goes NaN — the node and its subtree vanish. Caught at BIND time
825
+ * (the track's type is known then), the precedent being UnboundTargetError:
826
+ * mismatched binds are build errors, not silent no-ops.
827
+ */
828
+ var BindTypeMismatchError = class extends Error {
829
+ target;
830
+ got;
831
+ /** The accepted type(s) — a single id, or the set a polymorphic prop (e.g. `fill`: color|paint) admits. */
832
+ expected;
833
+ constructor(target, got, expected) {
834
+ const prop = target.slice(target.lastIndexOf("/") + 1);
835
+ const want = [expected].flat();
836
+ const hint = got === "number" && want.includes("vec2") ? `; target '${prop}.x'/'${prop}.y' or author a vec2 track` : "";
837
+ super(`track '${target}' is '${got}' but '${prop}' expects '${want.join("'|'")}' (would silently NaN evaluation)${hint}`);
838
+ this.target = target;
839
+ this.got = got;
840
+ this.name = "BindTypeMismatchError";
841
+ this.expected = expected;
842
+ }
843
+ };
844
+ /**
818
845
  * Bind a compiled timeline's tracks to property signals. `resolve` returns
819
846
  * the signal for a target path, or undefined — which is a compile-time-style
820
847
  * error (§2.2: unbound tracks are build errors, not silent no-ops).
@@ -825,6 +852,9 @@ function bindTimeline(compiled, resolve, playhead = createPlayhead()) {
825
852
  for (const [target, tr] of compiled.tracks) {
826
853
  const sig = resolve(target);
827
854
  if (!sig) throw new UnboundTargetError(target);
855
+ const got = tr.type;
856
+ const expects = sig.expects;
857
+ if (!(Array.isArray(expects) ? expects.includes(got) : got === expects)) throw new BindTypeMismatchError(target, got, expects);
828
858
  sig.bindSource(() => sampleTrack(tr, playhead()));
829
859
  bound.push(sig);
830
860
  samplers.set(target, {
@@ -974,4 +1004,4 @@ function bakeCheckpointed(cfg) {
974
1004
  };
975
1005
  }
976
1006
  //#endregion
977
- export { BakeError, CircularDependencyError, ColorParseError, DEFAULT_EASE, FontValidationError, PositionError, SidecarVersionError, TARGET_PATH, TimelineValidationError, TrackValidationError, UnboundTargetError, UnknownEasingError, UnknownValueTypeError, UnresolvableTargetError, ValueTypeInferenceError, WriteDuringEvaluationError, assignKeyIds, audioOffsetSamples, bake, bakeCheckpointed, batch, beginReadPhase, bindTimeline, booleanType, buildFontRegistry, buildTimeline, colorType, compileTimeline, computed, createPlayhead, cubicBezier, cubicBezierDerivative, deleteSidecarTrack, easingDerivatives, easings, emitDevWarning, emptySidecar, endReadPhase, evaluateAt, formatColor, getTimelineCallbacks, getValueType, hashKeys, inReadPhase, inferValueType, isDurationEditable, isEditableNodeId, isExemptFamily, key, lerpColor, mergeSidecar, mergeSidecarDetailed, migrateSidecar, namedEasing, normalizeEditedKeys, numberType, oklabToRgba, paintType, parseCmap, parseColor, pathType, random, registerValueType, resolveEase, resolveEaseDerivative, resolveTweenTarget, rgbaToOklab, sampleTrack, setDevWarning, setScheduler, setSidecarTrack, signal, spring, springEasing, springEasingDerivative, springPresets, springTo, stagger, stringType, synchronousScheduler, targetNodeId, timeline, track, untracked, validateFonts, validateTrack, vec2ArcType, vec2Equals, vec2Signal, vec2Type, velocityAt };
1007
+ export { BakeError, BindTypeMismatchError, CircularDependencyError, ColorParseError, DEFAULT_EASE, FontValidationError, PositionError, SidecarVersionError, TARGET_PATH, TimelineValidationError, TrackValidationError, UnboundTargetError, UnknownEasingError, UnknownValueTypeError, UnresolvableTargetError, ValueTypeInferenceError, WriteDuringEvaluationError, assignKeyIds, audioOffsetSamples, bake, bakeCheckpointed, batch, beginReadPhase, bindTimeline, booleanType, buildFontRegistry, buildTimeline, colorType, compileTimeline, computed, createPlayhead, cubicBezier, cubicBezierDerivative, deleteSidecarTrack, easingDerivatives, easings, emitDevWarning, emptySidecar, endReadPhase, evaluateAt, formatColor, getTimelineCallbacks, getValueType, hashKeys, inReadPhase, inferValueType, isDurationEditable, isEditableNodeId, isExemptFamily, key, lerpColor, mergeSidecar, mergeSidecarDetailed, migrateSidecar, namedEasing, normalizeEditedKeys, numberType, oklabToRgba, paintType, parseCmap, parseColor, pathType, random, registerValueType, resolveEase, resolveEaseDerivative, resolveTweenTarget, rgbaToOklab, sampleTrack, setDevWarning, setScheduler, setSidecarTrack, signal, spring, springEasing, springEasingDerivative, springPresets, springTo, stagger, stringType, synchronousScheduler, targetNodeId, timeline, track, untracked, validateFonts, validateTrack, vec2ArcType, vec2Equals, vec2Signal, vec2Type, velocityAt };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glissade/core",
3
- "version": "0.13.0",
3
+ "version": "0.14.0-pre.0",
4
4
  "description": "glissade core: signals, tracks, timeline document, evaluation, easing, springs, seeded RNG. Zero DOM/Node dependencies.",
5
5
  "license": "Apache-2.0",
6
6
  "engines": {
@@ -21,6 +21,10 @@
21
21
  "types": "./dist/clips.d.ts",
22
22
  "default": "./dist/clips.js"
23
23
  },
24
+ "./i18n": {
25
+ "types": "./dist/i18n.d.ts",
26
+ "default": "./dist/i18n.js"
27
+ },
24
28
  "./font-ingest": {
25
29
  "types": "./dist/font-ingest.d.ts",
26
30
  "default": "./dist/font-ingest.js"