@hyperframes/core 0.9.26 → 0.9.27

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.
@@ -10,4 +10,6 @@ export declare function replaceFileAtomically(filePath: string, content: string
10
10
  export declare function createFileAtomically(filePath: string, content: string | Uint8Array, operations?: DirectFileSystem & Pick<typeof fs, "linkSync">): void;
11
11
  /** The file a write to `filePath` lands on: folder links and file links followed as the system does. */
12
12
  export declare function resolveWritePath(filePath: string): string;
13
+ /** `prefix` + 6 random characters in `parent`, made private; Windows past 260 characters needs the long path. */
14
+ export declare function createStagingDir(parent: string, prefix: string): string;
13
15
  export {};
@@ -149,3 +149,27 @@ function writeTempSibling(filePath, content, mode, operations) {
149
149
  function errorCode(error) {
150
150
  return String(error?.code);
151
151
  }
152
+ const WIN32_LONG_PREFIX = "\\\\?\\";
153
+ const WIN32_ABSOLUTE = /^([A-Za-z]:\\|\\\\)/;
154
+ const WIN32_DOS_DEVICE = /^\\\\[.?]\\/;
155
+ function toWin32LongPath(path) {
156
+ const full = resolve(path);
157
+ if (!WIN32_ABSOLUTE.test(full) || WIN32_DOS_DEVICE.test(full))
158
+ return path;
159
+ return full.startsWith("\\\\")
160
+ ? `${WIN32_LONG_PREFIX}UNC\\${full.slice(2)}`
161
+ : `${WIN32_LONG_PREFIX}${full}`;
162
+ }
163
+ /** `prefix` + 6 random characters in `parent`, made private; Windows past 260 characters needs the long path. */
164
+ export function createStagingDir(parent, prefix) {
165
+ const requested = join(parent, prefix);
166
+ const long = toWin32LongPath(requested);
167
+ const created = fs.mkdtempSync(long);
168
+ return long === requested ? created : withoutAddedLongPrefix(created);
169
+ }
170
+ function withoutAddedLongPrefix(path) {
171
+ const unc = `${WIN32_LONG_PREFIX}UNC\\`;
172
+ return path.startsWith(unc)
173
+ ? `\\\\${path.slice(unc.length)}`
174
+ : path.slice(WIN32_LONG_PREFIX.length);
175
+ }
@@ -1,4 +1,10 @@
1
1
  export declare const RUNTIME_BOOTSTRAP_ATTR = "data-hyperframes-preview-runtime";
2
+ export interface SceneRootLookup {
3
+ root: Element | null;
4
+ hasTemplate: boolean;
5
+ hasLiveRoot: boolean;
6
+ }
7
+ export declare function locateSceneRoot(html: string): SceneRootLookup;
2
8
  export declare function isTemplateEntry(html: string): boolean;
3
9
  export declare function isFullHtmlDocument(html: string): boolean;
4
10
  /**
@@ -1,4 +1,5 @@
1
1
  import { acceleratedCanvasTrackerSource } from "../pageMotionBlur.js";
2
+ import { findSceneTemplate } from "@hyperframes/parsers/sub-composition-validity";
2
3
  import { parseHTML } from "linkedom";
3
4
  export const RUNTIME_BOOTSTRAP_ATTR = "data-hyperframes-preview-runtime";
4
5
  const RUNTIME_FILES = [
@@ -11,8 +12,20 @@ const SIMPLE_RUNTIME_FLAG_ASSIGNMENTS = [
11
12
  /^window\.__renderReady\s*=\s*(?:true|false)\s*;?$/,
12
13
  ];
13
14
  const LEADING_COMMENTS = /^(?:\s|<!--(?:>|->|[\s\S]*?-->))*/;
15
+ export function locateSceneRoot(html) {
16
+ const { document } = parseHTML(html);
17
+ const liveRoot = document.querySelector("[data-composition-id]");
18
+ const templates = Array.from(document.querySelectorAll("template"));
19
+ const sceneRoot = findSceneTemplate(templates)?.content.querySelector("[data-composition-id]") ?? null;
20
+ return {
21
+ root: sceneRoot,
22
+ hasTemplate: templates.length > 0,
23
+ hasLiveRoot: liveRoot !== null,
24
+ };
25
+ }
14
26
  export function isTemplateEntry(html) {
15
- return /^<template[\s>/]/i.test(html.replace(LEADING_COMMENTS, ""));
27
+ const { root, hasTemplate, hasLiveRoot } = locateSceneRoot(html);
28
+ return hasTemplate && root !== null && !hasLiveRoot;
16
29
  }
17
30
  export function isFullHtmlDocument(html) {
18
31
  return /^(?:<!doctype|<html[\s>/])/i.test(html.replace(LEADING_COMMENTS, ""));
@@ -1,17 +1,12 @@
1
1
  import { parseHTML } from "linkedom";
2
2
  import { HF_AUDIO_FX_ATTR } from "../audioFx.js";
3
+ import { locateSceneRoot } from "./htmlDocument.js";
3
4
  export { isTemplateEntry } from "./htmlDocument.js";
4
5
  function normalizeCompositionSrcPath(srcPath) {
5
6
  return srcPath.replace(/\\/g, "/").replace(/^\.\//, "");
6
7
  }
7
- // linkedom has no inert <template> content, so the template's innerHTML is re-parsed.
8
8
  function readSceneRoot(entryHtml) {
9
- if (!entryHtml)
10
- return null;
11
- const { document } = parseHTML(entryHtml);
12
- const template = document.querySelector("template");
13
- const scope = template ? parseHTML(template.innerHTML).document : document;
14
- return scope.querySelector("[data-composition-id]");
9
+ return entryHtml ? locateSceneRoot(entryHtml).root : null;
15
10
  }
16
11
  // The scene's own chain replaces the index's, which belongs to the whole project.
17
12
  function setSceneFxChain(el, sceneFxChain) {
@@ -1,10 +1,11 @@
1
1
  // @ts-expect-error -- wawoff2 ships no type declarations
2
2
  import wawoff2 from "wawoff2";
3
3
  import { createHash } from "node:crypto";
4
- import { existsSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, writeFileSync, } from "node:fs";
4
+ import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
6
6
  import { dirname, join } from "node:path";
7
7
  import { hyperframesCacheDir } from "../cacheDir.js";
8
+ import { createStagingDir } from "../atomicFile.js";
8
9
  const { compress } = wawoff2;
9
10
  export async function compressToWoff2(input) {
10
11
  return Buffer.from(await compress(input));
@@ -49,7 +50,7 @@ function cacheCompression(path, compressed) {
49
50
  mkdirSync(dirname(path), { recursive: true });
50
51
  // Keep the write on the cache filesystem for an atomic rename, inside a
51
52
  // private directory that this invocation owns.
52
- tempDir = mkdtempSync(join(dirname(path), ".compression-"));
53
+ tempDir = createStagingDir(dirname(path), ".compression-");
53
54
  const tmpPath = join(tempDir, "font.woff2");
54
55
  writeFileSync(tmpPath, compressed, { flag: "wx", mode: 0o644 });
55
56
  renameSync(tmpPath, path);