@hyperframes/core 0.8.45 → 0.8.47

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.
@@ -0,0 +1,28 @@
1
+ /** A composition is "ready" once every declared input settles, not just once
2
+ * its duration is known. Each input returns null (nothing to wait on) or a
3
+ * promise that resolves once it settles. */
4
+ export type CompositionReadinessInput = (doc: Document) => Promise<void> | null;
5
+ export interface PendingCompositionAssets {
6
+ pendingMedia: HTMLMediaElement[];
7
+ pendingImages: HTMLImageElement[];
8
+ fontsLoading: boolean;
9
+ }
10
+ export declare function isRealmElement(node: Node): node is Element;
11
+ export declare function isRealmHtmlMediaElement(node: Node): node is HTMLMediaElement;
12
+ /** One DOM pass for every declared-media asset not yet ready. */
13
+ export declare function scanPendingCompositionAssets(doc: Document): PendingCompositionAssets;
14
+ /** Declared-media readiness input: waits on the composition's own video,
15
+ * audio, image and font-face loads. */
16
+ export declare function mediaReadinessInput(doc: Document): Promise<void> | null;
17
+ export interface CompositionReadinessResult {
18
+ timedOut: boolean;
19
+ }
20
+ /** Invokes `onSettled` once every input settles, or the timeout elapses.
21
+ * Calls back synchronously, before returning, when nothing is pending — a
22
+ * caller that plays right after this call sees the decision already
23
+ * applied, same as before this gate existed. */
24
+ export declare function settleCompositionReadiness(doc: Document, onSettled: (result: CompositionReadinessResult) => void, opts?: {
25
+ inputs?: CompositionReadinessInput[];
26
+ timeoutMs?: number;
27
+ }): void;
28
+ //# sourceMappingURL=compositionReadiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositionReadiness.d.ts","sourceRoot":"","sources":["../src/compositionReadiness.ts"],"names":[],"mappings":"AAAA;;4CAE4C;AAC5C,MAAM,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEhF,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,EAAE,gBAAgB,EAAE,CAAC;IAClC,YAAY,EAAE,OAAO,CAAC;CACvB;AAWD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,OAAO,CAI1D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,gBAAgB,CAM5E;AAED,iEAAiE;AACjE,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,QAAQ,GAAG,wBAAwB,CAOpF;AAyBD;uCACuC;AACvC,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAMvE;AAID,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;gDAGgD;AAChD,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,CAAC,MAAM,EAAE,0BAA0B,KAAK,IAAI,EACvD,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACtE,IAAI,CAiBN"}
@@ -0,0 +1,79 @@
1
+ // HTMLMediaElement.HAVE_FUTURE_DATA per spec, used as a literal because not
2
+ // every DOM implementation defines the named static (e.g. happy-dom leaves
3
+ // it undefined).
4
+ const HAVE_FUTURE_DATA = 3;
5
+ // `doc` is a foreign (same-origin) iframe document, so its elements belong to
6
+ // that iframe's own realm — instanceof checks against this window's globals
7
+ // would silently reject every one of them. Resolve the class from the node's
8
+ // own defaultView first.
9
+ export function isRealmElement(node) {
10
+ const view = node.ownerDocument?.defaultView;
11
+ if (view && node instanceof view.Element)
12
+ return true;
13
+ return node instanceof Element;
14
+ }
15
+ export function isRealmHtmlMediaElement(node) {
16
+ if (!isRealmElement(node))
17
+ return false;
18
+ if (node.tagName !== "AUDIO" && node.tagName !== "VIDEO")
19
+ return false;
20
+ const view = node.ownerDocument?.defaultView;
21
+ if (view && node instanceof view.HTMLMediaElement)
22
+ return true;
23
+ return node instanceof HTMLMediaElement;
24
+ }
25
+ /** One DOM pass for every declared-media asset not yet ready. */
26
+ export function scanPendingCompositionAssets(doc) {
27
+ const pendingMedia = Array.from(doc.querySelectorAll("video, audio"))
28
+ .filter(isRealmHtmlMediaElement)
29
+ .filter((el) => el.readyState < HAVE_FUTURE_DATA);
30
+ const pendingImages = Array.from(doc.querySelectorAll("img")).filter((img) => !img.complete);
31
+ const fontsLoading = doc.fonts?.status === "loading";
32
+ return { pendingMedia, pendingImages, fontsLoading };
33
+ }
34
+ function collectPendingCompositionAssets(doc, { pendingMedia, pendingImages, fontsLoading }) {
35
+ const mediaReady = pendingMedia.map((el) => new Promise((resolve) => {
36
+ const onSettled = () => {
37
+ el.removeEventListener("canplay", onSettled);
38
+ el.removeEventListener("error", onSettled);
39
+ resolve();
40
+ };
41
+ el.addEventListener("canplay", onSettled);
42
+ el.addEventListener("error", onSettled);
43
+ }));
44
+ const imagesReady = pendingImages.map((img) => img.decode ? img.decode().catch(() => { }) : Promise.resolve());
45
+ const fontsReady = fontsLoading && doc.fonts ? doc.fonts.ready.then(() => { }) : Promise.resolve();
46
+ return Promise.all([...mediaReady, ...imagesReady, fontsReady]).then(() => { });
47
+ }
48
+ /** Declared-media readiness input: waits on the composition's own video,
49
+ * audio, image and font-face loads. */
50
+ export function mediaReadinessInput(doc) {
51
+ const scan = scanPendingCompositionAssets(doc);
52
+ if (scan.pendingMedia.length === 0 && scan.pendingImages.length === 0 && !scan.fontsLoading) {
53
+ return null;
54
+ }
55
+ return collectPendingCompositionAssets(doc, scan);
56
+ }
57
+ const DEFAULT_TIMEOUT_MS = 8_000;
58
+ /** Invokes `onSettled` once every input settles, or the timeout elapses.
59
+ * Calls back synchronously, before returning, when nothing is pending — a
60
+ * caller that plays right after this call sees the decision already
61
+ * applied, same as before this gate existed. */
62
+ export function settleCompositionReadiness(doc, onSettled, opts = {}) {
63
+ const inputs = opts.inputs ?? [mediaReadinessInput];
64
+ const pending = inputs.map((input) => input(doc)).filter((p) => p !== null);
65
+ if (pending.length === 0) {
66
+ onSettled({ timedOut: false });
67
+ return;
68
+ }
69
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
70
+ let timeoutId;
71
+ const timeout = new Promise((resolve) => {
72
+ timeoutId = setTimeout(() => resolve("timed-out"), timeoutMs);
73
+ });
74
+ Promise.race([Promise.all(pending).then(() => "done"), timeout]).then((result) => {
75
+ clearTimeout(timeoutId);
76
+ onSettled({ timedOut: result === "timed-out" });
77
+ });
78
+ }
79
+ //# sourceMappingURL=compositionReadiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositionReadiness.js","sourceRoot":"","sources":["../src/compositionReadiness.ts"],"names":[],"mappings":"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"}