@editframe/elements 0.34.6-beta → 0.34.8-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/overlays/SelectionOverlay.d.ts +2 -2
- package/dist/elements/EFAudio.d.ts +2 -2
- package/dist/elements/EFCaptions.d.ts +4 -4
- package/dist/elements/EFImage.d.ts +4 -4
- package/dist/elements/EFMedia/JitMediaEngine.js +6 -0
- package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -1
- package/dist/elements/EFMedia.d.ts +2 -2
- package/dist/elements/EFVideo.d.ts +4 -4
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/getRenderInfo.js.map +1 -1
- package/dist/gui/timeline/EFTimelineRow.d.ts +2 -2
- package/dist/node.d.ts +8 -0
- package/dist/node.js +3 -0
- package/package.json +14 -2
- package/tsdown.config.ts +1 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SelectionContext } from "../selection/selectionContext.js";
|
|
2
2
|
import { PanZoomTransform } from "../../elements/EFPanZoom.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit36 from "lit";
|
|
4
4
|
import { LitElement } from "lit";
|
|
5
5
|
import * as lit_html34 from "lit-html";
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ import * as lit_html34 from "lit-html";
|
|
|
10
10
|
* Uses fixed positioning to ensure 1:1 pixel ratio regardless of zoom level.
|
|
11
11
|
*/
|
|
12
12
|
declare class SelectionOverlay extends LitElement {
|
|
13
|
-
static styles:
|
|
13
|
+
static styles: lit36.CSSResult[];
|
|
14
14
|
createRenderRoot(): this;
|
|
15
15
|
firstUpdated(changedProperties: Map<string | number | symbol, unknown>): void;
|
|
16
16
|
selectionFromContext?: SelectionContext;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FrameRenderable, FrameState, FrameTask } from "../preview/FrameController.js";
|
|
2
2
|
import { EFMedia } from "./EFMedia.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html2 from "lit-html";
|
|
4
4
|
import * as lit_html_directives_ref_js1 from "lit-html/directives/ref.js";
|
|
5
5
|
|
|
6
6
|
//#region src/elements/EFAudio.d.ts
|
|
@@ -19,7 +19,7 @@ declare class EFAudio extends EFAudio_base implements FrameRenderable {
|
|
|
19
19
|
volume: number;
|
|
20
20
|
audioElementRef: lit_html_directives_ref_js1.Ref<HTMLAudioElement>;
|
|
21
21
|
protected updated(changedProperties: Map<PropertyKey, unknown>): void;
|
|
22
|
-
render():
|
|
22
|
+
render(): lit_html2.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;
|
|
@@ -23,6 +23,12 @@ var JitMediaEngine = class JitMediaEngine extends BaseMediaEngine {
|
|
|
23
23
|
}
|
|
24
24
|
#cachedVideoRendition = null;
|
|
25
25
|
#cachedAudioRendition = null;
|
|
26
|
+
getVideoRenditionInternal() {
|
|
27
|
+
return this.videoRendition;
|
|
28
|
+
}
|
|
29
|
+
getAudioRenditionInternal() {
|
|
30
|
+
return this.audioRendition;
|
|
31
|
+
}
|
|
26
32
|
get audioRendition() {
|
|
27
33
|
if (this.#cachedAudioRendition !== null) return this.#cachedAudioRendition;
|
|
28
34
|
if (!this.data.audioRenditions || this.data.audioRenditions.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JitMediaEngine.js","names":["#cachedAudioRendition","#cachedVideoRendition","rendition: VideoRendition"],"sources":["../../../src/elements/EFMedia/JitMediaEngine.ts"],"sourcesContent":["import type {\n AudioRendition,\n MediaEngine,\n RenditionId,\n ThumbnailResult,\n VideoRendition,\n} from \"../../transcoding/types\";\nimport type { ManifestResponse } from \"../../transcoding/types/index.js\";\nimport type { UrlGenerator } from \"../../transcoding/utils/UrlGenerator\";\nimport type { EFMedia } from \"../EFMedia.js\";\nimport { BaseMediaEngine } from \"./BaseMediaEngine\";\nimport { ThumbnailExtractor } from \"./shared/ThumbnailExtractor.js\";\n\nexport class JitMediaEngine extends BaseMediaEngine implements MediaEngine {\n private urlGenerator: UrlGenerator;\n private data: ManifestResponse = {} as ManifestResponse;\n private thumbnailExtractor: ThumbnailExtractor;\n\n static async fetch(host: EFMedia, urlGenerator: UrlGenerator, url: string, signal?: AbortSignal) {\n const engine = new JitMediaEngine(host, urlGenerator);\n const data = await engine.fetchManifest(url, signal);\n \n // Check for abort after potentially slow network operation\n signal?.throwIfAborted();\n \n engine.data = data;\n // Set MediaEngine interface properties\n engine.durationMs = data.durationMs;\n engine.src = data.sourceUrl;\n engine.templates = data.endpoints;\n return engine;\n }\n\n // MediaEngine interface properties\n durationMs = 0;\n src = \"\";\n templates!: { initSegment: string; mediaSegment: string };\n\n constructor(host: EFMedia, urlGenerator: UrlGenerator) {\n super(host);\n this.urlGenerator = urlGenerator;\n this.thumbnailExtractor = new ThumbnailExtractor(this);\n }\n\n // Cache renditions to avoid recomputing on every access\n #cachedVideoRendition: VideoRendition | undefined | null = null;\n #cachedAudioRendition: AudioRendition | undefined | null = null;\n\n get audioRendition(): AudioRendition | undefined {\n if (this.#cachedAudioRendition !== null) {\n return this.#cachedAudioRendition;\n }\n if (!this.data.audioRenditions || this.data.audioRenditions.length === 0) {\n this.#cachedAudioRendition = undefined;\n return undefined;\n }\n\n const rendition = this.data.audioRenditions[0];\n if (!rendition) {\n this.#cachedAudioRendition = undefined;\n return undefined;\n }\n\n this.#cachedAudioRendition = {\n id: rendition.id as RenditionId,\n trackId: undefined,\n src: this.data.sourceUrl,\n segmentDurationMs: rendition.segmentDurationMs,\n segmentDurationsMs: rendition.segmentDurationsMs,\n startTimeOffsetMs: rendition.startTimeOffsetMs,\n };\n return this.#cachedAudioRendition;\n }\n\n get videoRendition(): VideoRendition | undefined {\n if (this.#cachedVideoRendition !== null) {\n return this.#cachedVideoRendition;\n }\n if (!this.data.videoRenditions || this.data.videoRenditions.length === 0) {\n this.#cachedVideoRendition = undefined;\n return undefined;\n }\n\n const rendition = this.data.videoRenditions[0];\n if (!rendition) {\n this.#cachedVideoRendition = undefined;\n return undefined;\n }\n\n this.#cachedVideoRendition = {\n id: rendition.id as RenditionId,\n trackId: undefined,\n src: this.data.sourceUrl,\n segmentDurationMs: rendition.segmentDurationMs,\n segmentDurationsMs: rendition.segmentDurationsMs,\n startTimeOffsetMs: rendition.startTimeOffsetMs,\n };\n return this.#cachedVideoRendition;\n }\n\n\n\n async fetchInitSegment(\n rendition: { id?: RenditionId; trackId: number | undefined; src: string },\n signal?: AbortSignal,\n ) {\n if (!rendition.id) {\n throw new Error(\"Rendition ID is required for JIT metadata\");\n }\n const url = this.urlGenerator.generateSegmentUrl(\n \"init\",\n rendition.id,\n this,\n );\n\n // Use unified fetch method\n return this.fetchMedia(url, signal);\n }\n\n async fetchMediaSegment(\n segmentId: number,\n rendition: { id?: RenditionId; trackId: number | undefined; src: string },\n signal?: AbortSignal,\n ) {\n if (!rendition.id) {\n throw new Error(\"Rendition ID is required for JIT metadata\");\n }\n const url = this.urlGenerator.generateSegmentUrl(\n segmentId,\n rendition.id,\n this,\n );\n return this.fetchMedia(url, signal);\n }\n\n computeSegmentId(\n desiredSeekTimeMs: number,\n rendition: VideoRendition | AudioRendition,\n ) {\n // Don't request segments beyond the actual file duration\n // Note: seeking to exactly durationMs should be allowed (it's the last moment of the file)\n if (desiredSeekTimeMs > this.durationMs) {\n return undefined;\n }\n\n // Use actual segment durations if available (more accurate)\n if (\n rendition.segmentDurationsMs &&\n rendition.segmentDurationsMs.length > 0\n ) {\n let cumulativeTime = 0;\n\n for (let i = 0; i < rendition.segmentDurationsMs.length; i++) {\n const segmentDuration = rendition.segmentDurationsMs[i];\n if (segmentDuration === undefined) {\n throw new Error(\"Segment duration is required for JIT metadata\");\n }\n const segmentStartMs = cumulativeTime;\n const segmentEndMs = cumulativeTime + segmentDuration;\n\n // Check if the desired seek time falls within this segment\n // Special case: for the last segment, include the exact end time\n const isLastSegment = i === rendition.segmentDurationsMs.length - 1;\n const includesEndTime =\n isLastSegment && desiredSeekTimeMs === this.durationMs;\n\n if (\n desiredSeekTimeMs >= segmentStartMs &&\n (desiredSeekTimeMs < segmentEndMs || includesEndTime)\n ) {\n return i + 1; // Convert 0-based to 1-based segment ID\n }\n\n cumulativeTime += segmentDuration;\n\n // If we've reached or exceeded file duration, stop\n if (cumulativeTime >= this.durationMs) {\n break;\n }\n }\n\n // If we didn't find a segment, return undefined\n return undefined;\n }\n\n // Fall back to fixed duration calculation for backward compatibility\n if (!rendition.segmentDurationMs) {\n throw new Error(\"Segment duration is required for JIT metadata\");\n }\n\n const segmentIndex = Math.floor(\n desiredSeekTimeMs / rendition.segmentDurationMs,\n );\n\n // Calculate the actual segment start time\n const segmentStartMs = segmentIndex * rendition.segmentDurationMs;\n\n // If this segment would start at or beyond file duration, it doesn't exist\n if (segmentStartMs >= this.durationMs) {\n return undefined;\n }\n\n return segmentIndex + 1; // Convert 0-based to 1-based\n }\n\n getScrubVideoRendition(): VideoRendition | undefined {\n if (!this.data.videoRenditions) return undefined;\n\n const scrubManifestRendition = this.data.videoRenditions.find(\n (r) => r.id === \"scrub\",\n );\n\n if (!scrubManifestRendition) return this.getVideoRenditionInternal(); // Fallback to main\n\n return {\n id: scrubManifestRendition.id as any,\n trackId: undefined,\n src: this.src,\n segmentDurationMs: scrubManifestRendition.segmentDurationMs,\n segmentDurationsMs: scrubManifestRendition.segmentDurationsMs,\n };\n }\n\n /**\n * Get preferred buffer configuration for JIT transcoding\n * Uses higher buffering since transcoding introduces latency\n */\n getBufferConfig() {\n return {\n // Buffer more aggressively for JIT transcoding to smooth over latency\n videoBufferDurationMs: 8000,\n audioBufferDurationMs: 8000,\n maxVideoBufferFetches: 3,\n maxAudioBufferFetches: 3,\n bufferThresholdMs: 30000, // Timeline-aware buffering threshold\n };\n }\n\n /**\n * Extract thumbnail canvases using same rendition priority as video playback for frame alignment\n */\n async extractThumbnails(\n timestamps: number[],\n signal?: AbortSignal,\n ): Promise<(ThumbnailResult | null)[]> {\n // Use same rendition priority as video: try main rendition first for frame alignment\n let rendition: VideoRendition;\n try {\n const mainRendition = this.getVideoRenditionInternal();\n if (mainRendition) {\n rendition = mainRendition;\n } else {\n const scrubRendition = this.getScrubVideoRendition();\n if (scrubRendition) {\n rendition = scrubRendition;\n } else {\n throw new Error(\"No video rendition available\");\n }\n }\n } catch (error) {\n console.warn(\n \"JitMediaEngine: No video rendition available for thumbnails\",\n error,\n );\n return timestamps.map(() => null);\n }\n\n // Use shared thumbnail extraction logic\n return this.thumbnailExtractor.extractThumbnails(\n timestamps,\n rendition,\n this.durationMs,\n signal,\n );\n }\n\n convertToSegmentRelativeTimestamps(\n globalTimestamps: number[],\n _segmentId: number,\n _rendition: VideoRendition,\n ): number[] {\n return globalTimestamps.map((timestamp) => timestamp / 1000);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JitMediaEngine.js","names":["#cachedAudioRendition","#cachedVideoRendition","rendition: VideoRendition"],"sources":["../../../src/elements/EFMedia/JitMediaEngine.ts"],"sourcesContent":["import type {\n AudioRendition,\n MediaEngine,\n RenditionId,\n ThumbnailResult,\n VideoRendition,\n} from \"../../transcoding/types\";\nimport type { ManifestResponse } from \"../../transcoding/types/index.js\";\nimport type { UrlGenerator } from \"../../transcoding/utils/UrlGenerator\";\nimport type { EFMedia } from \"../EFMedia.js\";\nimport { BaseMediaEngine } from \"./BaseMediaEngine\";\nimport { ThumbnailExtractor } from \"./shared/ThumbnailExtractor.js\";\n\nexport class JitMediaEngine extends BaseMediaEngine implements MediaEngine {\n private urlGenerator: UrlGenerator;\n private data: ManifestResponse = {} as ManifestResponse;\n private thumbnailExtractor: ThumbnailExtractor;\n\n static async fetch(host: EFMedia, urlGenerator: UrlGenerator, url: string, signal?: AbortSignal) {\n const engine = new JitMediaEngine(host, urlGenerator);\n const data = await engine.fetchManifest(url, signal);\n \n // Check for abort after potentially slow network operation\n signal?.throwIfAborted();\n \n engine.data = data;\n // Set MediaEngine interface properties\n engine.durationMs = data.durationMs;\n engine.src = data.sourceUrl;\n engine.templates = data.endpoints;\n return engine;\n }\n\n // MediaEngine interface properties\n durationMs = 0;\n src = \"\";\n templates!: { initSegment: string; mediaSegment: string };\n\n constructor(host: EFMedia, urlGenerator: UrlGenerator) {\n super(host);\n this.urlGenerator = urlGenerator;\n this.thumbnailExtractor = new ThumbnailExtractor(this);\n }\n\n // Cache renditions to avoid recomputing on every access\n #cachedVideoRendition: VideoRendition | undefined | null = null;\n #cachedAudioRendition: AudioRendition | undefined | null = null;\n\n // Implement abstract methods required by BaseMediaEngine\n protected getVideoRenditionInternal(): VideoRendition | undefined {\n return this.videoRendition;\n }\n\n protected getAudioRenditionInternal(): AudioRendition | undefined {\n return this.audioRendition;\n }\n\n get audioRendition(): AudioRendition | undefined {\n if (this.#cachedAudioRendition !== null) {\n return this.#cachedAudioRendition;\n }\n if (!this.data.audioRenditions || this.data.audioRenditions.length === 0) {\n this.#cachedAudioRendition = undefined;\n return undefined;\n }\n\n const rendition = this.data.audioRenditions[0];\n if (!rendition) {\n this.#cachedAudioRendition = undefined;\n return undefined;\n }\n\n this.#cachedAudioRendition = {\n id: rendition.id as RenditionId,\n trackId: undefined,\n src: this.data.sourceUrl,\n segmentDurationMs: rendition.segmentDurationMs,\n segmentDurationsMs: rendition.segmentDurationsMs,\n startTimeOffsetMs: rendition.startTimeOffsetMs,\n };\n return this.#cachedAudioRendition;\n }\n\n get videoRendition(): VideoRendition | undefined {\n if (this.#cachedVideoRendition !== null) {\n return this.#cachedVideoRendition;\n }\n if (!this.data.videoRenditions || this.data.videoRenditions.length === 0) {\n this.#cachedVideoRendition = undefined;\n return undefined;\n }\n\n const rendition = this.data.videoRenditions[0];\n if (!rendition) {\n this.#cachedVideoRendition = undefined;\n return undefined;\n }\n\n this.#cachedVideoRendition = {\n id: rendition.id as RenditionId,\n trackId: undefined,\n src: this.data.sourceUrl,\n segmentDurationMs: rendition.segmentDurationMs,\n segmentDurationsMs: rendition.segmentDurationsMs,\n startTimeOffsetMs: rendition.startTimeOffsetMs,\n };\n return this.#cachedVideoRendition;\n }\n\n\n\n async fetchInitSegment(\n rendition: { id?: RenditionId; trackId: number | undefined; src: string },\n signal?: AbortSignal,\n ) {\n if (!rendition.id) {\n throw new Error(\"Rendition ID is required for JIT metadata\");\n }\n const url = this.urlGenerator.generateSegmentUrl(\n \"init\",\n rendition.id,\n this,\n );\n\n // Use unified fetch method\n return this.fetchMedia(url, signal);\n }\n\n async fetchMediaSegment(\n segmentId: number,\n rendition: { id?: RenditionId; trackId: number | undefined; src: string },\n signal?: AbortSignal,\n ) {\n if (!rendition.id) {\n throw new Error(\"Rendition ID is required for JIT metadata\");\n }\n const url = this.urlGenerator.generateSegmentUrl(\n segmentId,\n rendition.id,\n this,\n );\n return this.fetchMedia(url, signal);\n }\n\n computeSegmentId(\n desiredSeekTimeMs: number,\n rendition: VideoRendition | AudioRendition,\n ) {\n // Don't request segments beyond the actual file duration\n // Note: seeking to exactly durationMs should be allowed (it's the last moment of the file)\n if (desiredSeekTimeMs > this.durationMs) {\n return undefined;\n }\n\n // Use actual segment durations if available (more accurate)\n if (\n rendition.segmentDurationsMs &&\n rendition.segmentDurationsMs.length > 0\n ) {\n let cumulativeTime = 0;\n\n for (let i = 0; i < rendition.segmentDurationsMs.length; i++) {\n const segmentDuration = rendition.segmentDurationsMs[i];\n if (segmentDuration === undefined) {\n throw new Error(\"Segment duration is required for JIT metadata\");\n }\n const segmentStartMs = cumulativeTime;\n const segmentEndMs = cumulativeTime + segmentDuration;\n\n // Check if the desired seek time falls within this segment\n // Special case: for the last segment, include the exact end time\n const isLastSegment = i === rendition.segmentDurationsMs.length - 1;\n const includesEndTime =\n isLastSegment && desiredSeekTimeMs === this.durationMs;\n\n if (\n desiredSeekTimeMs >= segmentStartMs &&\n (desiredSeekTimeMs < segmentEndMs || includesEndTime)\n ) {\n return i + 1; // Convert 0-based to 1-based segment ID\n }\n\n cumulativeTime += segmentDuration;\n\n // If we've reached or exceeded file duration, stop\n if (cumulativeTime >= this.durationMs) {\n break;\n }\n }\n\n // If we didn't find a segment, return undefined\n return undefined;\n }\n\n // Fall back to fixed duration calculation for backward compatibility\n if (!rendition.segmentDurationMs) {\n throw new Error(\"Segment duration is required for JIT metadata\");\n }\n\n const segmentIndex = Math.floor(\n desiredSeekTimeMs / rendition.segmentDurationMs,\n );\n\n // Calculate the actual segment start time\n const segmentStartMs = segmentIndex * rendition.segmentDurationMs;\n\n // If this segment would start at or beyond file duration, it doesn't exist\n if (segmentStartMs >= this.durationMs) {\n return undefined;\n }\n\n return segmentIndex + 1; // Convert 0-based to 1-based\n }\n\n getScrubVideoRendition(): VideoRendition | undefined {\n if (!this.data.videoRenditions) return undefined;\n\n const scrubManifestRendition = this.data.videoRenditions.find(\n (r) => r.id === \"scrub\",\n );\n\n if (!scrubManifestRendition) return this.getVideoRenditionInternal(); // Fallback to main\n\n return {\n id: scrubManifestRendition.id as any,\n trackId: undefined,\n src: this.src,\n segmentDurationMs: scrubManifestRendition.segmentDurationMs,\n segmentDurationsMs: scrubManifestRendition.segmentDurationsMs,\n };\n }\n\n /**\n * Get preferred buffer configuration for JIT transcoding\n * Uses higher buffering since transcoding introduces latency\n */\n getBufferConfig() {\n return {\n // Buffer more aggressively for JIT transcoding to smooth over latency\n videoBufferDurationMs: 8000,\n audioBufferDurationMs: 8000,\n maxVideoBufferFetches: 3,\n maxAudioBufferFetches: 3,\n bufferThresholdMs: 30000, // Timeline-aware buffering threshold\n };\n }\n\n /**\n * Extract thumbnail canvases using same rendition priority as video playback for frame alignment\n */\n async extractThumbnails(\n timestamps: number[],\n signal?: AbortSignal,\n ): Promise<(ThumbnailResult | null)[]> {\n // Use same rendition priority as video: try main rendition first for frame alignment\n let rendition: VideoRendition;\n try {\n const mainRendition = this.getVideoRenditionInternal();\n if (mainRendition) {\n rendition = mainRendition;\n } else {\n const scrubRendition = this.getScrubVideoRendition();\n if (scrubRendition) {\n rendition = scrubRendition;\n } else {\n throw new Error(\"No video rendition available\");\n }\n }\n } catch (error) {\n console.warn(\n \"JitMediaEngine: No video rendition available for thumbnails\",\n error,\n );\n return timestamps.map(() => null);\n }\n\n // Use shared thumbnail extraction logic\n return this.thumbnailExtractor.extractThumbnails(\n timestamps,\n rendition,\n this.durationMs,\n signal,\n );\n }\n\n convertToSegmentRelativeTimestamps(\n globalTimestamps: number[],\n _segmentId: number,\n _rendition: VideoRendition,\n ): number[] {\n return globalTimestamps.map((timestamp) => timestamp / 1000);\n }\n}\n"],"mappings":";;;;AAaA,IAAa,iBAAb,MAAa,uBAAuB,gBAAuC;CAKzE,aAAa,MAAM,MAAe,cAA4B,KAAa,QAAsB;EAC/F,MAAM,SAAS,IAAI,eAAe,MAAM,aAAa;EACrD,MAAM,OAAO,MAAM,OAAO,cAAc,KAAK,OAAO;AAGpD,UAAQ,gBAAgB;AAExB,SAAO,OAAO;AAEd,SAAO,aAAa,KAAK;AACzB,SAAO,MAAM,KAAK;AAClB,SAAO,YAAY,KAAK;AACxB,SAAO;;CAQT,YAAY,MAAe,cAA4B;AACrD,QAAM,KAAK;cAxBoB,EAAE;oBAmBtB;aACP;AAKJ,OAAK,eAAe;AACpB,OAAK,qBAAqB,IAAI,mBAAmB,KAAK;;CAIxD,wBAA2D;CAC3D,wBAA2D;CAG3D,AAAU,4BAAwD;AAChE,SAAO,KAAK;;CAGd,AAAU,4BAAwD;AAChE,SAAO,KAAK;;CAGd,IAAI,iBAA6C;AAC/C,MAAI,MAAKA,yBAA0B,KACjC,QAAO,MAAKA;AAEd,MAAI,CAAC,KAAK,KAAK,mBAAmB,KAAK,KAAK,gBAAgB,WAAW,GAAG;AACxE,SAAKA,uBAAwB;AAC7B;;EAGF,MAAM,YAAY,KAAK,KAAK,gBAAgB;AAC5C,MAAI,CAAC,WAAW;AACd,SAAKA,uBAAwB;AAC7B;;AAGF,QAAKA,uBAAwB;GAC3B,IAAI,UAAU;GACd,SAAS;GACT,KAAK,KAAK,KAAK;GACf,mBAAmB,UAAU;GAC7B,oBAAoB,UAAU;GAC9B,mBAAmB,UAAU;GAC9B;AACD,SAAO,MAAKA;;CAGd,IAAI,iBAA6C;AAC/C,MAAI,MAAKC,yBAA0B,KACjC,QAAO,MAAKA;AAEd,MAAI,CAAC,KAAK,KAAK,mBAAmB,KAAK,KAAK,gBAAgB,WAAW,GAAG;AACxE,SAAKA,uBAAwB;AAC7B;;EAGF,MAAM,YAAY,KAAK,KAAK,gBAAgB;AAC5C,MAAI,CAAC,WAAW;AACd,SAAKA,uBAAwB;AAC7B;;AAGF,QAAKA,uBAAwB;GAC3B,IAAI,UAAU;GACd,SAAS;GACT,KAAK,KAAK,KAAK;GACf,mBAAmB,UAAU;GAC7B,oBAAoB,UAAU;GAC9B,mBAAmB,UAAU;GAC9B;AACD,SAAO,MAAKA;;CAKd,MAAM,iBACJ,WACA,QACA;AACA,MAAI,CAAC,UAAU,GACb,OAAM,IAAI,MAAM,4CAA4C;EAE9D,MAAM,MAAM,KAAK,aAAa,mBAC5B,QACA,UAAU,IACV,KACD;AAGD,SAAO,KAAK,WAAW,KAAK,OAAO;;CAGrC,MAAM,kBACJ,WACA,WACA,QACA;AACA,MAAI,CAAC,UAAU,GACb,OAAM,IAAI,MAAM,4CAA4C;EAE9D,MAAM,MAAM,KAAK,aAAa,mBAC5B,WACA,UAAU,IACV,KACD;AACD,SAAO,KAAK,WAAW,KAAK,OAAO;;CAGrC,iBACE,mBACA,WACA;AAGA,MAAI,oBAAoB,KAAK,WAC3B;AAIF,MACE,UAAU,sBACV,UAAU,mBAAmB,SAAS,GACtC;GACA,IAAI,iBAAiB;AAErB,QAAK,IAAI,IAAI,GAAG,IAAI,UAAU,mBAAmB,QAAQ,KAAK;IAC5D,MAAM,kBAAkB,UAAU,mBAAmB;AACrD,QAAI,oBAAoB,OACtB,OAAM,IAAI,MAAM,gDAAgD;IAElE,MAAM,iBAAiB;IACvB,MAAM,eAAe,iBAAiB;IAKtC,MAAM,kBADgB,MAAM,UAAU,mBAAmB,SAAS,KAE/C,sBAAsB,KAAK;AAE9C,QACE,qBAAqB,mBACpB,oBAAoB,gBAAgB,iBAErC,QAAO,IAAI;AAGb,sBAAkB;AAGlB,QAAI,kBAAkB,KAAK,WACzB;;AAKJ;;AAIF,MAAI,CAAC,UAAU,kBACb,OAAM,IAAI,MAAM,gDAAgD;EAGlE,MAAM,eAAe,KAAK,MACxB,oBAAoB,UAAU,kBAC/B;AAMD,MAHuB,eAAe,UAAU,qBAG1B,KAAK,WACzB;AAGF,SAAO,eAAe;;CAGxB,yBAAqD;AACnD,MAAI,CAAC,KAAK,KAAK,gBAAiB,QAAO;EAEvC,MAAM,yBAAyB,KAAK,KAAK,gBAAgB,MACtD,MAAM,EAAE,OAAO,QACjB;AAED,MAAI,CAAC,uBAAwB,QAAO,KAAK,2BAA2B;AAEpE,SAAO;GACL,IAAI,uBAAuB;GAC3B,SAAS;GACT,KAAK,KAAK;GACV,mBAAmB,uBAAuB;GAC1C,oBAAoB,uBAAuB;GAC5C;;;;;;CAOH,kBAAkB;AAChB,SAAO;GAEL,uBAAuB;GACvB,uBAAuB;GACvB,uBAAuB;GACvB,uBAAuB;GACvB,mBAAmB;GACpB;;;;;CAMH,MAAM,kBACJ,YACA,QACqC;EAErC,IAAIC;AACJ,MAAI;GACF,MAAM,gBAAgB,KAAK,2BAA2B;AACtD,OAAI,cACF,aAAY;QACP;IACL,MAAM,iBAAiB,KAAK,wBAAwB;AACpD,QAAI,eACF,aAAY;QAEZ,OAAM,IAAI,MAAM,+BAA+B;;WAG5C,OAAO;AACd,WAAQ,KACN,+DACA,MACD;AACD,UAAO,WAAW,UAAU,KAAK;;AAInC,SAAO,KAAK,mBAAmB,kBAC7B,YACA,WACA,KAAK,YACL,OACD;;CAGH,mCACE,kBACA,YACA,YACU;AACV,SAAO,iBAAiB,KAAK,cAAc,YAAY,IAAK"}
|
|
@@ -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,9 +1,9 @@
|
|
|
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 lit3 from "lit";
|
|
5
5
|
import { PropertyValueMap } from "lit";
|
|
6
|
-
import * as
|
|
6
|
+
import * as lit_html3 from "lit-html";
|
|
7
7
|
import * as lit_html_directives_ref0 from "lit-html/directives/ref";
|
|
8
8
|
|
|
9
9
|
//#region src/elements/EFVideo.d.ts
|
|
@@ -23,7 +23,7 @@ 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:
|
|
26
|
+
static styles: lit3.CSSResult[];
|
|
27
27
|
canvasRef: lit_html_directives_ref0.Ref<HTMLCanvasElement>;
|
|
28
28
|
/**
|
|
29
29
|
* Duration in milliseconds for video buffering ahead of current time
|
|
@@ -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_html3.TemplateResult<1>;
|
|
80
80
|
get canvasElement(): HTMLCanvasElement | undefined;
|
|
81
81
|
/**
|
|
82
82
|
* @deprecated Use FrameRenderable methods (prepareFrame, renderFrame) via FrameController instead.
|
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,5 +1,5 @@
|
|
|
1
1
|
import { TemporalMixinInterface } from "../../elements/EFTemporal.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit37 from "lit";
|
|
3
3
|
import { LitElement, PropertyValues, TemplateResult, nothing } from "lit";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/timeline/EFTimelineRow.d.ts
|
|
@@ -14,7 +14,7 @@ declare const EFTimelineRow_base: typeof LitElement;
|
|
|
14
14
|
* Heights are determined by content, not hardcoded.
|
|
15
15
|
*/
|
|
16
16
|
declare class EFTimelineRow extends EFTimelineRow_base {
|
|
17
|
-
static styles:
|
|
17
|
+
static styles: lit37.CSSResult[];
|
|
18
18
|
element: TemporalMixinInterface & Element;
|
|
19
19
|
depth: number;
|
|
20
20
|
pixelsPerMs: number;
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.8-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.8-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
|