@editframe/elements 0.34.5-beta → 0.34.7-beta
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/canvas/EFCanvas.d.ts +4 -4
- package/dist/elements/EFAudio.d.ts +4 -4
- package/dist/elements/EFCaptions.d.ts +4 -4
- package/dist/elements/EFImage.d.ts +4 -4
- package/dist/elements/EFMedia.d.ts +2 -2
- package/dist/elements/EFPanZoom.d.ts +4 -4
- package/dist/elements/EFSurface.d.ts +4 -4
- package/dist/elements/EFText.d.ts +4 -4
- package/dist/elements/EFTextSegment.d.ts +4 -4
- package/dist/elements/EFThumbnailStrip.d.ts +4 -4
- package/dist/elements/EFVideo.d.ts +6 -6
- package/dist/elements/EFWaveform.d.ts +4 -4
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/getRenderInfo.js.map +1 -1
- package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
- package/dist/gui/EFConfiguration.d.ts +4 -4
- package/dist/gui/EFControls.d.ts +2 -2
- package/dist/gui/EFDial.d.ts +4 -4
- package/dist/gui/EFFilmstrip.d.ts +2 -2
- package/dist/gui/EFFitScale.d.ts +3 -3
- package/dist/gui/EFFocusOverlay.d.ts +4 -4
- package/dist/gui/EFPause.d.ts +4 -4
- package/dist/gui/EFPlay.d.ts +4 -4
- package/dist/gui/EFPreview.d.ts +4 -4
- package/dist/gui/EFResizableBox.d.ts +4 -4
- package/dist/gui/EFScrubber.d.ts +4 -4
- package/dist/gui/EFTimeDisplay.d.ts +4 -4
- package/dist/gui/EFToggleLoop.d.ts +4 -4
- package/dist/gui/EFTogglePlay.d.ts +4 -4
- package/dist/gui/EFTransformHandles.d.ts +4 -4
- package/dist/gui/EFWorkbench.d.ts +6 -6
- package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
- package/dist/gui/hierarchy/EFHierarchyItem.d.ts +2 -2
- package/dist/gui/tree/EFTree.d.ts +4 -4
- package/dist/gui/tree/EFTreeItem.d.ts +4 -4
- package/dist/node.d.ts +8 -0
- package/dist/node.js +3 -0
- package/dist/preview/renderTimegroupToCanvas.js +2 -1
- package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
- package/package.json +14 -2
- package/tsdown.config.ts +1 -0
|
@@ -5,9 +5,9 @@ import { PanZoomTransform } from "../elements/EFPanZoom.js";
|
|
|
5
5
|
import "./overlays/SelectionOverlay.js";
|
|
6
6
|
import "../gui/EFOverlayLayer.js";
|
|
7
7
|
import "../gui/EFTransformHandles.js";
|
|
8
|
-
import * as
|
|
8
|
+
import * as lit4 from "lit";
|
|
9
9
|
import { LitElement } from "lit";
|
|
10
|
-
import * as
|
|
10
|
+
import * as lit_html3 from "lit-html";
|
|
11
11
|
|
|
12
12
|
//#region src/canvas/EFCanvas.d.ts
|
|
13
13
|
declare const EFCanvas_base: typeof LitElement;
|
|
@@ -87,7 +87,7 @@ declare const EFCanvas_base: typeof LitElement;
|
|
|
87
87
|
* Manages existing elements (EF* elements, divs, etc.) and provides selection functionality.
|
|
88
88
|
*/
|
|
89
89
|
declare class EFCanvas extends EFCanvas_base {
|
|
90
|
-
static styles:
|
|
90
|
+
static styles: lit4.CSSResult[];
|
|
91
91
|
panZoomTransform?: PanZoomTransform;
|
|
92
92
|
elementIdAttribute: string;
|
|
93
93
|
enableTransformHandles: boolean;
|
|
@@ -302,7 +302,7 @@ declare class EFCanvas extends EFCanvas_base {
|
|
|
302
302
|
* Cleanup transform handles.
|
|
303
303
|
*/
|
|
304
304
|
private cleanupTransformHandles;
|
|
305
|
-
render():
|
|
305
|
+
render(): lit_html3.TemplateResult<1>;
|
|
306
306
|
}
|
|
307
307
|
declare global {
|
|
308
308
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FrameRenderable, FrameState, FrameTask } from "../preview/FrameController.js";
|
|
2
2
|
import { EFMedia } from "./EFMedia.js";
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
3
|
+
import * as lit_html7 from "lit-html";
|
|
4
|
+
import * as lit_html_directives_ref_js2 from "lit-html/directives/ref.js";
|
|
5
5
|
|
|
6
6
|
//#region src/elements/EFAudio.d.ts
|
|
7
7
|
declare const EFAudio_base: typeof EFMedia;
|
|
@@ -17,9 +17,9 @@ declare class EFAudio extends EFAudio_base implements FrameRenderable {
|
|
|
17
17
|
* @domAttribute "volume"
|
|
18
18
|
*/
|
|
19
19
|
volume: number;
|
|
20
|
-
audioElementRef:
|
|
20
|
+
audioElementRef: lit_html_directives_ref_js2.Ref<HTMLAudioElement>;
|
|
21
21
|
protected updated(changedProperties: Map<PropertyKey, unknown>): void;
|
|
22
|
-
render():
|
|
22
|
+
render(): lit_html7.TemplateResult<1>;
|
|
23
23
|
/**
|
|
24
24
|
* @deprecated Use FrameRenderable methods (prepareFrame, renderFrame) via FrameController instead.
|
|
25
25
|
* This is a compatibility wrapper that delegates to the new system.
|
|
@@ -5,9 +5,9 @@ import { FetchMixinInterface } from "./FetchMixin.js";
|
|
|
5
5
|
import { AsyncValue } from "./EFMedia.js";
|
|
6
6
|
import { EFVideo } from "./EFVideo.js";
|
|
7
7
|
import { EFAudio } from "./EFAudio.js";
|
|
8
|
-
import * as
|
|
8
|
+
import * as lit1 from "lit";
|
|
9
9
|
import { LitElement, PropertyValueMap } from "lit";
|
|
10
|
-
import * as
|
|
10
|
+
import * as lit_html0 from "lit-html";
|
|
11
11
|
|
|
12
12
|
//#region src/elements/EFCaptions.d.ts
|
|
13
13
|
interface WordSegment {
|
|
@@ -65,7 +65,7 @@ declare class EFCaptionsAfterActiveWord extends EFCaptionsSegment {
|
|
|
65
65
|
declare const EFCaptions_base: (new (...args: any[]) => EFSourceMixinInterface) & (new (...args: any[]) => TemporalMixinInterface) & (new (...args: any[]) => FetchMixinInterface) & typeof LitElement;
|
|
66
66
|
declare class EFCaptions extends EFCaptions_base implements FrameRenderable {
|
|
67
67
|
#private;
|
|
68
|
-
static styles:
|
|
68
|
+
static styles: lit1.CSSResult[];
|
|
69
69
|
targetSelector: string;
|
|
70
70
|
set target(value: string);
|
|
71
71
|
wordStyle: string;
|
|
@@ -88,7 +88,7 @@ declare class EFCaptions extends EFCaptions_base implements FrameRenderable {
|
|
|
88
88
|
segmentContainers: HTMLCollectionOf<EFCaptionsSegment>;
|
|
89
89
|
beforeActiveWordContainers: HTMLCollectionOf<EFCaptionsBeforeActiveWord>;
|
|
90
90
|
afterActiveWordContainers: HTMLCollectionOf<EFCaptionsAfterActiveWord>;
|
|
91
|
-
render():
|
|
91
|
+
render(): lit_html0.TemplateResult<1>;
|
|
92
92
|
transcriptionsPath(): string | null;
|
|
93
93
|
captionsPath(): string | null;
|
|
94
94
|
/**
|
|
@@ -2,16 +2,16 @@ import { FrameRenderable, FrameState, FrameTask } from "../preview/FrameControll
|
|
|
2
2
|
import { EFSourceMixinInterface } from "./EFSourceMixin.js";
|
|
3
3
|
import { TemporalMixinInterface } from "./EFTemporal.js";
|
|
4
4
|
import { FetchMixinInterface } from "./FetchMixin.js";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit2 from "lit";
|
|
6
6
|
import { LitElement, PropertyValueMap } from "lit";
|
|
7
|
-
import * as
|
|
7
|
+
import * as lit_html1 from "lit-html";
|
|
8
8
|
import * as lit_html_directives_ref_js0 from "lit-html/directives/ref.js";
|
|
9
9
|
|
|
10
10
|
//#region src/elements/EFImage.d.ts
|
|
11
11
|
declare const EFImage_base: (new (...args: any[]) => TemporalMixinInterface) & (new (...args: any[]) => EFSourceMixinInterface) & (new (...args: any[]) => FetchMixinInterface) & typeof LitElement;
|
|
12
12
|
declare class EFImage extends EFImage_base implements FrameRenderable {
|
|
13
13
|
#private;
|
|
14
|
-
static styles:
|
|
14
|
+
static styles: lit2.CSSResult[];
|
|
15
15
|
imageRef: lit_html_directives_ref_js0.Ref<HTMLImageElement>;
|
|
16
16
|
canvasRef: lit_html_directives_ref_js0.Ref<HTMLCanvasElement>;
|
|
17
17
|
/**
|
|
@@ -22,7 +22,7 @@ declare class EFImage extends EFImage_base implements FrameRenderable {
|
|
|
22
22
|
get renderVersion(): number;
|
|
23
23
|
set assetId(value: string | null);
|
|
24
24
|
get assetId(): string | null;
|
|
25
|
-
render():
|
|
25
|
+
render(): lit_html1.TemplateResult<1>;
|
|
26
26
|
private isDirectUrl;
|
|
27
27
|
assetPath(): string;
|
|
28
28
|
get hasOwnDuration(): boolean;
|
|
@@ -5,7 +5,7 @@ import { FetchMixinInterface } from "./FetchMixin.js";
|
|
|
5
5
|
import { ControllableInterface } from "../gui/Controllable.js";
|
|
6
6
|
import { AudioSpan, MediaEngine } from "../transcoding/types/index.js";
|
|
7
7
|
import { UrlGenerator } from "../transcoding/utils/UrlGenerator.js";
|
|
8
|
-
import * as
|
|
8
|
+
import * as lit0 from "lit";
|
|
9
9
|
import { LitElement, PropertyValueMap } from "lit";
|
|
10
10
|
|
|
11
11
|
//#region src/elements/EFMedia.d.ts
|
|
@@ -57,7 +57,7 @@ declare class EFMedia extends EFMedia_base {
|
|
|
57
57
|
*/
|
|
58
58
|
get requiredTracks(): "audio" | "video" | "both";
|
|
59
59
|
static get observedAttributes(): string[];
|
|
60
|
-
static styles:
|
|
60
|
+
static styles: lit0.CSSResult[];
|
|
61
61
|
/**
|
|
62
62
|
* Duration in milliseconds for audio buffering ahead of current time
|
|
63
63
|
* @domAttribute "audio-buffer-duration"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit3 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html2 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/elements/EFPanZoom.d.ts
|
|
6
6
|
interface PanZoomTransform {
|
|
@@ -9,7 +9,7 @@ interface PanZoomTransform {
|
|
|
9
9
|
scale: number;
|
|
10
10
|
}
|
|
11
11
|
declare class EFPanZoom extends LitElement {
|
|
12
|
-
static styles:
|
|
12
|
+
static styles: lit3.CSSResult[];
|
|
13
13
|
x: number;
|
|
14
14
|
y: number;
|
|
15
15
|
scale: number;
|
|
@@ -89,7 +89,7 @@ declare class EFPanZoom extends LitElement {
|
|
|
89
89
|
* @param padding - Padding factor (0-1), e.g., 0.1 = 10% padding on each side. Default: 0.05
|
|
90
90
|
*/
|
|
91
91
|
fitToContent(padding?: number): void;
|
|
92
|
-
render():
|
|
92
|
+
render(): lit_html2.TemplateResult<1>;
|
|
93
93
|
}
|
|
94
94
|
//#endregion
|
|
95
95
|
export { EFPanZoom, PanZoomTransform };
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { FrameRenderable, FrameState } from "../preview/FrameController.js";
|
|
2
2
|
import { ContextMixinInterface } from "../gui/ContextMixin.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit28 from "lit";
|
|
4
4
|
import { LitElement } from "lit";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit_html27 from "lit-html";
|
|
6
6
|
import * as lit_html_directives_ref3 from "lit-html/directives/ref";
|
|
7
7
|
|
|
8
8
|
//#region src/elements/EFSurface.d.ts
|
|
9
9
|
declare class EFSurface extends LitElement implements FrameRenderable {
|
|
10
10
|
#private;
|
|
11
|
-
static styles:
|
|
11
|
+
static styles: lit28.CSSResult[];
|
|
12
12
|
canvasRef: lit_html_directives_ref3.Ref<HTMLCanvasElement>;
|
|
13
13
|
targetElement: ContextMixinInterface | null;
|
|
14
14
|
target: string;
|
|
15
|
-
render():
|
|
15
|
+
render(): lit_html27.TemplateResult<1>;
|
|
16
16
|
get rootTimegroup(): any;
|
|
17
17
|
get currentTimeMs(): number;
|
|
18
18
|
get durationMs(): number;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { TemporalMixinInterface } from "./EFTemporal.js";
|
|
2
2
|
import { EFTextSegment } from "./EFTextSegment.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit8 from "lit";
|
|
4
4
|
import { LitElement, PropertyValueMap } from "lit";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit_html9 from "lit-html";
|
|
6
6
|
|
|
7
7
|
//#region src/elements/EFText.d.ts
|
|
8
8
|
type SplitMode = "line" | "word" | "char";
|
|
9
9
|
declare const EFText_base: (new (...args: any[]) => TemporalMixinInterface) & typeof LitElement;
|
|
10
10
|
declare class EFText extends EFText_base {
|
|
11
11
|
#private;
|
|
12
|
-
static styles:
|
|
12
|
+
static styles: lit8.CSSResult[];
|
|
13
13
|
split: SplitMode;
|
|
14
14
|
private validateSplit;
|
|
15
15
|
staggerMs?: number;
|
|
@@ -20,7 +20,7 @@ declare class EFText extends EFText_base {
|
|
|
20
20
|
private _textContent;
|
|
21
21
|
private _templateElement;
|
|
22
22
|
private _segmentsReadyResolvers;
|
|
23
|
-
render():
|
|
23
|
+
render(): lit_html9.TemplateResult<1>;
|
|
24
24
|
set textContent(value: string | null);
|
|
25
25
|
get textContent(): string;
|
|
26
26
|
/**
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { TemporalMixinInterface } from "./EFTemporal.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit9 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html10 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/elements/EFTextSegment.d.ts
|
|
7
7
|
declare const EFTextSegment_base: (new (...args: any[]) => TemporalMixinInterface) & typeof LitElement;
|
|
8
8
|
declare class EFTextSegment extends EFTextSegment_base {
|
|
9
|
-
static styles:
|
|
9
|
+
static styles: lit9.CSSResult[];
|
|
10
10
|
/**
|
|
11
11
|
* Registers animation styles that should be shared across all text segments.
|
|
12
12
|
* This is the correct way to inject animation styles for segments - not via innerHTML.
|
|
@@ -32,7 +32,7 @@ declare class EFTextSegment extends EFTextSegment_base {
|
|
|
32
32
|
* @param id The identifier of the stylesheet to remove
|
|
33
33
|
*/
|
|
34
34
|
static unregisterAnimations(id: string): void;
|
|
35
|
-
render():
|
|
35
|
+
render(): lit_html10.TemplateResult<1>;
|
|
36
36
|
private setCSSVariables;
|
|
37
37
|
protected firstUpdated(): void;
|
|
38
38
|
protected updated(): void;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { EFVideo } from "./EFVideo.js";
|
|
2
2
|
import { EFTimegroup } from "./EFTimegroup.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit29 from "lit";
|
|
4
4
|
import { LitElement } from "lit";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit_html28 from "lit-html";
|
|
6
6
|
import * as lit_html_directives_ref4 from "lit-html/directives/ref";
|
|
7
7
|
|
|
8
8
|
//#region src/elements/EFThumbnailStrip.d.ts
|
|
9
9
|
declare class EFThumbnailStrip extends LitElement {
|
|
10
|
-
static styles:
|
|
10
|
+
static styles: lit29.CSSResult[];
|
|
11
11
|
canvasRef: lit_html_directives_ref4.Ref<HTMLCanvasElement>;
|
|
12
12
|
target: string;
|
|
13
13
|
thumbnailWidth: number;
|
|
@@ -155,7 +155,7 @@ declare class EFThumbnailStrip extends LitElement {
|
|
|
155
155
|
* Invalidate all cached thumbnails for this element.
|
|
156
156
|
*/
|
|
157
157
|
invalidateAll(): void;
|
|
158
|
-
render():
|
|
158
|
+
render(): lit_html28.TemplateResult<1>;
|
|
159
159
|
}
|
|
160
160
|
declare global {
|
|
161
161
|
interface HTMLElementTagNameMap {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FrameRenderable, FrameState, FrameTask } from "../preview/FrameController.js";
|
|
2
2
|
import { EFFramegen } from "../EF_FRAMEGEN.js";
|
|
3
3
|
import { EFMedia } from "./EFMedia.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit7 from "lit";
|
|
5
5
|
import { PropertyValueMap } from "lit";
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
6
|
+
import * as lit_html8 from "lit-html";
|
|
7
|
+
import * as lit_html_directives_ref2 from "lit-html/directives/ref";
|
|
8
8
|
|
|
9
9
|
//#region src/elements/EFVideo.d.ts
|
|
10
10
|
declare global {
|
|
@@ -23,8 +23,8 @@ interface LoadingState {
|
|
|
23
23
|
declare const EFVideo_base: typeof EFMedia;
|
|
24
24
|
declare class EFVideo extends EFVideo_base implements FrameRenderable {
|
|
25
25
|
#private;
|
|
26
|
-
static styles:
|
|
27
|
-
canvasRef:
|
|
26
|
+
static styles: lit7.CSSResult[];
|
|
27
|
+
canvasRef: lit_html_directives_ref2.Ref<HTMLCanvasElement>;
|
|
28
28
|
/**
|
|
29
29
|
* Duration in milliseconds for video buffering ahead of current time
|
|
30
30
|
* @domAttribute "video-buffer-duration"
|
|
@@ -76,7 +76,7 @@ declare class EFVideo extends EFVideo_base implements FrameRenderable {
|
|
|
76
76
|
};
|
|
77
77
|
constructor();
|
|
78
78
|
protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
79
|
-
render():
|
|
79
|
+
render(): lit_html8.TemplateResult<1>;
|
|
80
80
|
get canvasElement(): HTMLCanvasElement | undefined;
|
|
81
81
|
/**
|
|
82
82
|
* @deprecated Use FrameRenderable methods (prepareFrame, renderFrame) via FrameController instead.
|
|
@@ -3,16 +3,16 @@ import { TemporalMixinInterface } from "./EFTemporal.js";
|
|
|
3
3
|
import { EFVideo } from "./EFVideo.js";
|
|
4
4
|
import { EFAudio } from "./EFAudio.js";
|
|
5
5
|
import { TargetController } from "./TargetController.js";
|
|
6
|
-
import * as
|
|
6
|
+
import * as lit10 from "lit";
|
|
7
7
|
import { LitElement, PropertyValueMap } from "lit";
|
|
8
8
|
import { Ref } from "lit/directives/ref.js";
|
|
9
|
-
import * as
|
|
9
|
+
import * as lit_html11 from "lit-html";
|
|
10
10
|
|
|
11
11
|
//#region src/elements/EFWaveform.d.ts
|
|
12
12
|
declare const EFWaveform_base: (new (...args: any[]) => TemporalMixinInterface) & typeof LitElement;
|
|
13
13
|
declare class EFWaveform extends EFWaveform_base implements FrameRenderable {
|
|
14
14
|
#private;
|
|
15
|
-
static styles:
|
|
15
|
+
static styles: lit10.CSSResult;
|
|
16
16
|
canvasRef: Ref<HTMLCanvasElement>;
|
|
17
17
|
private ctx;
|
|
18
18
|
private styleObserver;
|
|
@@ -24,7 +24,7 @@ declare class EFWaveform extends EFWaveform_base implements FrameRenderable {
|
|
|
24
24
|
* @public
|
|
25
25
|
*/
|
|
26
26
|
get renderVersion(): number;
|
|
27
|
-
render():
|
|
27
|
+
render(): lit_html11.TemplateResult<1>;
|
|
28
28
|
mode: "roundBars" | "bars" | "bricks" | "line" | "curve" | "pixel" | "wave" | "spikes";
|
|
29
29
|
color: string;
|
|
30
30
|
target: string;
|
package/dist/getRenderInfo.d.ts
CHANGED
|
@@ -21,9 +21,9 @@ declare const RenderInfo: z.ZodObject<{
|
|
|
21
21
|
efImage: string[];
|
|
22
22
|
}>;
|
|
23
23
|
}, "strip", z.ZodTypeAny, {
|
|
24
|
-
fps: number;
|
|
25
24
|
width: number;
|
|
26
25
|
height: number;
|
|
26
|
+
fps: number;
|
|
27
27
|
durationMs: number;
|
|
28
28
|
assets: {
|
|
29
29
|
efMedia: Record<string, any>;
|
|
@@ -31,9 +31,9 @@ declare const RenderInfo: z.ZodObject<{
|
|
|
31
31
|
efImage: string[];
|
|
32
32
|
};
|
|
33
33
|
}, {
|
|
34
|
-
fps: number;
|
|
35
34
|
width: number;
|
|
36
35
|
height: number;
|
|
36
|
+
fps: number;
|
|
37
37
|
durationMs: number;
|
|
38
38
|
assets: {
|
|
39
39
|
efMedia: Record<string, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRenderInfo.js","names":[],"sources":["../src/getRenderInfo.ts"],"sourcesContent":["/**\n * THIS MODULE DOESNT USE THE DEBUG LOGGER BECAUSE IT IS\n * RUN IN A WEB BROWSER. LOGS ARE CAPTURED AND RE-LOGGED.\n *\n * A similar module exists in @/render. For the time being, we are\n * allowing this divergence to allow for a more efficient implementation\n * of the render info extraction.\n */\n\nimport type {\
|
|
1
|
+
{"version":3,"file":"getRenderInfo.js","names":[],"sources":["../src/getRenderInfo.ts"],"sourcesContent":["/**\n * THIS MODULE DOESNT USE THE DEBUG LOGGER BECAUSE IT IS\n * RUN IN A WEB BROWSER. LOGS ARE CAPTURED AND RE-LOGGED.\n *\n * A similar module exists in @/render. For the time being, we are\n * allowing this divergence to allow for a more efficient implementation\n * of the render info extraction.\n */\n\n// Import types directly from source files to avoid circular dependency through index.ts\nimport type { EFTimegroup } from \"./elements/EFTimegroup.js\";\nimport type { EFMedia } from \"./elements/EFMedia.js\";\nimport type { EFCaptions } from \"./elements/EFCaptions.js\";\nimport type { EFImage } from \"./elements/EFImage.js\";\nimport { z } from \"zod\";\n\nexport const RenderInfo = z.object({\n width: z.number().positive(),\n height: z.number().positive(),\n fps: z.number().positive(),\n durationMs: z.number().positive(),\n assets: z.object({\n efMedia: z.record(z.any()),\n efCaptions: z.array(z.string()),\n efImage: z.array(z.string()),\n }),\n});\n\nexport const getRenderInfo = async () => {\n const rootTimeGroup = document.querySelector(\"ef-timegroup\") as\n | EFTimegroup\n | undefined;\n if (!rootTimeGroup) {\n throw new Error(\"No ef-timegroup found\");\n }\n\n console.error(\"Waiting for media durations\", rootTimeGroup);\n await rootTimeGroup.waitForMediaDurations();\n\n const width = rootTimeGroup.clientWidth;\n const height = rootTimeGroup.clientHeight;\n const fps = 30;\n const durationMs = Math.round(rootTimeGroup.durationMs);\n\n const elements = document.querySelectorAll(\n \"ef-audio, ef-video, ef-image, ef-captions\",\n );\n\n const assets = {\n efMedia: <Record<string, any>>{},\n efCaptions: new Set<string>(),\n efImage: new Set<string>(),\n };\n\n for (const element of elements) {\n switch (element.tagName) {\n case \"EF-AUDIO\":\n case \"EF-VIDEO\": {\n const src = (element as EFMedia).src;\n console.error(\"Processing element\", element.tagName, src);\n // Access fragment index data from the media engine task\n const mediaEngine = (element as EFMedia).mediaEngineTask.value;\n if (mediaEngine && \"data\" in mediaEngine) {\n assets.efMedia[src] = (mediaEngine as any).data;\n }\n break;\n }\n case \"EF-IMAGE\": {\n const src = (element as EFImage).src;\n console.error(\"Processing element\", element.tagName, src);\n assets.efImage.add(src);\n break;\n }\n case \"EF-CAPTIONS\": {\n const src = (element as EFCaptions).targetElement?.src;\n console.error(\"Processing element\", element.tagName, src);\n assets.efCaptions.add(src ?? \"undefined\");\n break;\n }\n }\n }\n\n const renderInfo = {\n width,\n height,\n fps,\n durationMs,\n assets: {\n efMedia: assets.efMedia,\n efCaptions: Array.from(assets.efCaptions),\n efImage: Array.from(assets.efImage),\n },\n };\n\n console.error(\"Render info\", renderInfo);\n\n return renderInfo;\n};\n"],"mappings":";;;AAgBA,MAAa,aAAa,EAAE,OAAO;CACjC,OAAO,EAAE,QAAQ,CAAC,UAAU;CAC5B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,KAAK,EAAE,QAAQ,CAAC,UAAU;CAC1B,YAAY,EAAE,QAAQ,CAAC,UAAU;CACjC,QAAQ,EAAE,OAAO;EACf,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC;EAC1B,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC;EAC/B,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC;EAC7B,CAAC;CACH,CAAC;AAEF,MAAa,gBAAgB,YAAY;CACvC,MAAM,gBAAgB,SAAS,cAAc,eAAe;AAG5D,KAAI,CAAC,cACH,OAAM,IAAI,MAAM,wBAAwB;AAG1C,SAAQ,MAAM,+BAA+B,cAAc;AAC3D,OAAM,cAAc,uBAAuB;CAE3C,MAAM,QAAQ,cAAc;CAC5B,MAAM,SAAS,cAAc;CAC7B,MAAM,MAAM;CACZ,MAAM,aAAa,KAAK,MAAM,cAAc,WAAW;CAEvD,MAAM,WAAW,SAAS,iBACxB,4CACD;CAED,MAAM,SAAS;EACb,SAA8B,EAAE;EAChC,4BAAY,IAAI,KAAa;EAC7B,yBAAS,IAAI,KAAa;EAC3B;AAED,MAAK,MAAM,WAAW,SACpB,SAAQ,QAAQ,SAAhB;EACE,KAAK;EACL,KAAK,YAAY;GACf,MAAM,MAAO,QAAoB;AACjC,WAAQ,MAAM,sBAAsB,QAAQ,SAAS,IAAI;GAEzD,MAAM,cAAe,QAAoB,gBAAgB;AACzD,OAAI,eAAe,UAAU,YAC3B,QAAO,QAAQ,OAAQ,YAAoB;AAE7C;;EAEF,KAAK,YAAY;GACf,MAAM,MAAO,QAAoB;AACjC,WAAQ,MAAM,sBAAsB,QAAQ,SAAS,IAAI;AACzD,UAAO,QAAQ,IAAI,IAAI;AACvB;;EAEF,KAAK,eAAe;GAClB,MAAM,MAAO,QAAuB,eAAe;AACnD,WAAQ,MAAM,sBAAsB,QAAQ,SAAS,IAAI;AACzD,UAAO,WAAW,IAAI,OAAO,YAAY;AACzC;;;CAKN,MAAM,aAAa;EACjB;EACA;EACA;EACA;EACA,QAAQ;GACN,SAAS,OAAO;GAChB,YAAY,MAAM,KAAK,OAAO,WAAW;GACzC,SAAS,MAAM,KAAK,OAAO,QAAQ;GACpC;EACF;AAED,SAAQ,MAAM,eAAe,WAAW;AAExC,QAAO"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit22 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html22 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFActiveRootTemporal.d.ts
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ import * as lit_html20 from "lit-html";
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
declare class EFActiveRootTemporal extends LitElement {
|
|
17
|
-
static styles:
|
|
17
|
+
static styles: lit22.CSSResult;
|
|
18
18
|
/**
|
|
19
19
|
* Canvas element ID or selector to bind to.
|
|
20
20
|
* If not specified, will search for the nearest ef-canvas ancestor.
|
|
@@ -38,7 +38,7 @@ declare class EFActiveRootTemporal extends LitElement {
|
|
|
38
38
|
* Remove event listener.
|
|
39
39
|
*/
|
|
40
40
|
private removeListener;
|
|
41
|
-
render():
|
|
41
|
+
render(): lit_html22.TemplateResult<1>;
|
|
42
42
|
}
|
|
43
43
|
declare global {
|
|
44
44
|
interface HTMLElementTagNameMap {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit11 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html12 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFConfiguration.d.ts
|
|
6
6
|
declare class EFConfiguration extends LitElement {
|
|
7
|
-
static styles:
|
|
7
|
+
static styles: lit11.CSSResult[];
|
|
8
8
|
efConfiguration: this;
|
|
9
9
|
apiHost?: string;
|
|
10
10
|
signingURL: string;
|
|
@@ -15,7 +15,7 @@ declare class EFConfiguration extends LitElement {
|
|
|
15
15
|
* - "jit": Force JitMediaEngine for all sources (uses /api/v1/transcode/* URLs)
|
|
16
16
|
*/
|
|
17
17
|
mediaEngine?: "cloud" | "local" | "jit";
|
|
18
|
-
render():
|
|
18
|
+
render(): lit_html12.TemplateResult<1>;
|
|
19
19
|
}
|
|
20
20
|
declare global {
|
|
21
21
|
interface HTMLElementTagNameMap {
|
package/dist/gui/EFControls.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TemporalMixinInterface } from "../elements/EFTemporal.js";
|
|
2
2
|
import { ControllableInterface } from "./Controllable.js";
|
|
3
3
|
import { FocusContext } from "./focusContext.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit24 from "lit";
|
|
5
5
|
import { LitElement, PropertyValueMap } from "lit";
|
|
6
6
|
|
|
7
7
|
//#region src/gui/EFControls.d.ts
|
|
@@ -26,7 +26,7 @@ import { LitElement, PropertyValueMap } from "lit";
|
|
|
26
26
|
*/
|
|
27
27
|
declare class EFControls extends LitElement {
|
|
28
28
|
#private;
|
|
29
|
-
static styles:
|
|
29
|
+
static styles: lit24.CSSResult;
|
|
30
30
|
createRenderRoot(): this;
|
|
31
31
|
/**
|
|
32
32
|
* The ID of the ef-preview element to control
|
package/dist/gui/EFDial.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit23 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html23 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFDial.d.ts
|
|
6
6
|
interface DialChangeDetail {
|
|
@@ -13,12 +13,12 @@ declare class EFDial extends LitElement {
|
|
|
13
13
|
private isDragging;
|
|
14
14
|
private dragStartAngle;
|
|
15
15
|
private dragStartValue;
|
|
16
|
-
static styles:
|
|
16
|
+
static styles: lit23.CSSResult;
|
|
17
17
|
private getAngleFromPoint;
|
|
18
18
|
private handlePointerDown;
|
|
19
19
|
private handlePointerMove;
|
|
20
20
|
private handlePointerUp;
|
|
21
|
-
render():
|
|
21
|
+
render(): lit_html23.TemplateResult<1>;
|
|
22
22
|
}
|
|
23
23
|
//#endregion
|
|
24
24
|
export { DialChangeDetail, EFDial };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TemporalMixinInterface } from "../elements/EFTemporal.js";
|
|
2
2
|
import "./timeline/EFTimeline.js";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html5 from "lit-html";
|
|
5
5
|
import * as lit_html_directives_ref0 from "lit-html/directives/ref";
|
|
6
6
|
|
|
7
7
|
//#region src/gui/EFFilmstrip.d.ts
|
|
@@ -22,7 +22,7 @@ declare class EFFilmstrip extends EFFilmstrip_base {
|
|
|
22
22
|
timelineRef: lit_html_directives_ref0.Ref<HTMLElement>;
|
|
23
23
|
connectedCallback(): void;
|
|
24
24
|
protected willUpdate(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
25
|
-
render():
|
|
25
|
+
render(): lit_html5.TemplateResult<1>;
|
|
26
26
|
}
|
|
27
27
|
declare global {
|
|
28
28
|
interface HTMLElementTagNameMap {
|
package/dist/gui/EFFitScale.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { LitElement } from "lit";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit_html_directives_ref0 from "lit-html/directives/ref";
|
|
3
3
|
|
|
4
4
|
//#region src/gui/EFFitScale.d.ts
|
|
5
5
|
declare class EFFitScale extends LitElement {
|
|
6
|
-
containerRef:
|
|
7
|
-
contentRef:
|
|
6
|
+
containerRef: lit_html_directives_ref0.Ref<HTMLDivElement>;
|
|
7
|
+
contentRef: lit_html_directives_ref0.Ref<HTMLSlotElement>;
|
|
8
8
|
createRenderRoot(): this;
|
|
9
9
|
uniqueId: string;
|
|
10
10
|
private scale;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit25 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html24 from "lit-html";
|
|
4
4
|
import * as lit_html_directives_ref_js3 from "lit-html/directives/ref.js";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFFocusOverlay.d.ts
|
|
7
7
|
declare class EFFocusOverlay extends LitElement {
|
|
8
|
-
static styles:
|
|
8
|
+
static styles: lit25.CSSResult;
|
|
9
9
|
focusedElement?: HTMLElement | null;
|
|
10
10
|
overlay: lit_html_directives_ref_js3.Ref<HTMLDivElement>;
|
|
11
11
|
private animationFrame?;
|
|
12
12
|
drawOverlay: () => void;
|
|
13
|
-
render():
|
|
13
|
+
render(): lit_html24.TemplateResult<1>;
|
|
14
14
|
connectedCallback(): void;
|
|
15
15
|
disconnectedCallback(): void;
|
|
16
16
|
protected updated(): void;
|
package/dist/gui/EFPause.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit18 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html18 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFPause.d.ts
|
|
7
7
|
declare const EFPause_base: (new (...args: any[]) => {
|
|
@@ -10,13 +10,13 @@ declare const EFPause_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFPause extends EFPause_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit18.CSSResult[];
|
|
14
14
|
playing: boolean;
|
|
15
15
|
get efContext(): ControllableInterface | null;
|
|
16
16
|
connectedCallback(): void;
|
|
17
17
|
disconnectedCallback(): void;
|
|
18
18
|
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
19
|
-
render():
|
|
19
|
+
render(): lit_html18.TemplateResult<1>;
|
|
20
20
|
handleClick: () => void;
|
|
21
21
|
}
|
|
22
22
|
declare global {
|
package/dist/gui/EFPlay.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit17 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html17 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFPlay.d.ts
|
|
7
7
|
declare const EFPlay_base: (new (...args: any[]) => {
|
|
@@ -10,13 +10,13 @@ declare const EFPlay_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFPlay extends EFPlay_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit17.CSSResult[];
|
|
14
14
|
playing: boolean;
|
|
15
15
|
get efContext(): ControllableInterface | null;
|
|
16
16
|
connectedCallback(): void;
|
|
17
17
|
disconnectedCallback(): void;
|
|
18
18
|
updated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
19
|
-
render():
|
|
19
|
+
render(): lit_html17.TemplateResult<1>;
|
|
20
20
|
handleClick: () => void;
|
|
21
21
|
}
|
|
22
22
|
declare global {
|
package/dist/gui/EFPreview.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { ContextMixinInterface } from "./ContextMixin.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit12 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html13 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFPreview.d.ts
|
|
7
7
|
declare const EFPreview_base: (new (...args: any[]) => ContextMixinInterface) & typeof LitElement;
|
|
8
8
|
declare class EFPreview extends EFPreview_base {
|
|
9
|
-
static styles:
|
|
9
|
+
static styles: lit12.CSSResult[];
|
|
10
10
|
focusedElement?: HTMLElement;
|
|
11
11
|
/**
|
|
12
12
|
* Find the closest temporal element (timegroup, video, audio, etc.)
|
|
13
13
|
*/
|
|
14
14
|
private findClosestTemporal;
|
|
15
15
|
constructor();
|
|
16
|
-
render():
|
|
16
|
+
render(): lit_html13.TemplateResult<1>;
|
|
17
17
|
}
|
|
18
18
|
declare global {
|
|
19
19
|
interface HTMLElementTagNameMap {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit27 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html26 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFResizableBox.d.ts
|
|
6
6
|
interface BoxBounds {
|
|
@@ -21,7 +21,7 @@ declare class EFResizableBox extends LitElement {
|
|
|
21
21
|
private resizeStartCorner;
|
|
22
22
|
private resizeStartSize;
|
|
23
23
|
private resizeStartPosition;
|
|
24
|
-
static styles:
|
|
24
|
+
static styles: lit27.CSSResult;
|
|
25
25
|
private resizeObserver?;
|
|
26
26
|
connectedCallback(): void;
|
|
27
27
|
disconnectedCallback(): void;
|
|
@@ -30,7 +30,7 @@ declare class EFResizableBox extends LitElement {
|
|
|
30
30
|
private handlePointerUp;
|
|
31
31
|
private cleanup;
|
|
32
32
|
private dispatchBoundsChange;
|
|
33
|
-
render():
|
|
33
|
+
render(): lit_html26.TemplateResult<1>;
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
36
|
export { BoxBounds, EFResizableBox };
|
package/dist/gui/EFScrubber.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit20 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html20 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFScrubber.d.ts
|
|
7
7
|
declare const EFScrubber_base: (new (...args: any[]) => {
|
|
@@ -10,7 +10,7 @@ declare const EFScrubber_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFScrubber extends EFScrubber_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit20.CSSResult[];
|
|
14
14
|
playing: boolean;
|
|
15
15
|
contextCurrentTimeMs: number;
|
|
16
16
|
contextDurationMs: number;
|
|
@@ -50,7 +50,7 @@ declare class EFScrubber extends EFScrubber_base {
|
|
|
50
50
|
private boundHandlePointerUp;
|
|
51
51
|
private boundHandlePointerCancel;
|
|
52
52
|
private boundHandleContextMenu;
|
|
53
|
-
render():
|
|
53
|
+
render(): lit_html20.TemplateResult<1>;
|
|
54
54
|
connectedCallback(): void;
|
|
55
55
|
disconnectedCallback(): void;
|
|
56
56
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit21 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html21 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFTimeDisplay.d.ts
|
|
7
7
|
declare const EFTimeDisplay_base: (new (...args: any[]) => {
|
|
@@ -10,11 +10,11 @@ declare const EFTimeDisplay_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFTimeDisplay extends EFTimeDisplay_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit21.CSSResult;
|
|
14
14
|
currentTimeMs: number;
|
|
15
15
|
durationMs: number;
|
|
16
16
|
private formatTime;
|
|
17
|
-
render():
|
|
17
|
+
render(): lit_html21.TemplateResult<1>;
|
|
18
18
|
}
|
|
19
19
|
declare global {
|
|
20
20
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit19 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html19 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFToggleLoop.d.ts
|
|
7
7
|
declare const EFToggleLoop_base: (new (...args: any[]) => {
|
|
@@ -10,9 +10,9 @@ declare const EFToggleLoop_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFToggleLoop extends EFToggleLoop_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit19.CSSResult[];
|
|
14
14
|
get context(): ControllableInterface | null;
|
|
15
|
-
render():
|
|
15
|
+
render(): lit_html19.TemplateResult<1>;
|
|
16
16
|
}
|
|
17
17
|
declare global {
|
|
18
18
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ControllableInterface } from "./Controllable.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit16 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html16 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFTogglePlay.d.ts
|
|
7
7
|
declare const EFTogglePlay_base: (new (...args: any[]) => {
|
|
@@ -10,12 +10,12 @@ declare const EFTogglePlay_base: (new (...args: any[]) => {
|
|
|
10
10
|
effectiveContext: ControllableInterface | null;
|
|
11
11
|
}) & typeof LitElement;
|
|
12
12
|
declare class EFTogglePlay extends EFTogglePlay_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit16.CSSResult[];
|
|
14
14
|
playing: boolean;
|
|
15
15
|
get efContext(): ControllableInterface | null;
|
|
16
16
|
connectedCallback(): void;
|
|
17
17
|
disconnectedCallback(): void;
|
|
18
|
-
render():
|
|
18
|
+
render(): lit_html16.TemplateResult<1>;
|
|
19
19
|
togglePlay: () => void;
|
|
20
20
|
private getPlaybackController;
|
|
21
21
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PanZoomTransform } from "../elements/EFPanZoom.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit26 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html25 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFTransformHandles.d.ts
|
|
7
7
|
interface TransformBounds {
|
|
@@ -49,7 +49,7 @@ declare class EFTransformHandles extends LitElement {
|
|
|
49
49
|
* Note: Not a @state() property to avoid re-renders during interaction.
|
|
50
50
|
*/
|
|
51
51
|
private initialBounds;
|
|
52
|
-
static styles:
|
|
52
|
+
static styles: lit26.CSSResult;
|
|
53
53
|
private resizeObserver?;
|
|
54
54
|
/**
|
|
55
55
|
* Single source of truth for zoom scale.
|
|
@@ -79,7 +79,7 @@ declare class EFTransformHandles extends LitElement {
|
|
|
79
79
|
private handleMouseMove;
|
|
80
80
|
private handleMouseUp;
|
|
81
81
|
private cleanup;
|
|
82
|
-
render():
|
|
82
|
+
render(): lit_html25.TemplateResult<1>;
|
|
83
83
|
}
|
|
84
84
|
declare global {
|
|
85
85
|
interface HTMLElementTagNameMap {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { ContextMixinInterface } from "./ContextMixin.js";
|
|
2
2
|
import { RenderToVideoOptions } from "../preview/renderTimegroupToVideo.js";
|
|
3
3
|
import "./EFFitScale.js";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit6 from "lit";
|
|
5
5
|
import { LitElement, PropertyValueMap } from "lit";
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
6
|
+
import * as lit_html6 from "lit-html";
|
|
7
|
+
import * as lit_html_directives_ref_js1 from "lit-html/directives/ref.js";
|
|
8
8
|
|
|
9
9
|
//#region src/gui/EFWorkbench.d.ts
|
|
10
10
|
declare const EFWorkbench_base: (new (...args: any[]) => ContextMixinInterface) & typeof LitElement;
|
|
11
11
|
declare class EFWorkbench extends EFWorkbench_base {
|
|
12
|
-
static styles:
|
|
12
|
+
static styles: lit6.CSSResult[];
|
|
13
13
|
rendering: boolean;
|
|
14
14
|
private panZoomTransform;
|
|
15
15
|
private isExporting;
|
|
@@ -61,7 +61,7 @@ declare class EFWorkbench extends EFWorkbench_base {
|
|
|
61
61
|
private canvasPreviewResult;
|
|
62
62
|
private canvasAnimationFrame;
|
|
63
63
|
private boundHandleTransformChanged;
|
|
64
|
-
focusOverlay:
|
|
64
|
+
focusOverlay: lit_html_directives_ref_js1.Ref<HTMLDivElement>;
|
|
65
65
|
handleStageWheel(event: WheelEvent): void;
|
|
66
66
|
connectedCallback(): void;
|
|
67
67
|
disconnectedCallback(): void;
|
|
@@ -194,7 +194,7 @@ declare class EFWorkbench extends EFWorkbench_base {
|
|
|
194
194
|
updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
|
|
195
195
|
drawOverlays: () => void;
|
|
196
196
|
private renderPlaybackStats;
|
|
197
|
-
render():
|
|
197
|
+
render(): lit_html6.TemplateResult<1>;
|
|
198
198
|
}
|
|
199
199
|
declare global {
|
|
200
200
|
interface HTMLElementTagNameMap {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SelectionContext } from "../../canvas/selection/selectionContext.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit5 from "lit";
|
|
3
3
|
import { LitElement, PropertyValues } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html4 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/hierarchy/EFHierarchy.d.ts
|
|
7
7
|
declare const EFHierarchy_base: typeof LitElement;
|
|
8
8
|
declare class EFHierarchy extends EFHierarchy_base {
|
|
9
|
-
static styles:
|
|
9
|
+
static styles: lit5.CSSResult[];
|
|
10
10
|
target: string;
|
|
11
11
|
header: string;
|
|
12
12
|
showHeader: boolean;
|
|
@@ -53,7 +53,7 @@ declare class EFHierarchy extends EFHierarchy_base {
|
|
|
53
53
|
private autoSelectFirstRootTimegroup;
|
|
54
54
|
private setupSelectionListener;
|
|
55
55
|
private removeSelectionListener;
|
|
56
|
-
render():
|
|
56
|
+
render(): lit_html4.TemplateResult<1>;
|
|
57
57
|
}
|
|
58
58
|
declare global {
|
|
59
59
|
interface HTMLElementTagNameMap {
|
|
@@ -4,13 +4,13 @@ import { EFAudio } from "../../elements/EFAudio.js";
|
|
|
4
4
|
import { EFTimegroup } from "../../elements/EFTimegroup.js";
|
|
5
5
|
import { EFImage } from "../../elements/EFImage.js";
|
|
6
6
|
import { HierarchyContext } from "./hierarchyContext.js";
|
|
7
|
-
import * as
|
|
7
|
+
import * as lit13 from "lit";
|
|
8
8
|
import { LitElement, PropertyValues, TemplateResult, nothing } from "lit";
|
|
9
9
|
|
|
10
10
|
//#region src/gui/hierarchy/EFHierarchyItem.d.ts
|
|
11
11
|
declare const EFHierarchyItem_base: typeof LitElement;
|
|
12
12
|
declare class EFHierarchyItem<ElementType extends HTMLElement = HTMLElement> extends EFHierarchyItem_base {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit13.CSSResult[];
|
|
14
14
|
hierarchyContext?: HierarchyContext;
|
|
15
15
|
canvasSelectionContext?: SelectionContext;
|
|
16
16
|
element: ElementType;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { TreeItem } from "./treeContext.js";
|
|
2
2
|
import "./EFTreeItem.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit14 from "lit";
|
|
4
4
|
import { LitElement, PropertyValues } from "lit";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit_html14 from "lit-html";
|
|
6
6
|
|
|
7
7
|
//#region src/gui/tree/EFTree.d.ts
|
|
8
8
|
|
|
@@ -29,7 +29,7 @@ import * as lit_html12 from "lit-html";
|
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
declare class EFTree extends LitElement {
|
|
32
|
-
static styles:
|
|
32
|
+
static styles: lit14.CSSResult;
|
|
33
33
|
/** Tree items to display */
|
|
34
34
|
items: TreeItem[];
|
|
35
35
|
/** Optional header text */
|
|
@@ -48,7 +48,7 @@ declare class EFTree extends LitElement {
|
|
|
48
48
|
protected willUpdate(changedProperties: PropertyValues): void;
|
|
49
49
|
protected updated(changedProperties: PropertyValues): void;
|
|
50
50
|
connectedCallback(): void;
|
|
51
|
-
render():
|
|
51
|
+
render(): lit_html14.TemplateResult<1>;
|
|
52
52
|
}
|
|
53
53
|
declare global {
|
|
54
54
|
interface HTMLElementTagNameMap {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { TreeContext, TreeItem } from "./treeContext.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit15 from "lit";
|
|
3
3
|
import { LitElement, nothing } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html15 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/tree/EFTreeItem.d.ts
|
|
7
7
|
|
|
@@ -17,7 +17,7 @@ import * as lit_html13 from "lit-html";
|
|
|
17
17
|
* @fires tree-item-click - When item is clicked (for selection)
|
|
18
18
|
*/
|
|
19
19
|
declare class EFTreeItem extends LitElement {
|
|
20
|
-
static styles:
|
|
20
|
+
static styles: lit15.CSSResult;
|
|
21
21
|
treeContext?: TreeContext;
|
|
22
22
|
item: TreeItem;
|
|
23
23
|
private localExpanded;
|
|
@@ -26,7 +26,7 @@ declare class EFTreeItem extends LitElement {
|
|
|
26
26
|
get hasChildren(): boolean;
|
|
27
27
|
private handleClick;
|
|
28
28
|
private handleExpandClick;
|
|
29
|
-
render():
|
|
29
|
+
render(): lit_html15.TemplateResult<1> | typeof nothing;
|
|
30
30
|
}
|
|
31
31
|
declare global {
|
|
32
32
|
interface HTMLElementTagNameMap {
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { EFMedia } from "./elements/EFMedia.js";
|
|
2
|
+
import { ContainerInfo } from "./elements/ContainerInfo.js";
|
|
3
|
+
import { ElementPositionInfo } from "./elements/ElementPositionInfo.js";
|
|
4
|
+
import { EFCaptions } from "./elements/EFCaptions.js";
|
|
5
|
+
import { EFTimegroup } from "./elements/EFTimegroup.js";
|
|
6
|
+
import { EFImage } from "./elements/EFImage.js";
|
|
7
|
+
import { RenderInfo, getRenderInfo } from "./getRenderInfo.js";
|
|
8
|
+
export { type ContainerInfo, type EFCaptions, type EFImage, type EFMedia, type EFTimegroup, type ElementPositionInfo, RenderInfo, getRenderInfo };
|
package/dist/node.js
ADDED
|
@@ -26,11 +26,12 @@ var ContentNotReadyError = class extends Error {
|
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
28
28
|
* Module-level state for render operations.
|
|
29
|
+
* Note: xmlSerializer is lazy-initialized for Node.js compatibility
|
|
29
30
|
*/
|
|
30
31
|
const renderState = {
|
|
31
32
|
inlineImageCache: /* @__PURE__ */ new Map(),
|
|
32
33
|
layoutInitializedCanvases: /* @__PURE__ */ new WeakSet(),
|
|
33
|
-
xmlSerializer:
|
|
34
|
+
xmlSerializer: null,
|
|
34
35
|
textEncoder: new TextEncoder(),
|
|
35
36
|
metrics: {
|
|
36
37
|
inlineImageCacheHits: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderTimegroupToCanvas.js","names":["timeMs: number","timeoutMs: number","blankVideos: string[]","renderState: RenderState","scaleColors: Record<number, string>","image: HTMLCanvasElement | HTMLImageElement","options: CanvasPreviewOptions","pendingResolutionScale: number | null"],"sources":["../../src/preview/renderTimegroupToCanvas.ts"],"sourcesContent":["import type { EFTimegroup } from \"../elements/EFTimegroup.js\";\nimport {\n buildCloneStructure,\n syncStyles,\n collectDocumentStyles,\n overrideRootCloneStyles,\n removeHiddenNodesForSerialization,\n restoreHiddenNodes,\n type SyncState,\n} from \"./renderTimegroupPreview.js\";\nimport { getEffectiveRenderMode } from \"./renderers.js\";\nimport { RenderContext } from \"./RenderContext.js\";\nimport { FrameController } from \"./FrameController.js\";\n\n// Re-export renderer types for external use\nexport type { RenderOptions, RenderResult, Renderer } from \"./renderers.js\";\nexport { getEffectiveRenderMode, isCanvas, isImage } from \"./renderers.js\";\nimport {\n type TemporalElement,\n isVisibleAtTime,\n DEFAULT_WIDTH,\n DEFAULT_HEIGHT,\n DEFAULT_THUMBNAIL_SCALE,\n DEFAULT_BLOCKING_TIMEOUT_MS,\n createPreviewContainer,\n} from \"./previewTypes.js\";\nimport { defaultProfiler } from \"./RenderProfiler.js\";\nimport { logger } from \"./logger.js\";\n\n// Import rendering modules\nimport {\n renderToImage,\n renderToImageDirect,\n prepareFrameDataUri,\n loadImageFromDataUri,\n} from \"./rendering/renderToImage.js\";\nimport { renderToImageNative, createDprCanvas } from \"./rendering/renderToImageNative.js\";\nimport { clearInlineImageCache, getInlineImageCacheSize } from \"./rendering/inlineImages.js\";\n\n// Re-export rendering types and functions for external use\nexport type {\n NativeRenderOptions,\n ForeignObjectRenderOptions,\n} from \"./rendering/types.js\";\nexport {\n renderToImage,\n renderToImageNative,\n renderToImageDirect,\n prepareFrameDataUri,\n loadImageFromDataUri,\n};\n\n// ============================================================================\n// Constants (module-specific, not shared)\n// ============================================================================\n\n/** Number of rows to sample when checking canvas content */\nconst CANVAS_SAMPLE_STRIP_HEIGHT = 4;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Content readiness strategy for capture operations.\n * - \"immediate\": Capture NOW, skip all waits. May have blank video frames.\n * - \"blocking\": Wait for video content to be ready. Throws on timeout.\n */\nexport type ContentReadyMode = \"immediate\" | \"blocking\";\n\n/**\n * Options for capturing a timegroup frame.\n */\nexport interface CaptureOptions {\n /** Time to capture at in milliseconds (required) */\n timeMs: number;\n /** Scale factor (default: 0.25 for captureTimegroupAtTime) */\n scale?: number;\n /** Skip restoring original time after capture (for batch operations) */\n skipRestore?: boolean;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n}\n\n/**\n * Options for batch capture operations, excluding timeMs which is provided per-timestamp.\n */\nexport interface CaptureBatchOptions {\n /** Scale factor for thumbnails (default: 0.25) */\n scale?: number;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n}\n\n/**\n * Error thrown when video content is not ready within the blocking timeout.\n */\nexport class ContentNotReadyError extends Error {\n constructor(\n public readonly timeMs: number,\n public readonly timeoutMs: number,\n public readonly blankVideos: string[],\n ) {\n super(`Video content not ready at ${timeMs}ms after ${timeoutMs}ms timeout. Blank videos: ${blankVideos.join(', ')}`);\n this.name = 'ContentNotReadyError';\n }\n}\n\n// ============================================================================\n// Module State (reset via resetRenderState)\n// ============================================================================\n\n/**\n * Module-level render state including caches and reusable objects.\n */\ninterface RenderState {\n inlineImageCache: Map<string, string>;\n layoutInitializedCanvases: WeakSet<HTMLCanvasElement>;\n xmlSerializer: XMLSerializer;\n textEncoder: TextEncoder;\n metrics: {\n inlineImageCacheHits: number;\n inlineImageCacheMisses: number;\n inlineImageCacheEvictions: number;\n };\n}\n\n/**\n * Module-level state for render operations.\n */\nconst renderState: RenderState = {\n inlineImageCache: new Map(),\n layoutInitializedCanvases: new WeakSet(),\n xmlSerializer: new XMLSerializer(),\n textEncoder: new TextEncoder(),\n metrics: {\n inlineImageCacheHits: 0,\n inlineImageCacheMisses: 0,\n inlineImageCacheEvictions: 0,\n },\n};\n\n/**\n * Get the current render state for testing and debugging.\n * @returns The module-level render state object\n */\nexport function getRenderState(): RenderState {\n return renderState;\n}\n\n/**\n * Get cache metrics for monitoring performance.\n * @returns Object with cache hit/miss/eviction counts\n */\nexport function getCacheMetrics(): RenderState['metrics'] {\n return { ...renderState.metrics };\n}\n\n/**\n * Reset cache metrics to zero.\n */\nexport function resetCacheMetrics(): void {\n renderState.metrics.inlineImageCacheHits = 0;\n renderState.metrics.inlineImageCacheMisses = 0;\n renderState.metrics.inlineImageCacheEvictions = 0;\n}\n\n/**\n * Reset all module state including profiling counters, caches, and logging flags.\n * Call at the start of export sessions to ensure clean state.\n */\nexport function resetRenderState(): void {\n defaultProfiler.reset();\n clearInlineImageCache();\n resetCacheMetrics();\n}\n\n// Re-export cache management functions\nexport { clearInlineImageCache, getInlineImageCacheSize };\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Create a debug label for showing render info.\n */\nfunction createDebugLabel(): HTMLDivElement {\n const debugLabel = document.createElement(\"div\");\n debugLabel.style.cssText = `\n position: absolute;\n top: -24px;\n left: 0;\n padding: 2px 8px;\n font: bold 12px monospace;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 3px;\n white-space: nowrap;\n z-index: 1000;\n pointer-events: none;\n `;\n return debugLabel;\n}\n\n/**\n * Update debug label with resolution info.\n */\nfunction updateDebugLabel(\n label: HTMLDivElement,\n renderWidth: number,\n renderHeight: number,\n resolutionScale: number,\n): void {\n const scaleColors: Record<number, string> = {\n 1: \"#00ff00\",\n 0.75: \"#ffff00\",\n 0.5: \"#ff8800\",\n 0.25: \"#ff0000\",\n };\n label.style.color = scaleColors[resolutionScale] || \"#ffffff\";\n label.textContent = `Render: ${renderWidth}x${renderHeight} (${Math.round(resolutionScale * 100)}%)`;\n}\n\n/**\n * Wait for next animation frame (allows browser to complete layout)\n */\nfunction waitForFrame(): Promise<void> {\n return new Promise(resolve => requestAnimationFrame(() => resolve()));\n}\n\n/**\n * Check if a canvas has any rendered content (not all transparent/uninitialized).\n * Returns true if there's ANY non-transparent pixel.\n */\nfunction canvasHasContent(canvas: HTMLCanvasElement): boolean {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return false;\n \n try {\n const width = canvas.width;\n const height = canvas.height;\n if (width === 0 || height === 0) return false;\n \n // Sample a horizontal strip across the middle of the canvas\n // This catches most video content even if edges are black\n const stripY = Math.floor(height / 2);\n const imageData = ctx.getImageData(0, stripY, width, CANVAS_SAMPLE_STRIP_HEIGHT);\n const data = imageData.data;\n \n // Check if ANY pixel has non-zero alpha (is not transparent)\n // A truly blank/uninitialized canvas has all pixels at [0,0,0,0]\n // A black video frame would have pixels at [0,0,0,255] (opaque black)\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] !== 0) {\n return true;\n }\n }\n \n return false;\n } catch {\n // Canvas might be tainted, assume it has content\n return true;\n }\n}\n\ninterface WaitForVideoContentResult {\n ready: boolean;\n blankVideos: string[];\n}\n\n/**\n * Wait for video canvases within a timegroup to have content.\n * Only checks videos that should be visible at the current time.\n * Returns result with ready status and list of blank video names.\n */\nasync function waitForVideoContent(\n timegroup: EFTimegroup,\n timeMs: number,\n maxWaitMs: number,\n): Promise<WaitForVideoContentResult> {\n const startTime = performance.now();\n \n // Find all video elements in the timegroup (including nested)\n const allVideos = timegroup.querySelectorAll(\"ef-video\");\n if (allVideos.length === 0) return { ready: true, blankVideos: [] };\n \n // Filter to only videos that should be visible at this time\n const visibleVideos = Array.from(allVideos).filter(video => {\n // Check if video itself is in time range\n if (!isVisibleAtTime(video, timeMs)) return false;\n \n // Check if all ancestor timegroups are in time range\n let parent = video.parentElement;\n while (parent && parent !== timegroup) {\n if (parent.tagName === 'EF-TIMEGROUP' && !isVisibleAtTime(parent, timeMs)) {\n return false;\n }\n parent = parent.parentElement;\n }\n return true;\n });\n \n if (visibleVideos.length === 0) return { ready: true, blankVideos: [] };\n \n const getBlankVideoNames = () => visibleVideos\n .filter(video => {\n const shadowCanvas = video.shadowRoot?.querySelector(\"canvas\");\n return shadowCanvas && !canvasHasContent(shadowCanvas);\n })\n .map(v => (v as TemporalElement).src || v.id || 'unnamed');\n \n while (performance.now() - startTime < maxWaitMs) {\n let allHaveContent = true;\n \n for (const video of visibleVideos) {\n const shadowCanvas = video.shadowRoot?.querySelector(\"canvas\");\n if (shadowCanvas && shadowCanvas.width > 0 && shadowCanvas.height > 0) {\n if (!canvasHasContent(shadowCanvas)) {\n allHaveContent = false;\n break;\n }\n }\n }\n \n if (allHaveContent) return { ready: true, blankVideos: [] };\n \n // Wait a bit and check again\n await waitForFrame();\n }\n \n return { ready: false, blankVideos: getBlankVideoNames() };\n}\n\n/**\n * Options for capturing from an existing render clone.\n */\nexport interface CaptureFromCloneOptions {\n /** Scale factor for the output canvas (default: 0.25) */\n scale?: number;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n /** Original timegroup (for dimension and background reference) */\n originalTimegroup?: EFTimegroup;\n}\n\n/**\n * Captures a frame from an already-seeked render clone.\n * Used internally by captureBatch for efficiency (reuses one clone across all captures).\n * \n * @param renderClone - A render clone that has already been seeked to the target time\n * @param renderContainer - The container holding the render clone (from createRenderClone)\n * @param options - Capture options\n * @returns Canvas with the rendered frame\n */\nexport async function captureFromClone(\n renderClone: EFTimegroup,\n renderContainer: HTMLElement,\n options: CaptureFromCloneOptions = {},\n): Promise<HTMLCanvasElement> {\n const {\n scale = DEFAULT_THUMBNAIL_SCALE,\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n originalTimegroup,\n } = options;\n\n // Use original timegroup dimensions if available, otherwise clone dimensions\n const sourceForDimensions = originalTimegroup ?? renderClone;\n const width = sourceForDimensions.offsetWidth || DEFAULT_WIDTH;\n const height = sourceForDimensions.offsetHeight || DEFAULT_HEIGHT;\n\n // Create canvas at scaled size\n const dpr = window.devicePixelRatio || 1;\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale * dpr);\n canvas.height = Math.floor(height * scale * dpr);\n canvas.style.width = `${Math.floor(width * scale)}px`;\n canvas.style.height = `${Math.floor(height * scale)}px`;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2d context\");\n }\n\n // Handle content readiness based on mode\n const timeMs = renderClone.currentTimeMs;\n \n // Use FrameController to ensure all FrameRenderable elements are ready\n // This coordinates prepare → render phases for video, audio, captions, etc.\n const frameController = new FrameController(renderClone);\n await frameController.renderFrame(timeMs, { waitForLitUpdate: false });\n \n if (contentReadyMode === \"blocking\") {\n const result = await waitForVideoContent(renderClone, timeMs, blockingTimeoutMs);\n if (!result.ready) {\n throw new ContentNotReadyError(timeMs, blockingTimeoutMs, result.blankVideos);\n }\n }\n\n // Create RenderContext for caching during this capture operation\n const renderContext = new RenderContext();\n \n try {\n let image: HTMLCanvasElement | HTMLImageElement;\n const renderMode = getEffectiveRenderMode();\n \n if (renderMode === \"native\") {\n // NATIVE PATH: Render the seeked renderClone directly from live DOM\n // The clone is already at the correct time, so drawElementImage captures its current\n // visual state including video frames at the correct position.\n // \n // Position render container properly for capture\n renderContainer.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: ${width}px;\n height: ${height}px;\n pointer-events: none;\n overflow: hidden;\n `;\n \n // OPTIMIZATION: Always skip DPR scaling for captures (thumbnails and video export).\n // Retina quality isn't needed for captured frames, and DPR=2 means 4x more pixels.\n // Live preview uses a different code path (renderTimegroupToCanvas) which handles DPR properly.\n image = await renderToImageNative(renderContainer, width, height, { skipDprScaling: true });\n } else {\n // FOREIGNOBJECT PATH: Build passive structure from the SEEKED render clone\n // The clone is already at the correct time, so getComputedStyle captures the right values.\n // Styles are synced during clone building in a single pass.\n const t0 = performance.now();\n const { container, syncState } = buildCloneStructure(renderClone, timeMs);\n const buildTime = performance.now() - t0;\n\n // Create wrapper using shared helper\n const bgSource = originalTimegroup ?? renderClone;\n const previewContainer = createPreviewContainer({\n width,\n height,\n background: getComputedStyle(bgSource).background || \"#000\",\n });\n \n const t1 = performance.now();\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = collectDocumentStyles();\n const stylesTime = performance.now() - t1;\n previewContainer.appendChild(styleEl);\n previewContainer.appendChild(container);\n \n // Ensure clone root is visible\n overrideRootCloneStyles(syncState, true);\n\n // Render using foreignObject serialization\n // Pass scale, renderContext, and sourceMap for caching optimization\n const t2 = performance.now();\n image = await renderToImage(previewContainer, width, height, { \n canvasScale: scale,\n renderContext,\n sourceMap: syncState.canvasSourceMap,\n });\n const renderTime = performance.now() - t2;\n \n logger.debug(`[captureFromClone] build=${buildTime.toFixed(0)}ms, styles=${stylesTime.toFixed(0)}ms, render=${renderTime.toFixed(0)}ms (canvasScale=${scale})`);\n }\n\n // Draw to canvas (may need scaling for native path which is at DPR)\n const srcWidth = image.width;\n const srcHeight = image.height;\n ctx.drawImage(\n image,\n 0, 0, srcWidth, srcHeight,\n 0, 0, canvas.width, canvas.height\n );\n\n return canvas;\n } finally {\n // Ensure RenderContext is disposed even if an error occurs\n renderContext.dispose();\n }\n}\n\n/**\n * Captures a single frame from a timegroup at a specific time.\n * \n * CLONE-TIMELINE ARCHITECTURE:\n * Creates an independent render clone, seeks it to the target time, and captures.\n * Prime-timeline is NEVER seeked - user can continue previewing/editing during capture.\n * \n * @param timegroup - The source timegroup\n * @param options - Capture options including timeMs, scale, contentReadyMode\n * @returns Canvas with the rendered frame\n * @throws ContentNotReadyError if blocking mode times out waiting for video content\n */\nexport async function captureTimegroupAtTime(\n timegroup: EFTimegroup,\n options: CaptureOptions,\n): Promise<HTMLCanvasElement> {\n const {\n timeMs,\n scale = DEFAULT_THUMBNAIL_SCALE,\n // skipRestore is deprecated with Clone-timeline (Prime is never seeked)\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n } = options;\n\n // CLONE-TIMELINE: Create a short-lived render clone for this capture\n // Prime-timeline is NEVER seeked - clone is fully independent\n const { clone: renderClone, container: renderContainer, cleanup: cleanupRenderClone } = \n await timegroup.createRenderClone();\n \n try {\n // Seek the clone to target time (Prime stays at user position)\n // Use seekForRender which bypasses duration clamping - render clones may have\n // zero duration initially until media durations are computed, but we still\n // want to seek to the requested time for capture purposes.\n await renderClone.seekForRender(timeMs);\n \n // Use the shared capture helper\n return await captureFromClone(renderClone, renderContainer, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n originalTimegroup: timegroup,\n });\n } finally {\n // Clean up the render clone\n cleanupRenderClone();\n }\n}\n\n/** Epsilon for comparing time values (ms) - times within this are considered equal */\nconst TIME_EPSILON_MS = 1;\n\n/** Default scale for preview rendering */\nconst DEFAULT_PREVIEW_SCALE = 1;\n\n/** Default resolution scale (full resolution) */\nconst DEFAULT_RESOLUTION_SCALE = 1;\n\n/**\n * Convert relative time to absolute time for a timegroup.\n * Nested timegroup children have ABSOLUTE startTimeMs values,\n * so relative capture times must be converted for temporal culling.\n */\nfunction toAbsoluteTime(timegroup: EFTimegroup, relativeTimeMs: number): number {\n return relativeTimeMs + (timegroup.startTimeMs ?? 0);\n}\n\nexport interface CanvasPreviewResult {\n /**\n * Wrapper container holding the canvas and debug label.\n * Append this to your DOM - the canvas inside will receive transforms.\n */\n container: HTMLDivElement;\n canvas: HTMLCanvasElement;\n /**\n * Call this to re-render the timegroup to canvas at current visual state.\n * Returns a promise that resolves when rendering is complete.\n */\n refresh: () => Promise<void>;\n syncState: SyncState;\n /**\n * Dynamically change the resolution scale without rebuilding the clone structure.\n * This is nearly instant - just updates CSS and internal variables.\n * The next refresh() call will render at the new resolution.\n */\n setResolutionScale: (scale: number) => void;\n /**\n * Get the current resolution scale.\n */\n getResolutionScale: () => number;\n /**\n * Dispose the preview and release resources.\n * Call this when the preview is no longer needed.\n */\n dispose: () => void;\n}\n\n/**\n * Options for canvas preview rendering.\n */\nexport interface CanvasPreviewOptions {\n /**\n * Output scale factor (default: 1).\n * Scales the final canvas size.\n */\n scale?: number;\n \n /**\n * Resolution scale for internal rendering (default: 1).\n * Reduces the internal render resolution for better performance.\n * The canvas CSS size remains the same (browser upscales).\n * - 1: Full resolution\n * - 0.75: 3/4 resolution\n * - 0.5: Half resolution\n * - 0.25: Quarter resolution\n */\n resolutionScale?: number;\n}\n\n/**\n * Renders a timegroup preview to a canvas using SVG foreignObject.\n * \n * Optimized with:\n * - Persistent clone structure (built once)\n * - Temporal bucketing for time-based culling\n * - Property split (static vs animated)\n * - Parent index for O(1) visibility checks\n * - Resolution scaling for performance (renders at lower resolution, CSS upscales)\n *\n * @param timegroup - The source timegroup to preview\n * @param scaleOrOptions - Scale factor (default 1) or options object\n * @returns Object with canvas and refresh function\n */\nexport function renderTimegroupToCanvas(\n timegroup: EFTimegroup,\n scaleOrOptions: number | CanvasPreviewOptions = DEFAULT_PREVIEW_SCALE,\n): CanvasPreviewResult {\n // Normalize options\n const options: CanvasPreviewOptions = typeof scaleOrOptions === \"number\"\n ? { scale: scaleOrOptions }\n : scaleOrOptions;\n \n const scale = options.scale ?? DEFAULT_PREVIEW_SCALE;\n // These are mutable to support dynamic resolution changes\n let currentResolutionScale = options.resolutionScale ?? DEFAULT_RESOLUTION_SCALE;\n \n const width = timegroup.offsetWidth || DEFAULT_WIDTH;\n const height = timegroup.offsetHeight || DEFAULT_HEIGHT;\n const dpr = window.devicePixelRatio || 1;\n \n // Calculate effective render dimensions (internal resolution) - mutable\n let renderWidth = Math.floor(width * currentResolutionScale);\n let renderHeight = Math.floor(height * currentResolutionScale);\n\n // Create canvas with proper DPR handling\n const canvas = createDprCanvas({\n renderWidth,\n renderHeight,\n scale,\n fullWidth: width,\n fullHeight: height,\n dpr,\n });\n \n // Create wrapper container with debug label\n const wrapperContainer = document.createElement(\"div\");\n wrapperContainer.style.cssText = \"position: relative; display: inline-block;\";\n const debugLabel = createDebugLabel();\n wrapperContainer.appendChild(debugLabel);\n wrapperContainer.appendChild(canvas);\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2d context\");\n }\n\n // Build clone structure ONCE with optimized sync state\n // Initial sync happens during clone building in a single pass\n const initialTimeMs = toAbsoluteTime(timegroup, timegroup.currentTimeMs ?? 0);\n const { container, syncState } = buildCloneStructure(timegroup, initialTimeMs);\n\n // Create a wrapper div with scaled dimensions\n // When resolutionScale < 1, we render at a smaller size and CSS transform scales the content\n const previewContainer = createPreviewContainer({\n width: renderWidth,\n height: renderHeight,\n background: getComputedStyle(timegroup).background || \"#000\",\n });\n \n // Apply CSS transform to scale down the content within the container\n // This makes the clone render at reduced complexity\n if (currentResolutionScale < 1) {\n container.style.transform = `scale(${currentResolutionScale})`;\n container.style.transformOrigin = \"top left\";\n }\n \n // Inject document styles so CSS rules work in SVG foreignObject\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = collectDocumentStyles();\n previewContainer.appendChild(styleEl);\n \n previewContainer.appendChild(container);\n overrideRootCloneStyles(syncState);\n\n // Track render state\n let rendering = false;\n let lastTimeMs = -1;\n let disposed = false;\n\n // Create RenderContext for caching across refresh calls\n const renderContext = new RenderContext();\n \n // Create FrameController for coordinating element rendering\n // Cached for the lifetime of this preview instance\n const frameController = new FrameController(timegroup);\n\n // Log resolution scale on first render for debugging\n let hasLoggedScale = false;\n \n // Pending resolution change - applied at start of next refresh to avoid blanking\n let pendingResolutionScale: number | null = null;\n \n /**\n * Apply pending resolution scale changes.\n * Called at the start of refresh() before rendering, so the old content\n * stays visible until new content is ready to be drawn.\n */\n const applyPendingResolutionChange = (): void => {\n if (pendingResolutionScale === null) return;\n \n const newScale = pendingResolutionScale;\n pendingResolutionScale = null;\n \n currentResolutionScale = newScale;\n renderWidth = Math.floor(width * currentResolutionScale);\n renderHeight = Math.floor(height * currentResolutionScale);\n \n // Update previewContainer dimensions (affects what renderToImage produces)\n previewContainer.style.width = `${renderWidth}px`;\n previewContainer.style.height = `${renderHeight}px`;\n \n // Update clone transform\n if (currentResolutionScale < 1) {\n container.style.transform = `scale(${currentResolutionScale})`;\n container.style.transformOrigin = \"top left\";\n } else {\n container.style.transform = \"\";\n }\n \n // Canvas dimensions will be updated right before drawing (in refresh)\n // to avoid clearing the canvas until new content is ready\n };\n \n /**\n * Dynamically change resolution scale without rebuilding clone structure.\n * The actual change is deferred until next refresh() to avoid blanking -\n * old content stays visible until new content is ready.\n */\n const setResolutionScale = (newScale: number): void => {\n // Clamp to valid range\n newScale = Math.max(0.1, Math.min(1, newScale));\n \n if (newScale === currentResolutionScale && pendingResolutionScale === null) return;\n \n // Queue the change - will be applied at start of next refresh\n pendingResolutionScale = newScale;\n \n // Force re-render on next refresh by invalidating lastTimeMs\n lastTimeMs = -1;\n };\n \n const getResolutionScale = (): number => pendingResolutionScale ?? currentResolutionScale;\n \n const refresh = async (): Promise<void> => {\n if (rendering || disposed) return;\n // Clone-timeline: captures use separate clones, Prime-timeline is never locked\n \n const sourceTimeMs = timegroup.currentTimeMs ?? 0;\n const userTimeMs = timegroup.userTimeMs ?? 0;\n if (Math.abs(sourceTimeMs - userTimeMs) > TIME_EPSILON_MS) return;\n \n if (userTimeMs === lastTimeMs) return;\n lastTimeMs = userTimeMs;\n \n rendering = true;\n \n // Apply any pending resolution changes before rendering\n // This updates previewContainer and clone transform, but NOT canvas dimensions yet\n applyPendingResolutionChange();\n \n // Log scale info once per initialization\n if (!hasLoggedScale) {\n hasLoggedScale = true;\n const mode = getEffectiveRenderMode();\n logger.debug(`[renderTimegroupToCanvas] Resolution scale: ${currentResolutionScale} (${width}x${height} → ${renderWidth}x${renderHeight}), canvas buffer: ${canvas.width}x${canvas.height}, CSS size: ${canvas.style.width}x${canvas.style.height}, renderMode: ${mode}`);\n }\n\n try {\n // Use FrameController to ensure all FrameRenderable elements are ready\n // This coordinates prepare → render phases before we capture their state\n await frameController.renderFrame(userTimeMs);\n \n syncStyles(syncState, toAbsoluteTime(timegroup, userTimeMs));\n overrideRootCloneStyles(syncState);\n\n // Remove hidden nodes from DOM for serialization - they won't be serialized\n // or have their canvases encoded. This is a significant optimization.\n const removedNodes = removeHiddenNodesForSerialization(syncState);\n\n // Render at scaled dimensions with canvas scaling for internal video frames\n // Pass renderContext and sourceMap for caching optimization\n const t0 = performance.now();\n const image = await renderToImage(previewContainer, renderWidth, renderHeight, {\n canvasScale: currentResolutionScale,\n renderContext,\n sourceMap: syncState.canvasSourceMap,\n });\n const renderTime = performance.now() - t0;\n \n // Restore hidden nodes for next frame's delta tracking\n restoreHiddenNodes(removedNodes);\n\n // Update canvas buffer dimensions NOW, right before drawing\n // This clears the canvas, but we immediately draw new content\n const targetWidth = Math.floor(renderWidth * scale * dpr);\n const targetHeight = Math.floor(renderHeight * scale * dpr);\n if (canvas.width !== targetWidth || canvas.height !== targetHeight) {\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n } else {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n \n ctx.save();\n ctx.scale(dpr * scale, dpr * scale);\n ctx.drawImage(image, 0, 0);\n ctx.restore();\n \n // Log render time periodically (every 60 frames)\n defaultProfiler.incrementRenderCount();\n if (defaultProfiler.shouldLogByFrameCount(60)) {\n logger.debug(`[renderTimegroupToCanvas] Frame render: ${renderTime.toFixed(1)}ms (resolutionScale=${currentResolutionScale}, image=${image.width}x${image.height})`);\n }\n \n // Update debug label\n updateDebugLabel(debugLabel, renderWidth, renderHeight, currentResolutionScale);\n } catch (e) {\n logger.error(\"Canvas preview render failed:\", e);\n } finally {\n rendering = false;\n }\n };\n\n /**\n * Dispose the preview and release resources.\n */\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n frameController.abort();\n renderContext.dispose();\n };\n\n // Do initial render\n refresh();\n\n return { container: wrapperContainer, canvas, refresh, syncState, setResolutionScale, getResolutionScale, dispose };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"renderTimegroupToCanvas.js","names":["timeMs: number","timeoutMs: number","blankVideos: string[]","renderState: RenderState","scaleColors: Record<number, string>","image: HTMLCanvasElement | HTMLImageElement","options: CanvasPreviewOptions","pendingResolutionScale: number | null"],"sources":["../../src/preview/renderTimegroupToCanvas.ts"],"sourcesContent":["import type { EFTimegroup } from \"../elements/EFTimegroup.js\";\nimport {\n buildCloneStructure,\n syncStyles,\n collectDocumentStyles,\n overrideRootCloneStyles,\n removeHiddenNodesForSerialization,\n restoreHiddenNodes,\n type SyncState,\n} from \"./renderTimegroupPreview.js\";\nimport { getEffectiveRenderMode } from \"./renderers.js\";\nimport { RenderContext } from \"./RenderContext.js\";\nimport { FrameController } from \"./FrameController.js\";\n\n// Re-export renderer types for external use\nexport type { RenderOptions, RenderResult, Renderer } from \"./renderers.js\";\nexport { getEffectiveRenderMode, isCanvas, isImage } from \"./renderers.js\";\nimport {\n type TemporalElement,\n isVisibleAtTime,\n DEFAULT_WIDTH,\n DEFAULT_HEIGHT,\n DEFAULT_THUMBNAIL_SCALE,\n DEFAULT_BLOCKING_TIMEOUT_MS,\n createPreviewContainer,\n} from \"./previewTypes.js\";\nimport { defaultProfiler } from \"./RenderProfiler.js\";\nimport { logger } from \"./logger.js\";\n\n// Import rendering modules\nimport {\n renderToImage,\n renderToImageDirect,\n prepareFrameDataUri,\n loadImageFromDataUri,\n} from \"./rendering/renderToImage.js\";\nimport { renderToImageNative, createDprCanvas } from \"./rendering/renderToImageNative.js\";\nimport { clearInlineImageCache, getInlineImageCacheSize } from \"./rendering/inlineImages.js\";\n\n// Re-export rendering types and functions for external use\nexport type {\n NativeRenderOptions,\n ForeignObjectRenderOptions,\n} from \"./rendering/types.js\";\nexport {\n renderToImage,\n renderToImageNative,\n renderToImageDirect,\n prepareFrameDataUri,\n loadImageFromDataUri,\n};\n\n// ============================================================================\n// Constants (module-specific, not shared)\n// ============================================================================\n\n/** Number of rows to sample when checking canvas content */\nconst CANVAS_SAMPLE_STRIP_HEIGHT = 4;\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Content readiness strategy for capture operations.\n * - \"immediate\": Capture NOW, skip all waits. May have blank video frames.\n * - \"blocking\": Wait for video content to be ready. Throws on timeout.\n */\nexport type ContentReadyMode = \"immediate\" | \"blocking\";\n\n/**\n * Options for capturing a timegroup frame.\n */\nexport interface CaptureOptions {\n /** Time to capture at in milliseconds (required) */\n timeMs: number;\n /** Scale factor (default: 0.25 for captureTimegroupAtTime) */\n scale?: number;\n /** Skip restoring original time after capture (for batch operations) */\n skipRestore?: boolean;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n}\n\n/**\n * Options for batch capture operations, excluding timeMs which is provided per-timestamp.\n */\nexport interface CaptureBatchOptions {\n /** Scale factor for thumbnails (default: 0.25) */\n scale?: number;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n}\n\n/**\n * Error thrown when video content is not ready within the blocking timeout.\n */\nexport class ContentNotReadyError extends Error {\n constructor(\n public readonly timeMs: number,\n public readonly timeoutMs: number,\n public readonly blankVideos: string[],\n ) {\n super(`Video content not ready at ${timeMs}ms after ${timeoutMs}ms timeout. Blank videos: ${blankVideos.join(', ')}`);\n this.name = 'ContentNotReadyError';\n }\n}\n\n// ============================================================================\n// Module State (reset via resetRenderState)\n// ============================================================================\n\n/**\n * Module-level render state including caches and reusable objects.\n */\ninterface RenderState {\n inlineImageCache: Map<string, string>;\n layoutInitializedCanvases: WeakSet<HTMLCanvasElement>;\n xmlSerializer: XMLSerializer | null;\n textEncoder: TextEncoder;\n metrics: {\n inlineImageCacheHits: number;\n inlineImageCacheMisses: number;\n inlineImageCacheEvictions: number;\n };\n}\n\n/**\n * Module-level state for render operations.\n * Note: xmlSerializer is lazy-initialized for Node.js compatibility\n */\nconst renderState: RenderState = {\n inlineImageCache: new Map(),\n layoutInitializedCanvases: new WeakSet(),\n xmlSerializer: null, // Lazy-initialized in browser context\n textEncoder: new TextEncoder(),\n metrics: {\n inlineImageCacheHits: 0,\n inlineImageCacheMisses: 0,\n inlineImageCacheEvictions: 0,\n },\n};\n\n/**\n * Get the current render state for testing and debugging.\n * @returns The module-level render state object\n */\nexport function getRenderState(): RenderState {\n return renderState;\n}\n\n/**\n * Get cache metrics for monitoring performance.\n * @returns Object with cache hit/miss/eviction counts\n */\nexport function getCacheMetrics(): RenderState['metrics'] {\n return { ...renderState.metrics };\n}\n\n/**\n * Reset cache metrics to zero.\n */\nexport function resetCacheMetrics(): void {\n renderState.metrics.inlineImageCacheHits = 0;\n renderState.metrics.inlineImageCacheMisses = 0;\n renderState.metrics.inlineImageCacheEvictions = 0;\n}\n\n/**\n * Reset all module state including profiling counters, caches, and logging flags.\n * Call at the start of export sessions to ensure clean state.\n */\nexport function resetRenderState(): void {\n defaultProfiler.reset();\n clearInlineImageCache();\n resetCacheMetrics();\n}\n\n// Re-export cache management functions\nexport { clearInlineImageCache, getInlineImageCacheSize };\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Create a debug label for showing render info.\n */\nfunction createDebugLabel(): HTMLDivElement {\n const debugLabel = document.createElement(\"div\");\n debugLabel.style.cssText = `\n position: absolute;\n top: -24px;\n left: 0;\n padding: 2px 8px;\n font: bold 12px monospace;\n background: rgba(0, 0, 0, 0.8);\n border-radius: 3px;\n white-space: nowrap;\n z-index: 1000;\n pointer-events: none;\n `;\n return debugLabel;\n}\n\n/**\n * Update debug label with resolution info.\n */\nfunction updateDebugLabel(\n label: HTMLDivElement,\n renderWidth: number,\n renderHeight: number,\n resolutionScale: number,\n): void {\n const scaleColors: Record<number, string> = {\n 1: \"#00ff00\",\n 0.75: \"#ffff00\",\n 0.5: \"#ff8800\",\n 0.25: \"#ff0000\",\n };\n label.style.color = scaleColors[resolutionScale] || \"#ffffff\";\n label.textContent = `Render: ${renderWidth}x${renderHeight} (${Math.round(resolutionScale * 100)}%)`;\n}\n\n/**\n * Wait for next animation frame (allows browser to complete layout)\n */\nfunction waitForFrame(): Promise<void> {\n return new Promise(resolve => requestAnimationFrame(() => resolve()));\n}\n\n/**\n * Check if a canvas has any rendered content (not all transparent/uninitialized).\n * Returns true if there's ANY non-transparent pixel.\n */\nfunction canvasHasContent(canvas: HTMLCanvasElement): boolean {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return false;\n \n try {\n const width = canvas.width;\n const height = canvas.height;\n if (width === 0 || height === 0) return false;\n \n // Sample a horizontal strip across the middle of the canvas\n // This catches most video content even if edges are black\n const stripY = Math.floor(height / 2);\n const imageData = ctx.getImageData(0, stripY, width, CANVAS_SAMPLE_STRIP_HEIGHT);\n const data = imageData.data;\n \n // Check if ANY pixel has non-zero alpha (is not transparent)\n // A truly blank/uninitialized canvas has all pixels at [0,0,0,0]\n // A black video frame would have pixels at [0,0,0,255] (opaque black)\n for (let i = 3; i < data.length; i += 4) {\n if (data[i] !== 0) {\n return true;\n }\n }\n \n return false;\n } catch {\n // Canvas might be tainted, assume it has content\n return true;\n }\n}\n\ninterface WaitForVideoContentResult {\n ready: boolean;\n blankVideos: string[];\n}\n\n/**\n * Wait for video canvases within a timegroup to have content.\n * Only checks videos that should be visible at the current time.\n * Returns result with ready status and list of blank video names.\n */\nasync function waitForVideoContent(\n timegroup: EFTimegroup,\n timeMs: number,\n maxWaitMs: number,\n): Promise<WaitForVideoContentResult> {\n const startTime = performance.now();\n \n // Find all video elements in the timegroup (including nested)\n const allVideos = timegroup.querySelectorAll(\"ef-video\");\n if (allVideos.length === 0) return { ready: true, blankVideos: [] };\n \n // Filter to only videos that should be visible at this time\n const visibleVideos = Array.from(allVideos).filter(video => {\n // Check if video itself is in time range\n if (!isVisibleAtTime(video, timeMs)) return false;\n \n // Check if all ancestor timegroups are in time range\n let parent = video.parentElement;\n while (parent && parent !== timegroup) {\n if (parent.tagName === 'EF-TIMEGROUP' && !isVisibleAtTime(parent, timeMs)) {\n return false;\n }\n parent = parent.parentElement;\n }\n return true;\n });\n \n if (visibleVideos.length === 0) return { ready: true, blankVideos: [] };\n \n const getBlankVideoNames = () => visibleVideos\n .filter(video => {\n const shadowCanvas = video.shadowRoot?.querySelector(\"canvas\");\n return shadowCanvas && !canvasHasContent(shadowCanvas);\n })\n .map(v => (v as TemporalElement).src || v.id || 'unnamed');\n \n while (performance.now() - startTime < maxWaitMs) {\n let allHaveContent = true;\n \n for (const video of visibleVideos) {\n const shadowCanvas = video.shadowRoot?.querySelector(\"canvas\");\n if (shadowCanvas && shadowCanvas.width > 0 && shadowCanvas.height > 0) {\n if (!canvasHasContent(shadowCanvas)) {\n allHaveContent = false;\n break;\n }\n }\n }\n \n if (allHaveContent) return { ready: true, blankVideos: [] };\n \n // Wait a bit and check again\n await waitForFrame();\n }\n \n return { ready: false, blankVideos: getBlankVideoNames() };\n}\n\n/**\n * Options for capturing from an existing render clone.\n */\nexport interface CaptureFromCloneOptions {\n /** Scale factor for the output canvas (default: 0.25) */\n scale?: number;\n /** Content readiness strategy (default: \"immediate\") */\n contentReadyMode?: ContentReadyMode;\n /** Max wait time for blocking mode before throwing (default: 5000ms) */\n blockingTimeoutMs?: number;\n /** Original timegroup (for dimension and background reference) */\n originalTimegroup?: EFTimegroup;\n}\n\n/**\n * Captures a frame from an already-seeked render clone.\n * Used internally by captureBatch for efficiency (reuses one clone across all captures).\n * \n * @param renderClone - A render clone that has already been seeked to the target time\n * @param renderContainer - The container holding the render clone (from createRenderClone)\n * @param options - Capture options\n * @returns Canvas with the rendered frame\n */\nexport async function captureFromClone(\n renderClone: EFTimegroup,\n renderContainer: HTMLElement,\n options: CaptureFromCloneOptions = {},\n): Promise<HTMLCanvasElement> {\n const {\n scale = DEFAULT_THUMBNAIL_SCALE,\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n originalTimegroup,\n } = options;\n\n // Use original timegroup dimensions if available, otherwise clone dimensions\n const sourceForDimensions = originalTimegroup ?? renderClone;\n const width = sourceForDimensions.offsetWidth || DEFAULT_WIDTH;\n const height = sourceForDimensions.offsetHeight || DEFAULT_HEIGHT;\n\n // Create canvas at scaled size\n const dpr = window.devicePixelRatio || 1;\n const canvas = document.createElement(\"canvas\");\n canvas.width = Math.floor(width * scale * dpr);\n canvas.height = Math.floor(height * scale * dpr);\n canvas.style.width = `${Math.floor(width * scale)}px`;\n canvas.style.height = `${Math.floor(height * scale)}px`;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2d context\");\n }\n\n // Handle content readiness based on mode\n const timeMs = renderClone.currentTimeMs;\n \n // Use FrameController to ensure all FrameRenderable elements are ready\n // This coordinates prepare → render phases for video, audio, captions, etc.\n const frameController = new FrameController(renderClone);\n await frameController.renderFrame(timeMs, { waitForLitUpdate: false });\n \n if (contentReadyMode === \"blocking\") {\n const result = await waitForVideoContent(renderClone, timeMs, blockingTimeoutMs);\n if (!result.ready) {\n throw new ContentNotReadyError(timeMs, blockingTimeoutMs, result.blankVideos);\n }\n }\n\n // Create RenderContext for caching during this capture operation\n const renderContext = new RenderContext();\n \n try {\n let image: HTMLCanvasElement | HTMLImageElement;\n const renderMode = getEffectiveRenderMode();\n \n if (renderMode === \"native\") {\n // NATIVE PATH: Render the seeked renderClone directly from live DOM\n // The clone is already at the correct time, so drawElementImage captures its current\n // visual state including video frames at the correct position.\n // \n // Position render container properly for capture\n renderContainer.style.cssText = `\n position: fixed;\n left: 0;\n top: 0;\n width: ${width}px;\n height: ${height}px;\n pointer-events: none;\n overflow: hidden;\n `;\n \n // OPTIMIZATION: Always skip DPR scaling for captures (thumbnails and video export).\n // Retina quality isn't needed for captured frames, and DPR=2 means 4x more pixels.\n // Live preview uses a different code path (renderTimegroupToCanvas) which handles DPR properly.\n image = await renderToImageNative(renderContainer, width, height, { skipDprScaling: true });\n } else {\n // FOREIGNOBJECT PATH: Build passive structure from the SEEKED render clone\n // The clone is already at the correct time, so getComputedStyle captures the right values.\n // Styles are synced during clone building in a single pass.\n const t0 = performance.now();\n const { container, syncState } = buildCloneStructure(renderClone, timeMs);\n const buildTime = performance.now() - t0;\n\n // Create wrapper using shared helper\n const bgSource = originalTimegroup ?? renderClone;\n const previewContainer = createPreviewContainer({\n width,\n height,\n background: getComputedStyle(bgSource).background || \"#000\",\n });\n \n const t1 = performance.now();\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = collectDocumentStyles();\n const stylesTime = performance.now() - t1;\n previewContainer.appendChild(styleEl);\n previewContainer.appendChild(container);\n \n // Ensure clone root is visible\n overrideRootCloneStyles(syncState, true);\n\n // Render using foreignObject serialization\n // Pass scale, renderContext, and sourceMap for caching optimization\n const t2 = performance.now();\n image = await renderToImage(previewContainer, width, height, { \n canvasScale: scale,\n renderContext,\n sourceMap: syncState.canvasSourceMap,\n });\n const renderTime = performance.now() - t2;\n \n logger.debug(`[captureFromClone] build=${buildTime.toFixed(0)}ms, styles=${stylesTime.toFixed(0)}ms, render=${renderTime.toFixed(0)}ms (canvasScale=${scale})`);\n }\n\n // Draw to canvas (may need scaling for native path which is at DPR)\n const srcWidth = image.width;\n const srcHeight = image.height;\n ctx.drawImage(\n image,\n 0, 0, srcWidth, srcHeight,\n 0, 0, canvas.width, canvas.height\n );\n\n return canvas;\n } finally {\n // Ensure RenderContext is disposed even if an error occurs\n renderContext.dispose();\n }\n}\n\n/**\n * Captures a single frame from a timegroup at a specific time.\n * \n * CLONE-TIMELINE ARCHITECTURE:\n * Creates an independent render clone, seeks it to the target time, and captures.\n * Prime-timeline is NEVER seeked - user can continue previewing/editing during capture.\n * \n * @param timegroup - The source timegroup\n * @param options - Capture options including timeMs, scale, contentReadyMode\n * @returns Canvas with the rendered frame\n * @throws ContentNotReadyError if blocking mode times out waiting for video content\n */\nexport async function captureTimegroupAtTime(\n timegroup: EFTimegroup,\n options: CaptureOptions,\n): Promise<HTMLCanvasElement> {\n const {\n timeMs,\n scale = DEFAULT_THUMBNAIL_SCALE,\n // skipRestore is deprecated with Clone-timeline (Prime is never seeked)\n contentReadyMode = \"immediate\",\n blockingTimeoutMs = DEFAULT_BLOCKING_TIMEOUT_MS,\n } = options;\n\n // CLONE-TIMELINE: Create a short-lived render clone for this capture\n // Prime-timeline is NEVER seeked - clone is fully independent\n const { clone: renderClone, container: renderContainer, cleanup: cleanupRenderClone } = \n await timegroup.createRenderClone();\n \n try {\n // Seek the clone to target time (Prime stays at user position)\n // Use seekForRender which bypasses duration clamping - render clones may have\n // zero duration initially until media durations are computed, but we still\n // want to seek to the requested time for capture purposes.\n await renderClone.seekForRender(timeMs);\n \n // Use the shared capture helper\n return await captureFromClone(renderClone, renderContainer, {\n scale,\n contentReadyMode,\n blockingTimeoutMs,\n originalTimegroup: timegroup,\n });\n } finally {\n // Clean up the render clone\n cleanupRenderClone();\n }\n}\n\n/** Epsilon for comparing time values (ms) - times within this are considered equal */\nconst TIME_EPSILON_MS = 1;\n\n/** Default scale for preview rendering */\nconst DEFAULT_PREVIEW_SCALE = 1;\n\n/** Default resolution scale (full resolution) */\nconst DEFAULT_RESOLUTION_SCALE = 1;\n\n/**\n * Convert relative time to absolute time for a timegroup.\n * Nested timegroup children have ABSOLUTE startTimeMs values,\n * so relative capture times must be converted for temporal culling.\n */\nfunction toAbsoluteTime(timegroup: EFTimegroup, relativeTimeMs: number): number {\n return relativeTimeMs + (timegroup.startTimeMs ?? 0);\n}\n\nexport interface CanvasPreviewResult {\n /**\n * Wrapper container holding the canvas and debug label.\n * Append this to your DOM - the canvas inside will receive transforms.\n */\n container: HTMLDivElement;\n canvas: HTMLCanvasElement;\n /**\n * Call this to re-render the timegroup to canvas at current visual state.\n * Returns a promise that resolves when rendering is complete.\n */\n refresh: () => Promise<void>;\n syncState: SyncState;\n /**\n * Dynamically change the resolution scale without rebuilding the clone structure.\n * This is nearly instant - just updates CSS and internal variables.\n * The next refresh() call will render at the new resolution.\n */\n setResolutionScale: (scale: number) => void;\n /**\n * Get the current resolution scale.\n */\n getResolutionScale: () => number;\n /**\n * Dispose the preview and release resources.\n * Call this when the preview is no longer needed.\n */\n dispose: () => void;\n}\n\n/**\n * Options for canvas preview rendering.\n */\nexport interface CanvasPreviewOptions {\n /**\n * Output scale factor (default: 1).\n * Scales the final canvas size.\n */\n scale?: number;\n \n /**\n * Resolution scale for internal rendering (default: 1).\n * Reduces the internal render resolution for better performance.\n * The canvas CSS size remains the same (browser upscales).\n * - 1: Full resolution\n * - 0.75: 3/4 resolution\n * - 0.5: Half resolution\n * - 0.25: Quarter resolution\n */\n resolutionScale?: number;\n}\n\n/**\n * Renders a timegroup preview to a canvas using SVG foreignObject.\n * \n * Optimized with:\n * - Persistent clone structure (built once)\n * - Temporal bucketing for time-based culling\n * - Property split (static vs animated)\n * - Parent index for O(1) visibility checks\n * - Resolution scaling for performance (renders at lower resolution, CSS upscales)\n *\n * @param timegroup - The source timegroup to preview\n * @param scaleOrOptions - Scale factor (default 1) or options object\n * @returns Object with canvas and refresh function\n */\nexport function renderTimegroupToCanvas(\n timegroup: EFTimegroup,\n scaleOrOptions: number | CanvasPreviewOptions = DEFAULT_PREVIEW_SCALE,\n): CanvasPreviewResult {\n // Normalize options\n const options: CanvasPreviewOptions = typeof scaleOrOptions === \"number\"\n ? { scale: scaleOrOptions }\n : scaleOrOptions;\n \n const scale = options.scale ?? DEFAULT_PREVIEW_SCALE;\n // These are mutable to support dynamic resolution changes\n let currentResolutionScale = options.resolutionScale ?? DEFAULT_RESOLUTION_SCALE;\n \n const width = timegroup.offsetWidth || DEFAULT_WIDTH;\n const height = timegroup.offsetHeight || DEFAULT_HEIGHT;\n const dpr = window.devicePixelRatio || 1;\n \n // Calculate effective render dimensions (internal resolution) - mutable\n let renderWidth = Math.floor(width * currentResolutionScale);\n let renderHeight = Math.floor(height * currentResolutionScale);\n\n // Create canvas with proper DPR handling\n const canvas = createDprCanvas({\n renderWidth,\n renderHeight,\n scale,\n fullWidth: width,\n fullHeight: height,\n dpr,\n });\n \n // Create wrapper container with debug label\n const wrapperContainer = document.createElement(\"div\");\n wrapperContainer.style.cssText = \"position: relative; display: inline-block;\";\n const debugLabel = createDebugLabel();\n wrapperContainer.appendChild(debugLabel);\n wrapperContainer.appendChild(canvas);\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to get canvas 2d context\");\n }\n\n // Build clone structure ONCE with optimized sync state\n // Initial sync happens during clone building in a single pass\n const initialTimeMs = toAbsoluteTime(timegroup, timegroup.currentTimeMs ?? 0);\n const { container, syncState } = buildCloneStructure(timegroup, initialTimeMs);\n\n // Create a wrapper div with scaled dimensions\n // When resolutionScale < 1, we render at a smaller size and CSS transform scales the content\n const previewContainer = createPreviewContainer({\n width: renderWidth,\n height: renderHeight,\n background: getComputedStyle(timegroup).background || \"#000\",\n });\n \n // Apply CSS transform to scale down the content within the container\n // This makes the clone render at reduced complexity\n if (currentResolutionScale < 1) {\n container.style.transform = `scale(${currentResolutionScale})`;\n container.style.transformOrigin = \"top left\";\n }\n \n // Inject document styles so CSS rules work in SVG foreignObject\n const styleEl = document.createElement(\"style\");\n styleEl.textContent = collectDocumentStyles();\n previewContainer.appendChild(styleEl);\n \n previewContainer.appendChild(container);\n overrideRootCloneStyles(syncState);\n\n // Track render state\n let rendering = false;\n let lastTimeMs = -1;\n let disposed = false;\n\n // Create RenderContext for caching across refresh calls\n const renderContext = new RenderContext();\n \n // Create FrameController for coordinating element rendering\n // Cached for the lifetime of this preview instance\n const frameController = new FrameController(timegroup);\n\n // Log resolution scale on first render for debugging\n let hasLoggedScale = false;\n \n // Pending resolution change - applied at start of next refresh to avoid blanking\n let pendingResolutionScale: number | null = null;\n \n /**\n * Apply pending resolution scale changes.\n * Called at the start of refresh() before rendering, so the old content\n * stays visible until new content is ready to be drawn.\n */\n const applyPendingResolutionChange = (): void => {\n if (pendingResolutionScale === null) return;\n \n const newScale = pendingResolutionScale;\n pendingResolutionScale = null;\n \n currentResolutionScale = newScale;\n renderWidth = Math.floor(width * currentResolutionScale);\n renderHeight = Math.floor(height * currentResolutionScale);\n \n // Update previewContainer dimensions (affects what renderToImage produces)\n previewContainer.style.width = `${renderWidth}px`;\n previewContainer.style.height = `${renderHeight}px`;\n \n // Update clone transform\n if (currentResolutionScale < 1) {\n container.style.transform = `scale(${currentResolutionScale})`;\n container.style.transformOrigin = \"top left\";\n } else {\n container.style.transform = \"\";\n }\n \n // Canvas dimensions will be updated right before drawing (in refresh)\n // to avoid clearing the canvas until new content is ready\n };\n \n /**\n * Dynamically change resolution scale without rebuilding clone structure.\n * The actual change is deferred until next refresh() to avoid blanking -\n * old content stays visible until new content is ready.\n */\n const setResolutionScale = (newScale: number): void => {\n // Clamp to valid range\n newScale = Math.max(0.1, Math.min(1, newScale));\n \n if (newScale === currentResolutionScale && pendingResolutionScale === null) return;\n \n // Queue the change - will be applied at start of next refresh\n pendingResolutionScale = newScale;\n \n // Force re-render on next refresh by invalidating lastTimeMs\n lastTimeMs = -1;\n };\n \n const getResolutionScale = (): number => pendingResolutionScale ?? currentResolutionScale;\n \n const refresh = async (): Promise<void> => {\n if (rendering || disposed) return;\n // Clone-timeline: captures use separate clones, Prime-timeline is never locked\n \n const sourceTimeMs = timegroup.currentTimeMs ?? 0;\n const userTimeMs = timegroup.userTimeMs ?? 0;\n if (Math.abs(sourceTimeMs - userTimeMs) > TIME_EPSILON_MS) return;\n \n if (userTimeMs === lastTimeMs) return;\n lastTimeMs = userTimeMs;\n \n rendering = true;\n \n // Apply any pending resolution changes before rendering\n // This updates previewContainer and clone transform, but NOT canvas dimensions yet\n applyPendingResolutionChange();\n \n // Log scale info once per initialization\n if (!hasLoggedScale) {\n hasLoggedScale = true;\n const mode = getEffectiveRenderMode();\n logger.debug(`[renderTimegroupToCanvas] Resolution scale: ${currentResolutionScale} (${width}x${height} → ${renderWidth}x${renderHeight}), canvas buffer: ${canvas.width}x${canvas.height}, CSS size: ${canvas.style.width}x${canvas.style.height}, renderMode: ${mode}`);\n }\n\n try {\n // Use FrameController to ensure all FrameRenderable elements are ready\n // This coordinates prepare → render phases before we capture their state\n await frameController.renderFrame(userTimeMs);\n \n syncStyles(syncState, toAbsoluteTime(timegroup, userTimeMs));\n overrideRootCloneStyles(syncState);\n\n // Remove hidden nodes from DOM for serialization - they won't be serialized\n // or have their canvases encoded. This is a significant optimization.\n const removedNodes = removeHiddenNodesForSerialization(syncState);\n\n // Render at scaled dimensions with canvas scaling for internal video frames\n // Pass renderContext and sourceMap for caching optimization\n const t0 = performance.now();\n const image = await renderToImage(previewContainer, renderWidth, renderHeight, {\n canvasScale: currentResolutionScale,\n renderContext,\n sourceMap: syncState.canvasSourceMap,\n });\n const renderTime = performance.now() - t0;\n \n // Restore hidden nodes for next frame's delta tracking\n restoreHiddenNodes(removedNodes);\n\n // Update canvas buffer dimensions NOW, right before drawing\n // This clears the canvas, but we immediately draw new content\n const targetWidth = Math.floor(renderWidth * scale * dpr);\n const targetHeight = Math.floor(renderHeight * scale * dpr);\n if (canvas.width !== targetWidth || canvas.height !== targetHeight) {\n canvas.width = targetWidth;\n canvas.height = targetHeight;\n } else {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n \n ctx.save();\n ctx.scale(dpr * scale, dpr * scale);\n ctx.drawImage(image, 0, 0);\n ctx.restore();\n \n // Log render time periodically (every 60 frames)\n defaultProfiler.incrementRenderCount();\n if (defaultProfiler.shouldLogByFrameCount(60)) {\n logger.debug(`[renderTimegroupToCanvas] Frame render: ${renderTime.toFixed(1)}ms (resolutionScale=${currentResolutionScale}, image=${image.width}x${image.height})`);\n }\n \n // Update debug label\n updateDebugLabel(debugLabel, renderWidth, renderHeight, currentResolutionScale);\n } catch (e) {\n logger.error(\"Canvas preview render failed:\", e);\n } finally {\n rendering = false;\n }\n };\n\n /**\n * Dispose the preview and release resources.\n */\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n frameController.abort();\n renderContext.dispose();\n };\n\n // Do initial render\n refresh();\n\n return { container: wrapperContainer, canvas, refresh, syncState, setResolutionScale, getResolutionScale, dispose };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.7-beta",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"license": "UNLICENSED",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@bramus/style-observer": "^1.3.0",
|
|
16
|
-
"@editframe/assets": "0.34.
|
|
16
|
+
"@editframe/assets": "0.34.7-beta",
|
|
17
17
|
"@lit/context": "^1.1.6",
|
|
18
18
|
"@opentelemetry/api": "^1.9.0",
|
|
19
19
|
"@opentelemetry/context-zone": "^1.26.0",
|
|
@@ -45,6 +45,12 @@
|
|
|
45
45
|
"default": "./dist/index.js"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
+
"./node": {
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/node.d.ts",
|
|
51
|
+
"default": "./dist/node.js"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
48
54
|
"./package.json": "./package.json",
|
|
49
55
|
"./styles.css": "./dist/style.css",
|
|
50
56
|
"./types.json": "./types.json"
|
|
@@ -57,6 +63,12 @@
|
|
|
57
63
|
"default": "./dist/index.js"
|
|
58
64
|
}
|
|
59
65
|
},
|
|
66
|
+
"./node": {
|
|
67
|
+
"import": {
|
|
68
|
+
"types": "./dist/node.d.ts",
|
|
69
|
+
"default": "./dist/node.js"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
60
72
|
"./package.json": "./package.json",
|
|
61
73
|
"./styles.css": "./dist/style.css",
|
|
62
74
|
"./types.json": "./types.json"
|
package/tsdown.config.ts
CHANGED
|
@@ -48,6 +48,7 @@ const inlineCssPlugin = (): Plugin => ({
|
|
|
48
48
|
|
|
49
49
|
export default defineConfig(
|
|
50
50
|
createTsdownConfig({
|
|
51
|
+
entry: ["src/index.ts", "src/node.ts"],
|
|
51
52
|
plugins: [inlineCssPlugin()],
|
|
52
53
|
external: [/@editframe\/assets/],
|
|
53
54
|
publint: false, // Disabled because CSS is built after tsdown
|