@hyperframes/core 0.8.168 → 0.8.170
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/compiler/compositionScoping.d.ts +5 -1
- package/dist/compiler/compositionScoping.js +12 -6
- package/dist/compiler/htmlBundler.js +16 -9
- package/dist/compiler/scenePartsManifest.js +4 -2
- package/dist/core.types.d.ts +0 -4
- package/dist/core.types.js +0 -5
- package/dist/distributedFps.d.ts +4 -0
- package/dist/distributedFps.js +5 -0
- package/dist/fonts/authoredGoogleFonts.js +2 -0
- package/dist/fonts/deterministicFonts.js +4 -0
- package/dist/fonts/systemFontLocator.d.ts +0 -1
- package/dist/fonts/systemFontLocator.js +1 -81
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/hyperframe.runtime.iife.js +63 -62
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/sceneParts.d.ts +2 -0
- package/dist/sceneParts.js +2 -0
- package/package.json +8 -4
|
@@ -4,7 +4,11 @@ export declare function scopeCssToComposition(css: string, compositionId: string
|
|
|
4
4
|
}): string;
|
|
5
5
|
/** Drops repeats of an identical `@font-face` across the given style texts, keeping the last copy:
|
|
6
6
|
* the last matching rule is the one the browser uses, so a rule in between never gains precedence. */
|
|
7
|
-
export declare
|
|
7
|
+
export declare const dedupeFontFaceRules: (styleTexts: string[]) => string[];
|
|
8
|
+
export declare function hoistFontFaceRules(styleTexts: string[]): {
|
|
9
|
+
styles: string[];
|
|
10
|
+
faces: string[];
|
|
11
|
+
};
|
|
8
12
|
export declare function scopedModulePrelude(timelineCompositionId: string, compositionSrc?: string | null): string;
|
|
9
13
|
export declare function wrapScopedCompositionScript(source: string, compositionId: string, errorLabel?: string, scopeSelectorOverride?: string, timelineCompositionId?: string, authoredRootId?: string | null, compositionSrc?: string | null): string;
|
|
10
14
|
export declare function wrapInlineScriptWithErrorBoundary(source: string, errorLabel: string): string;
|
|
@@ -162,7 +162,12 @@ function fontFaceKey(atRule) {
|
|
|
162
162
|
}
|
|
163
163
|
/** Drops repeats of an identical `@font-face` across the given style texts, keeping the last copy:
|
|
164
164
|
* the last matching rule is the one the browser uses, so a rule in between never gains precedence. */
|
|
165
|
-
export
|
|
165
|
+
export const dedupeFontFaceRules = (styleTexts) => dropFontFaces(styleTexts);
|
|
166
|
+
export function hoistFontFaceRules(styleTexts) {
|
|
167
|
+
const faces = [];
|
|
168
|
+
return { styles: dropFontFaces(styleTexts, faces), faces };
|
|
169
|
+
}
|
|
170
|
+
function dropFontFaces(styleTexts, hoisted) {
|
|
166
171
|
const seen = new Set();
|
|
167
172
|
return [...styleTexts]
|
|
168
173
|
.reverse()
|
|
@@ -181,13 +186,14 @@ export function dedupeFontFaceRules(styleTexts) {
|
|
|
181
186
|
if (!isFontFaceAtRule(node))
|
|
182
187
|
continue;
|
|
183
188
|
const key = fontFaceKey(node);
|
|
184
|
-
if (seen.has(key)) {
|
|
185
|
-
node.remove();
|
|
186
|
-
changed = true;
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
+
if (!seen.has(key)) {
|
|
189
190
|
seen.add(key);
|
|
191
|
+
if (!hoisted)
|
|
192
|
+
continue;
|
|
193
|
+
hoisted.unshift(node.toString());
|
|
190
194
|
}
|
|
195
|
+
node.remove();
|
|
196
|
+
changed = true;
|
|
191
197
|
}
|
|
192
198
|
return changed ? root.toResult({ map: false }).css : css;
|
|
193
199
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { compositionStyle, cssStyleMergeKey, deferScriptsUntilFonts, UNCONDITIONAL_CSS_KEY, headStyleRuns, INLINED_FILE_ATTR, inlineScriptRuns, styleElementsFor, } from "./scriptRuns.js";
|
|
3
3
|
import { countPageRoot, executableScripts, isJavaScriptType, planCompositionAssembly, } from "./compositionAssembly.js";
|
|
4
|
-
import { SCENE_PART_ATTR } from "../sceneParts.js";
|
|
4
|
+
import { SCENE_FONTS_ATTR, SCENE_PART_ATTR } from "../sceneParts.js";
|
|
5
5
|
import { ensureExternalScriptTag, readExternalScriptAttributes, } from "./externalScripts.js";
|
|
6
6
|
import { emitMountedModuleScripts, parseImportMap } from "./importMaps.js";
|
|
7
7
|
import { markFlattenedInnerRoot } from "../runtime/flattenedRoot.js";
|
|
@@ -20,7 +20,7 @@ import { transform } from "esbuild";
|
|
|
20
20
|
import { compileHtml } from "./htmlCompiler.js";
|
|
21
21
|
import { RUNTIME_BOOTSTRAP_ATTR, escapeInlineScriptSource, insertRuntimeTag, parseHTMLContent, stripEmbeddedRuntimeScripts, } from "./htmlDocument.js";
|
|
22
22
|
// rewriteSubCompPaths functions are used by inlineSubCompositions (shared module)
|
|
23
|
-
import { buildVariablesByCompScript, dedupeFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, scopedModulePrelude, wrapScopedCompositionScript, } from "./compositionScoping.js";
|
|
23
|
+
import { buildVariablesByCompScript, dedupeFontFaceRules, hoistFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, scopedModulePrelude, wrapScopedCompositionScript, } from "./compositionScoping.js";
|
|
24
24
|
import { validateHyperframeHtmlContract } from "./staticGuard.js";
|
|
25
25
|
import { getHyperframeRuntimeScript } from "../generated/runtime-inline.js";
|
|
26
26
|
import { readDeclaredDefaults } from "../runtime/getVariables.js";
|
|
@@ -1171,13 +1171,20 @@ async function bundleProject(projectDir, options) {
|
|
|
1171
1171
|
if (srcset)
|
|
1172
1172
|
el.setAttribute("srcset", rewriteSrcsetWithInlinedAssets(srcset, projectDir, inlineAssets));
|
|
1173
1173
|
}
|
|
1174
|
-
// Before inlining, so postcss reads paths not font bytes
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1174
|
+
// Before inlining, so postcss reads paths not font bytes.
|
|
1175
|
+
const liveStyles = [...document.querySelectorAll("style")].filter(isAlwaysAppliedStyle);
|
|
1176
|
+
const liveCss = liveStyles.map((el) => el.textContent || "");
|
|
1177
|
+
const { styles, faces } = options?.sceneParts
|
|
1178
|
+
? hoistFontFaceRules(liveCss)
|
|
1179
|
+
: { styles: dedupeFontFaceRules(liveCss), faces: [] };
|
|
1180
|
+
liveStyles.forEach((el, i) => {
|
|
1181
|
+
el.textContent = styles[i] ?? "";
|
|
1182
|
+
});
|
|
1183
|
+
if (faces.length > 0) {
|
|
1184
|
+
const holder = document.createElement("style");
|
|
1185
|
+
holder.setAttribute(SCENE_FONTS_ATTR, "");
|
|
1186
|
+
holder.textContent = faces.join("\n");
|
|
1187
|
+
document.head.prepend(holder);
|
|
1181
1188
|
}
|
|
1182
1189
|
for (const styleEl of document.querySelectorAll("style")) {
|
|
1183
1190
|
styleEl.textContent = rewriteCssUrlsWithInlinedAssets(styleEl.textContent || "", projectDir, inlineAssets);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { SCENE_PART_ATTR, SCENE_PARTS_META } from "../sceneParts.js";
|
|
2
|
+
import { SCENE_FONTS_ATTR, SCENE_PART_ATTR, SCENE_PARTS_META, } from "../sceneParts.js";
|
|
3
3
|
import { injectTagsAtHeadStart, parseHTMLContent } from "./htmlDocument.js";
|
|
4
4
|
const hash = (text) => createHash("sha1").update(text).digest("hex").slice(0, 16);
|
|
5
5
|
/**
|
|
@@ -19,7 +19,9 @@ export function addScenePartsManifest(html, ignore = []) {
|
|
|
19
19
|
// A marker keeps each part's place in `shared`, so moving or reordering a scene changes it.
|
|
20
20
|
for (const el of parts)
|
|
21
21
|
el.replaceWith(doc.createComment(`hf-scene:${el.getAttribute(SCENE_PART_ATTR)}`));
|
|
22
|
-
for (const el of ignore.flatMap((sel) => [
|
|
22
|
+
for (const el of [...ignore, `style[${SCENE_FONTS_ATTR}]`].flatMap((sel) => [
|
|
23
|
+
...doc.querySelectorAll(sel),
|
|
24
|
+
]))
|
|
23
25
|
el.remove();
|
|
24
26
|
const manifest = {
|
|
25
27
|
shared: hash(doc.toString()),
|
package/dist/core.types.d.ts
CHANGED
|
@@ -65,10 +65,6 @@ export declare function parseFps(input: string | number): FpsParseResult;
|
|
|
65
65
|
* errors — those still surface via the discriminated result.
|
|
66
66
|
*/
|
|
67
67
|
export declare function parseFpsWithDefault(input: string | number | undefined): FpsParseResult;
|
|
68
|
-
/** Integer rates the distributed renderer (Lambda, Cloud Run) accepts; fractional fps renders in-process only. */
|
|
69
|
-
export declare const DISTRIBUTED_FPS: readonly [24, 25, 30, 60];
|
|
70
|
-
export type DistributedFps = (typeof DISTRIBUTED_FPS)[number];
|
|
71
|
-
export declare function isDistributedFps(value: unknown): value is DistributedFps;
|
|
72
68
|
/** Video orientation / aspect ratio. */
|
|
73
69
|
export type Orientation = "16:9" | "9:16";
|
|
74
70
|
export type { Asset, TimelineElementType, MediaElementType, TimelineElementBase, TimelineMediaElement, WaveformData, TimelineTextElement, TimelineCompositionElement, CompositionVariableType, CompositionVariableBase, StringVariable, NumberVariable, ColorVariable, BooleanVariable, EnumVariable, CompositionVariable, CompositionSpec, TimelineElement, MediaFile, CanvasResolution, CompositionAPI, PlayerAPI, AddElementData, ValidationResult, CompositionAsset, Keyframe, KeyframeProperties, ElementKeyframes, StageZoom, StageZoomKeyframe, } from "@hyperframes/parsers";
|
package/dist/core.types.js
CHANGED
|
@@ -101,9 +101,4 @@ export function parseFpsWithDefault(input) {
|
|
|
101
101
|
return { ok: true, value: { num: 30, den: 1 } };
|
|
102
102
|
return parseFps(input);
|
|
103
103
|
}
|
|
104
|
-
/** Integer rates the distributed renderer (Lambda, Cloud Run) accepts; fractional fps renders in-process only. */
|
|
105
|
-
export const DISTRIBUTED_FPS = [24, 25, 30, 60];
|
|
106
|
-
export function isDistributedFps(value) {
|
|
107
|
-
return DISTRIBUTED_FPS.includes(value);
|
|
108
|
-
}
|
|
109
104
|
export { CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, normalizeResolutionFlag, isAspectAgnosticResolutionAlias, resolveResolutionFlagPair, checkOutputResolutionCompatibility, suggestMatchingPreset, COMPOSITION_VARIABLE_TYPES, TIMELINE_COLORS, DEFAULT_DURATIONS, getDefaultStageZoom, isTextElement, isMediaElement, isCompositionElement, } from "@hyperframes/parsers";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Integer rates the distributed renderer (Lambda, Cloud Run) accepts; fractional fps renders in-process only. */
|
|
2
|
+
export declare const DISTRIBUTED_FPS: readonly [24, 25, 30, 60];
|
|
3
|
+
export type DistributedFps = (typeof DISTRIBUTED_FPS)[number];
|
|
4
|
+
export declare function isDistributedFps(value: unknown): value is DistributedFps;
|
|
@@ -202,6 +202,8 @@ export function normalizeSystemFontPrimaryFamilies(html, deterministicPrimary =
|
|
|
202
202
|
return changed ? document.toString() : html;
|
|
203
203
|
}
|
|
204
204
|
function collectCssCustomProperties(css, customProperties) {
|
|
205
|
+
if (!css.includes("--"))
|
|
206
|
+
return;
|
|
205
207
|
const root = parseCssRoot(css);
|
|
206
208
|
if (!root)
|
|
207
209
|
return;
|
|
@@ -228,6 +230,8 @@ function* iterateCssRootFontFamilyDeclarations(root) {
|
|
|
228
230
|
yield* declarations;
|
|
229
231
|
}
|
|
230
232
|
function* iterateCssFontFamilyDeclarations(css) {
|
|
233
|
+
if (!/font-family/i.test(css))
|
|
234
|
+
return;
|
|
231
235
|
const root = parseCssRoot(css);
|
|
232
236
|
if (!root)
|
|
233
237
|
return;
|
|
@@ -24,5 +24,4 @@ export interface LocatedFontVariant extends LocatedFont {
|
|
|
24
24
|
style: "normal" | "italic";
|
|
25
25
|
}
|
|
26
26
|
export declare function locateSystemFontVariants(family: string): LocatedFontVariant[];
|
|
27
|
-
export declare function getSystemProfilerFamilies(): string[];
|
|
28
27
|
export declare function clearSystemFontCache(): void;
|
|
@@ -3,7 +3,6 @@ import { existsSync, lstatSync, readdirSync, realpathSync } from "node:fs";
|
|
|
3
3
|
import { homedir, platform } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
export const SYSTEM_FONT_SIZE_LIMIT = 5 * 1024 * 1024;
|
|
6
|
-
const PROFILER_TIMEOUT_MS = 5000;
|
|
7
6
|
const FC_MATCH_TIMEOUT_MS = 3000;
|
|
8
7
|
export const FONT_EXT_RE = /\.(otf|ttf|ttc|woff2?)$/i;
|
|
9
8
|
const FORMAT_PRIORITY = {
|
|
@@ -193,64 +192,6 @@ function pickBestCandidate(candidates) {
|
|
|
193
192
|
const best = candidates[0];
|
|
194
193
|
return { path: best.path, format: best.format };
|
|
195
194
|
}
|
|
196
|
-
let profilerCache = null;
|
|
197
|
-
// fallow-ignore-next-line complexity
|
|
198
|
-
function getSystemProfilerIndex() {
|
|
199
|
-
if (profilerCache)
|
|
200
|
-
return profilerCache;
|
|
201
|
-
profilerCache = new Map();
|
|
202
|
-
if (platform() !== "darwin")
|
|
203
|
-
return profilerCache;
|
|
204
|
-
try {
|
|
205
|
-
const raw = execFileSync("system_profiler", ["SPFontsDataType", "-json"], {
|
|
206
|
-
encoding: "utf8",
|
|
207
|
-
maxBuffer: 12 * 1024 * 1024,
|
|
208
|
-
timeout: PROFILER_TIMEOUT_MS,
|
|
209
|
-
});
|
|
210
|
-
const parsed = JSON.parse(raw);
|
|
211
|
-
if (!parsed?.SPFontsDataType || !Array.isArray(parsed.SPFontsDataType))
|
|
212
|
-
return profilerCache;
|
|
213
|
-
for (const fontEntry of parsed.SPFontsDataType) {
|
|
214
|
-
if (!fontEntry?.typefaces || !Array.isArray(fontEntry.typefaces))
|
|
215
|
-
continue;
|
|
216
|
-
for (const typeface of fontEntry.typefaces) {
|
|
217
|
-
if (!typeface)
|
|
218
|
-
continue;
|
|
219
|
-
const family = typeface.family ?? typeface.fullname ?? typeface._name;
|
|
220
|
-
if (typeof family !== "string")
|
|
221
|
-
continue;
|
|
222
|
-
const filePath = typeface.path;
|
|
223
|
-
if (typeof filePath !== "string" || !FONT_EXT_RE.test(filePath))
|
|
224
|
-
continue;
|
|
225
|
-
const normalized = normalizeName(family);
|
|
226
|
-
const ext = filePath.match(FONT_EXT_RE)?.[1] ?? "ttf";
|
|
227
|
-
const entry = {
|
|
228
|
-
family: normalized,
|
|
229
|
-
path: filePath,
|
|
230
|
-
format: extensionToFormat(ext),
|
|
231
|
-
isRegular: isRegularWeight(filePath),
|
|
232
|
-
};
|
|
233
|
-
const list = profilerCache.get(normalized) ?? [];
|
|
234
|
-
list.push(entry);
|
|
235
|
-
profilerCache.set(normalized, list);
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
catch {
|
|
240
|
-
// system_profiler unavailable
|
|
241
|
-
}
|
|
242
|
-
return profilerCache;
|
|
243
|
-
}
|
|
244
|
-
function locateViaSystemProfiler(targetFamily) {
|
|
245
|
-
const index = getSystemProfilerIndex();
|
|
246
|
-
const entries = index.get(targetFamily);
|
|
247
|
-
if (!entries || entries.length === 0)
|
|
248
|
-
return null;
|
|
249
|
-
const candidates = entries
|
|
250
|
-
.filter((e) => isRegularFile(e.path) && isPathBounded(e.path))
|
|
251
|
-
.map((e) => ({ path: e.path, format: e.format, isRegular: e.isRegular }));
|
|
252
|
-
return pickBestCandidate(candidates);
|
|
253
|
-
}
|
|
254
195
|
// fallow-ignore-next-line complexity
|
|
255
196
|
function locateViaFcMatch(targetFamily) {
|
|
256
197
|
if (platform() !== "linux")
|
|
@@ -280,11 +221,7 @@ export function locateSystemFont(family) {
|
|
|
280
221
|
const cached = cache.get(normalized);
|
|
281
222
|
if (cached !== undefined)
|
|
282
223
|
return cached;
|
|
283
|
-
let result =
|
|
284
|
-
result = locateViaSystemProfiler(normalized);
|
|
285
|
-
if (!result) {
|
|
286
|
-
result = locateViaFcMatch(normalized);
|
|
287
|
-
}
|
|
224
|
+
let result = locateViaFcMatch(normalized);
|
|
288
225
|
if (!result) {
|
|
289
226
|
const allCandidates = [];
|
|
290
227
|
for (const dir of fontDirectories()) {
|
|
@@ -330,18 +267,6 @@ export function locateSystemFontVariants(family) {
|
|
|
330
267
|
if (!normalized)
|
|
331
268
|
return [];
|
|
332
269
|
const variants = [];
|
|
333
|
-
const profilerIndex = getSystemProfilerIndex();
|
|
334
|
-
const profilerEntries = profilerIndex.get(normalized);
|
|
335
|
-
if (profilerEntries && profilerEntries.length > 0) {
|
|
336
|
-
for (const e of profilerEntries) {
|
|
337
|
-
if (!isRegularFile(e.path) || !isPathBounded(e.path))
|
|
338
|
-
continue;
|
|
339
|
-
const { weight, style } = inferWeightAndStyle(e.path);
|
|
340
|
-
variants.push({ path: e.path, format: e.format, weight, style });
|
|
341
|
-
}
|
|
342
|
-
if (variants.length > 0)
|
|
343
|
-
return dedupeVariants(variants);
|
|
344
|
-
}
|
|
345
270
|
const allCandidates = [];
|
|
346
271
|
for (const dir of fontDirectories()) {
|
|
347
272
|
allCandidates.push(...collectCandidatesFromDir(dir, normalized));
|
|
@@ -361,12 +286,7 @@ function dedupeVariants(variants) {
|
|
|
361
286
|
}
|
|
362
287
|
return Array.from(seen.values());
|
|
363
288
|
}
|
|
364
|
-
export function getSystemProfilerFamilies() {
|
|
365
|
-
const index = getSystemProfilerIndex();
|
|
366
|
-
return Array.from(index.keys());
|
|
367
|
-
}
|
|
368
289
|
export function clearSystemFontCache() {
|
|
369
290
|
cache.clear();
|
|
370
|
-
profilerCache = null;
|
|
371
291
|
allowedDirsCache = null;
|
|
372
292
|
}
|