@frame-by-frame/core 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,451 @@
1
+ //#region src/types.d.ts
2
+ /** The coordinate system used by every segment in one timeline. */
3
+ type ScrollUnit = "px" | "progress";
4
+ /** CSS-compatible easing keywords supported by the timeline engine. */
5
+ type EasingName = "linear" | "ease-in" | "ease-out" | "ease-in-out";
6
+ /** A custom easing function receives and returns normalized progress. */
7
+ type EasingFunction = (progress: number) => number;
8
+ /** A named or custom easing definition. */
9
+ type Easing = EasingName | EasingFunction;
10
+ /** A mapping between one scroll interval and one media-time interval. */
11
+ interface TimelineSegment {
12
+ /** Scroll interval expressed in `scrollUnit`. */
13
+ readonly scroll: readonly [start: number, end: number];
14
+ /** Media-time interval in seconds; forward and reverse ranges are valid. */
15
+ readonly media: readonly [start: number, end: number];
16
+ /** Coordinate unit, defaulting to pixels. */
17
+ readonly scrollUnit?: ScrollUnit;
18
+ /** Opaque media clip ID carried through resolution. */
19
+ readonly clip?: string;
20
+ /** Override for the timeline-level easing default. */
21
+ readonly easing?: Easing;
22
+ }
23
+ /** Frame snapping is disabled unless `snap` is explicitly enabled. */
24
+ type FrameConfig = {
25
+ /** Explicitly keeps frame snapping disabled. */
26
+ readonly snap?: false;
27
+ readonly fps?: never;
28
+ } | {
29
+ /** Enables nearest-frame snapping. */
30
+ readonly snap: true;
31
+ /** Finite, positive frame rate used for snapping. */
32
+ readonly fps: number;
33
+ };
34
+ /** Configuration captured by `createTimeline`. */
35
+ interface TimelineOptions {
36
+ /** Non-empty collection of mappings normalized at creation time. */
37
+ readonly segments: readonly TimelineSegment[];
38
+ /** Default easing inherited by segments without an override. */
39
+ readonly easing?: Easing;
40
+ /** Optional nearest-frame snapping configuration. */
41
+ readonly frame?: FrameConfig;
42
+ }
43
+ /** The timeline region containing a resolved position. */
44
+ type TimelinePhase = "before" | "active" | "gap" | "after";
45
+ /** The deterministic result of resolving one timeline position. */
46
+ interface TimelineResolution {
47
+ /** Region of the timeline containing the position. */
48
+ readonly phase: TimelinePhase;
49
+ /** Original input index when `phase` is `active`. */
50
+ readonly segmentIndex: number | null;
51
+ /** Clip selected by the active or held segment. */
52
+ readonly clipId: string | null;
53
+ /** Linear progress inside an active segment. */
54
+ readonly rawProgress: number | null;
55
+ /** Progress after easing inside an active segment. */
56
+ readonly easedProgress: number | null;
57
+ /** Continuous media time before frame snapping. */
58
+ readonly requestedTime: number;
59
+ /** Effective media time after optional frame snapping. */
60
+ readonly targetTime: number;
61
+ }
62
+ /** An immutable, normalized timeline that can resolve positions repeatedly. */
63
+ interface Timeline {
64
+ /** Effective unit shared by every normalized segment. */
65
+ readonly unit: ScrollUnit;
66
+ /** Resolves one finite position without mutating timeline state. */
67
+ resolve(position: number): TimelineResolution;
68
+ }
69
+ /** An independently observed scroll axis. */
70
+ type AxisName = "x" | "y";
71
+ /** A DOM scroll source resolved only when a controller mounts. */
72
+ type ScrollSource = Document | HTMLElement;
73
+ /** A direct, selected, or lazily resolved scroll source. */
74
+ type ScrollSourceReference = ScrollSource | string | (() => ScrollSource | null);
75
+ /** A direct, selected, or lazily resolved DOM element. */
76
+ type ElementReference<T extends Element = HTMLElement> = T | string | (() => T | null);
77
+ /** Renderer implementations available across the package entry points. */
78
+ type RendererType = "video" | "canvas";
79
+ /** Native hints plus explicit package-managed full-file preload. */
80
+ type VideoPreload = "none" | "metadata" | "auto" | "full";
81
+ /** Events that may activate an on-demand media binding. */
82
+ type VideoLoadingTrigger = "manual" | "target-near-viewport" | "first-use";
83
+ /** Loading policy shared by the clips in one binding. */
84
+ type VideoLoadingConfig = {
85
+ /** Immediate loading is the default policy. */
86
+ readonly mode?: "immediate";
87
+ readonly trigger?: never;
88
+ readonly rootMargin?: never;
89
+ /** Fetch credentials used only by clips configured with preload full. */
90
+ readonly credentials?: RequestCredentials;
91
+ /** Fetch cache mode used only by clips configured with preload full. */
92
+ readonly cache?: RequestCache;
93
+ } | {
94
+ readonly mode: "on-demand";
95
+ readonly trigger: "target-near-viewport";
96
+ /** IntersectionObserver root margin; defaults to 0px. */
97
+ readonly rootMargin?: string;
98
+ readonly credentials?: RequestCredentials;
99
+ readonly cache?: RequestCache;
100
+ } | {
101
+ readonly mode: "on-demand";
102
+ readonly trigger: "manual" | "first-use";
103
+ readonly rootMargin?: never;
104
+ readonly credentials?: RequestCredentials;
105
+ readonly cache?: RequestCache;
106
+ };
107
+ /** Valid values for the media element crossorigin attribute. */
108
+ type MediaCrossOrigin = "" | "anonymous" | "use-credentials";
109
+ /** One ordered candidate for a video clip. */
110
+ interface VideoSourceConfig {
111
+ /** URL assigned to the video element when this candidate is selected. */
112
+ readonly src: string;
113
+ /** Optional MIME type, including codecs when known. */
114
+ readonly type?: string;
115
+ }
116
+ /** One logical media asset that timeline segments may select by ID. */
117
+ interface VideoClipConfig {
118
+ /** Unique clip ID within one binding. */
119
+ readonly id: string;
120
+ /** Ordered source candidates for the same content. */
121
+ readonly sources: readonly VideoSourceConfig[];
122
+ /** Optional poster applied while this clip is active. */
123
+ readonly poster?: string;
124
+ /** Optional CORS mode applied before the selected source. */
125
+ readonly crossOrigin?: MediaCrossOrigin;
126
+ /** Native preload hint; defaults to metadata. */
127
+ readonly preload?: VideoPreload;
128
+ }
129
+ /** Property overrides for a supplied or package-created video target. */
130
+ interface VideoRendererConfig {
131
+ readonly muted?: boolean;
132
+ readonly playsInline?: boolean;
133
+ readonly controls?: boolean;
134
+ readonly loop?: boolean;
135
+ }
136
+ /** Bounded native seek scheduling options. */
137
+ interface VideoSeekConfig {
138
+ /** Smallest meaningful target-time change in seconds; defaults to 0.001. */
139
+ readonly timeEpsilon?: number;
140
+ }
141
+ /** Timeline and video-decoder configuration shared by every media binding. */
142
+ interface FrameByFrameBindingBaseConfig extends TimelineOptions {
143
+ /** Unique binding ID within one controller. */
144
+ readonly id: string;
145
+ /** Non-empty logical clips referenced by timeline segments. */
146
+ readonly clips: readonly VideoClipConfig[];
147
+ /** Binding-level eager or on-demand loading policy. */
148
+ readonly loading?: VideoLoadingConfig;
149
+ /** Optional video property overrides. */
150
+ readonly video?: VideoRendererConfig;
151
+ /** Optional native seek scheduler settings. */
152
+ readonly seek?: VideoSeekConfig;
153
+ }
154
+ /** One named native-video timeline controlled by a scroll axis. */
155
+ type FrameByFrameBindingConfig = FrameByFrameBindingBaseConfig & ({
156
+ /** Native video is the default renderer for the root package entry. */
157
+ readonly renderer?: "video";
158
+ /** Existing video target resolved during mount. */
159
+ readonly target: ElementReference<HTMLVideoElement>;
160
+ readonly mountTo?: never;
161
+ readonly canvas?: never;
162
+ } | {
163
+ /** Native video is the default renderer for the root package entry. */
164
+ readonly renderer?: "video";
165
+ readonly target?: never;
166
+ /** Container where the package creates and owns a video target. */
167
+ readonly mountTo: ElementReference;
168
+ readonly canvas?: never;
169
+ });
170
+ /** How a decoded video frame is fitted into the visible canvas. */
171
+ type CanvasFit = "contain" | "cover" | "fill" | "none";
172
+ /** Canvas presentation and optional decoder ownership. */
173
+ interface CanvasRendererConfig {
174
+ /** Frame fitting mode; defaults to contain. */
175
+ readonly fit?: CanvasFit;
176
+ /** Bitmap-to-CSS scale; defaults to the current device pixel ratio. */
177
+ readonly pixelRatio?: number | "device";
178
+ /** Canvas 2D interpolation setting; defaults to true. */
179
+ readonly imageSmoothingEnabled?: boolean;
180
+ /** Existing video used as the decoder instead of an internal detached element. */
181
+ readonly decoderTarget?: ElementReference<HTMLVideoElement>;
182
+ }
183
+ /** Canvas fields that responsive breakpoints may change without replacing ownership. */
184
+ interface CanvasRendererOverride {
185
+ readonly fit?: CanvasFit;
186
+ readonly pixelRatio?: number | "device";
187
+ readonly imageSmoothingEnabled?: boolean;
188
+ }
189
+ /** One named canvas timeline backed by a native video decoder. */
190
+ type CanvasBindingConfig = FrameByFrameBindingBaseConfig & ({
191
+ readonly renderer: "canvas";
192
+ /** Existing visible canvas resolved during mount. */
193
+ readonly target: ElementReference<HTMLCanvasElement>;
194
+ readonly mountTo?: never;
195
+ readonly canvas?: CanvasRendererConfig;
196
+ } | {
197
+ readonly renderer: "canvas";
198
+ readonly target?: never;
199
+ /** Container where the package creates and owns a visible canvas. */
200
+ readonly mountTo: ElementReference;
201
+ readonly canvas?: CanvasRendererConfig;
202
+ });
203
+ /** A video or canvas binding accepted by the opt-in canvas entry point. */
204
+ type CanvasFrameByFrameBindingConfig = FrameByFrameBindingConfig | CanvasBindingConfig;
205
+ /** Configuration for one independent scroll axis. */
206
+ interface FrameByFrameAxisConfig {
207
+ /** Whether this axis participates in updates; defaults to true. */
208
+ readonly enabled?: boolean;
209
+ /** Non-empty timeline bindings driven by this axis. */
210
+ readonly bindings: readonly FrameByFrameBindingConfig[];
211
+ }
212
+ /** Horizontal and vertical controller configuration. */
213
+ interface FrameByFrameAxesConfig {
214
+ readonly x?: false | FrameByFrameAxisConfig;
215
+ readonly y?: false | FrameByFrameAxisConfig;
216
+ }
217
+ /** One axis accepted by the opt-in canvas entry point. */
218
+ interface CanvasFrameByFrameAxisConfig {
219
+ readonly enabled?: boolean;
220
+ readonly bindings: readonly CanvasFrameByFrameBindingConfig[];
221
+ }
222
+ /** Axes accepted by the opt-in canvas entry point. */
223
+ interface CanvasFrameByFrameAxesConfig {
224
+ readonly x?: false | CanvasFrameByFrameAxisConfig;
225
+ readonly y?: false | CanvasFrameByFrameAxisConfig;
226
+ }
227
+ /** Timeline and media fields that a responsive breakpoint may replace or merge. */
228
+ interface FrameByFrameBindingOverride {
229
+ /** Existing binding ID selected for this override. */
230
+ readonly id: string;
231
+ /** Replaces the binding's complete segment collection. */
232
+ readonly segments?: readonly TimelineSegment[];
233
+ /** Replaces the binding's complete clip collection. */
234
+ readonly clips?: readonly VideoClipConfig[];
235
+ /** Overrides the timeline-level easing default. */
236
+ readonly easing?: Easing;
237
+ /** Shallowly overrides frame snapping options. */
238
+ readonly frame?: FrameConfig;
239
+ /** Shallowly overrides loading options. */
240
+ readonly loading?: VideoLoadingConfig;
241
+ /** Shallowly overrides native video properties. */
242
+ readonly video?: VideoRendererConfig;
243
+ /** Shallowly overrides native seek options. */
244
+ readonly seek?: VideoSeekConfig;
245
+ }
246
+ /** Binding override accepted by the canvas-enabled responsive cascade. */
247
+ interface CanvasFrameByFrameBindingOverride extends FrameByFrameBindingOverride {
248
+ /** Shallowly overrides canvas presentation without changing the decoder target. */
249
+ readonly canvas?: CanvasRendererOverride;
250
+ }
251
+ /** Responsive changes for one existing controller axis. */
252
+ interface FrameByFrameAxisOverride {
253
+ /** Disables or re-enables the axis without removing its bindings. */
254
+ readonly enabled?: boolean;
255
+ /** Overrides merged into existing bindings by stable ID. */
256
+ readonly bindings?: readonly FrameByFrameBindingOverride[];
257
+ }
258
+ /** Responsive changes scoped to existing axes and bindings. */
259
+ interface FrameByFrameBreakpointOverride {
260
+ readonly axes: {
261
+ readonly x?: false | FrameByFrameAxisOverride;
262
+ readonly y?: false | FrameByFrameAxisOverride;
263
+ };
264
+ }
265
+ /** One ordered media-query override in the responsive cascade. */
266
+ interface FrameByFrameBreakpointConfig {
267
+ /** Unique stable ID exposed by controller state and events. */
268
+ readonly id: string;
269
+ /** Media query evaluated only after mount. */
270
+ readonly query: string;
271
+ /** Partial configuration applied while the query matches. */
272
+ readonly override: FrameByFrameBreakpointOverride;
273
+ }
274
+ /** Responsive axis changes accepted by the canvas-enabled entry point. */
275
+ interface CanvasFrameByFrameAxisOverride {
276
+ readonly enabled?: boolean;
277
+ readonly bindings?: readonly CanvasFrameByFrameBindingOverride[];
278
+ }
279
+ /** Responsive changes accepted by the canvas-enabled entry point. */
280
+ interface CanvasFrameByFrameBreakpointOverride {
281
+ readonly axes: {
282
+ readonly x?: false | CanvasFrameByFrameAxisOverride;
283
+ readonly y?: false | CanvasFrameByFrameAxisOverride;
284
+ };
285
+ }
286
+ /** One ordered media-query override for a canvas-enabled controller. */
287
+ interface CanvasFrameByFrameBreakpointConfig {
288
+ readonly id: string;
289
+ readonly query: string;
290
+ readonly override: CanvasFrameByFrameBreakpointOverride;
291
+ }
292
+ /** How an active reduced-motion preference affects media bindings. */
293
+ type ReducedMotionBehavior = "first-frame" | "last-frame" | "disable" | "ignore";
294
+ /** Configuration captured by `createFrameByFrame`. */
295
+ interface FrameByFrameOptions {
296
+ /** Scroll source resolved during mount; omission selects the document. */
297
+ readonly source?: ScrollSourceReference;
298
+ /** At least one configured axis with one binding is required. */
299
+ readonly axes: FrameByFrameAxesConfig;
300
+ /** Ordered responsive overrides; later matching entries win. */
301
+ readonly breakpoints?: readonly FrameByFrameBreakpointConfig[];
302
+ /** Reduced-motion behavior; defaults to first-frame. */
303
+ readonly reducedMotion?: ReducedMotionBehavior;
304
+ }
305
+ /** Configuration captured by the opt-in canvas-enabled factory. */
306
+ interface CanvasFrameByFrameOptions {
307
+ readonly source?: ScrollSourceReference;
308
+ readonly axes: CanvasFrameByFrameAxesConfig;
309
+ readonly breakpoints?: readonly CanvasFrameByFrameBreakpointConfig[];
310
+ readonly reducedMotion?: ReducedMotionBehavior;
311
+ }
312
+ /** Controller lifecycle states. */
313
+ type FrameByFrameStatus = "idle" | "mounting" | "ready" | "disabled" | "error" | "destroyed";
314
+ /** Read-only public shape of package errors stored in state and events. */
315
+ interface FrameByFrameErrorInfo extends Error {
316
+ readonly name: "FrameByFrameError";
317
+ readonly code: FrameByFrameErrorCode;
318
+ readonly cause: unknown;
319
+ readonly details: FrameByFrameErrorDetails | undefined;
320
+ }
321
+ /** Last observed metrics for one axis. */
322
+ interface FrameByFrameAxisState {
323
+ readonly enabled: boolean;
324
+ readonly offset: number;
325
+ readonly max: number;
326
+ readonly progress: number;
327
+ }
328
+ /** Last timeline resolution for one binding. */
329
+ interface FrameByFrameBindingState {
330
+ readonly id: string;
331
+ readonly axis: AxisName;
332
+ readonly resolution: TimelineResolution | null;
333
+ readonly renderer: RendererType;
334
+ readonly loadState: VideoLoadState;
335
+ /** Full-preload progress keyed by clip ID. */
336
+ readonly loadProgress: Readonly<Record<string, VideoLoadProgress>>;
337
+ readonly activeClipId: string | null;
338
+ readonly selectedSource: string | null;
339
+ readonly duration: number | null;
340
+ readonly appliedTime: number | null;
341
+ readonly presentedTime: number | null;
342
+ readonly seeking: boolean;
343
+ readonly error: FrameByFrameErrorInfo | null;
344
+ }
345
+ /** Native media readiness for a controller binding. */
346
+ type VideoLoadState = "idle" | "loading" | "metadata" | "ready" | "error" | "unloaded";
347
+ /** Byte progress for one explicit full-file preload. */
348
+ interface VideoLoadProgress {
349
+ readonly loadedBytes: number;
350
+ readonly totalBytes: number | null;
351
+ readonly ratio: number | null;
352
+ }
353
+ /** Detached controller state for debugging and framework integration. */
354
+ interface FrameByFrameState {
355
+ readonly status: FrameByFrameStatus;
356
+ readonly enabled: boolean;
357
+ readonly source: ScrollSource | null;
358
+ readonly activeBreakpoints: readonly string[];
359
+ readonly prefersReducedMotion: boolean;
360
+ readonly axes: Readonly<Partial<Record<AxisName, FrameByFrameAxisState>>>;
361
+ readonly bindings: Readonly<Record<string, FrameByFrameBindingState>>;
362
+ readonly lastError: FrameByFrameErrorInfo | null;
363
+ }
364
+ /** Why the controller published an update snapshot. */
365
+ type FrameByFrameUpdateReason = "mount" | "scroll" | "refresh" | "enable" | "disable" | "breakpoint" | "preference" | "resize" | "visibility";
366
+ /** Payload emitted after one coalesced controller update. */
367
+ interface FrameByFrameUpdateEvent {
368
+ readonly reason: FrameByFrameUpdateReason;
369
+ readonly state: FrameByFrameState;
370
+ }
371
+ /** Payload emitted after the active responsive cascade changes successfully. */
372
+ interface FrameByFrameBreakpointChangeEvent {
373
+ readonly previous: readonly string[];
374
+ readonly current: readonly string[];
375
+ readonly state: FrameByFrameState;
376
+ }
377
+ /** Shared identity and state included by media lifecycle events. */
378
+ interface FrameByFrameBindingEvent {
379
+ readonly bindingId: string;
380
+ readonly clipId: string;
381
+ readonly state: FrameByFrameState;
382
+ }
383
+ /** Metadata became available for the selected clip. */
384
+ interface FrameByFrameLoadedMetadataEvent extends FrameByFrameBindingEvent {
385
+ readonly duration: number | null;
386
+ }
387
+ /** Full-file preload progress for one binding clip. */
388
+ interface FrameByFrameLoadProgressEvent extends FrameByFrameBindingEvent {
389
+ readonly loadedBytes: number;
390
+ readonly totalBytes: number | null;
391
+ readonly ratio: number | null;
392
+ }
393
+ /** A meaningful seek was submitted to the native video target. */
394
+ interface FrameByFrameSeekRequestEvent extends FrameByFrameBindingEvent {
395
+ readonly requestedTime: number;
396
+ readonly targetTime: number;
397
+ }
398
+ /** A frame was observed at or near browser composition. */
399
+ interface FrameByFrameFrameEvent extends FrameByFrameBindingEvent {
400
+ readonly presentedTime: number;
401
+ readonly expectedDisplayTime: number | null;
402
+ readonly width: number | null;
403
+ readonly height: number | null;
404
+ }
405
+ /** Public event payloads available in the controller foundation. */
406
+ interface FrameByFrameEventMap {
407
+ readonly mount: FrameByFrameState;
408
+ readonly update: FrameByFrameUpdateEvent;
409
+ readonly breakpointchange: FrameByFrameBreakpointChangeEvent;
410
+ readonly loadstart: FrameByFrameBindingEvent;
411
+ readonly loadprogress: FrameByFrameLoadProgressEvent;
412
+ readonly loadedmetadata: FrameByFrameLoadedMetadataEvent;
413
+ readonly loadready: FrameByFrameBindingEvent;
414
+ readonly seekrequest: FrameByFrameSeekRequestEvent;
415
+ readonly frame: FrameByFrameFrameEvent;
416
+ readonly error: FrameByFrameErrorInfo;
417
+ readonly destroy: FrameByFrameState;
418
+ }
419
+ /** Framework-independent controller lifecycle and state API. */
420
+ interface FrameByFrameController {
421
+ mount(): Promise<void>;
422
+ refresh(): void;
423
+ enable(): void;
424
+ disable(): void;
425
+ load(bindingId?: string): Promise<void>;
426
+ /** Waits for the latest automatically scheduled media readiness cycle. */
427
+ whenReady(): Promise<FrameByFrameState>;
428
+ unload(bindingId?: string): void;
429
+ getTarget(bindingId: string): HTMLVideoElement | null;
430
+ getState(): FrameByFrameState;
431
+ on<EventName extends keyof FrameByFrameEventMap>(event: EventName, listener: (payload: FrameByFrameEventMap[EventName]) => void): () => void;
432
+ destroy(): void;
433
+ }
434
+ /** Controller returned by the opt-in canvas entry point. */
435
+ interface CanvasFrameByFrameController extends Omit<FrameByFrameController, "getTarget"> {
436
+ getTarget(bindingId: string): HTMLVideoElement | HTMLCanvasElement | null;
437
+ }
438
+ /** Stable error codes currently emitted by the public package APIs. */
439
+ type FrameByFrameErrorCode = "INVALID_TIMELINE" | "INVALID_SEGMENT" | "OVERLAPPING_SEGMENTS" | "INVALID_FRAME_RATE" | "INVALID_EASING_RESULT" | "INVALID_CONTROLLER" | "INVALID_BREAKPOINT_CONFIG" | "DUPLICATE_BINDING_ID" | "ENVIRONMENT_UNAVAILABLE" | "SOURCE_NOT_FOUND" | "INVALID_LIFECYCLE_OPERATION" | "CONTROLLER_DESTROYED" | "INVALID_MEDIA_CONFIG" | "TARGET_NOT_FOUND" | "INVALID_TARGET_TYPE" | "TARGET_CONFLICT" | "MEDIA_SOURCE_UNSUPPORTED" | "MEDIA_LOAD_FAILED" | "FULL_PRELOAD_FAILED" | "MEDIA_DECODE_FAILED" | "MEDIA_SEEK_FAILED" | "CANVAS_CONTEXT_UNAVAILABLE" | "CANVAS_DRAW_FAILED" | "CANVAS_SECURITY_ERROR";
440
+ /** Structured context attached to a `FrameByFrameError`. */
441
+ type FrameByFrameErrorDetails = Readonly<Record<string, unknown>>;
442
+ /** Optional metadata accepted by `FrameByFrameError`. */
443
+ interface FrameByFrameErrorOptions {
444
+ /** Original failure that caused this package error. */
445
+ readonly cause?: unknown;
446
+ /** Package-owned read-only copy of structured diagnostic values. */
447
+ readonly details?: FrameByFrameErrorDetails;
448
+ }
449
+ //#endregion
450
+ export { Timeline as $, FrameByFrameBreakpointOverride as A, FrameByFrameOptions as B, FrameByFrameBindingBaseConfig as C, FrameByFrameBindingState as D, FrameByFrameBindingOverride as E, FrameByFrameErrorOptions as F, FrameByFrameUpdateReason as G, FrameByFrameState as H, FrameByFrameEventMap as I, ReducedMotionBehavior as J, FrameConfig as K, FrameByFrameFrameEvent as L, FrameByFrameErrorCode as M, FrameByFrameErrorDetails as N, FrameByFrameBreakpointChangeEvent as O, FrameByFrameErrorInfo as P, ScrollUnit as Q, FrameByFrameLoadProgressEvent as R, FrameByFrameAxisState as S, FrameByFrameBindingEvent as T, FrameByFrameStatus as U, FrameByFrameSeekRequestEvent as V, FrameByFrameUpdateEvent as W, ScrollSource as X, RendererType as Y, ScrollSourceReference as Z, EasingName as _, CanvasFrameByFrameAxisConfig as a, VideoLoadProgress as at, FrameByFrameAxisConfig as b, CanvasFrameByFrameBindingOverride as c, VideoLoadingTrigger as ct, CanvasFrameByFrameController as d, VideoSeekConfig as dt, TimelineOptions as et, CanvasFrameByFrameOptions as f, VideoSourceConfig as ft, EasingFunction as g, Easing as h, CanvasFrameByFrameAxesConfig as i, VideoClipConfig as it, FrameByFrameController as j, FrameByFrameBreakpointConfig as k, CanvasFrameByFrameBreakpointConfig as l, VideoPreload as lt, CanvasRendererOverride as m, CanvasBindingConfig as n, TimelineResolution as nt, CanvasFrameByFrameAxisOverride as o, VideoLoadState as ot, CanvasRendererConfig as p, MediaCrossOrigin as q, CanvasFit as r, TimelineSegment as rt, CanvasFrameByFrameBindingConfig as s, VideoLoadingConfig as st, AxisName as t, TimelinePhase as tt, CanvasFrameByFrameBreakpointOverride as u, VideoRendererConfig as ut, ElementReference as v, FrameByFrameBindingConfig as w, FrameByFrameAxisOverride as x, FrameByFrameAxesConfig as y, FrameByFrameLoadedMetadataEvent as z };
451
+ //# sourceMappingURL=types-BYfMRnsj.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-BYfMRnsj.d.ts","names":[],"sources":["../src/types.ts"],"mappings":";;KACY;;KAGA;;KAGA,kBAAkB;;KAGlB,SAAS,aAAa;;UAGjB;;WAEN,kBAAkB,eAAe;;WAEjC,iBAAiB,eAAe;;WAEhC,aAAa;;WAEb;;WAEA,SAAS;;;KAIR;;WAGG;WACA;;;WAIA;;WAEA;;;UAIE;;WAEN,mBAAmB;;WAEnB,SAAS;;WAET,QAAQ;;;KAIP;;UAGK;;WAEN,OAAO;;WAEP;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;;UAIM;;WAEN,MAAM;;EAEf,QAAQ,mBAAmB;;;KAIjB;;KAGA,eAAe,WAAW;;KAG1B,wBAAwB,+BAA+B;;KAGvD,iBAAiB,UAAU,UAAU,eAAe,oBAAoB;;KAGxE;;KAGA;;KAGA;;KAGA;;WAGG;WACA;WACA;;WAEA,cAAc;;WAEd,QAAQ;;WAGR;WACA;;WAEA;WACA,cAAc;WACd,QAAQ;;WAGR;WACA;WACA;WACA,cAAc;WACd,QAAQ;;;KAIX;;UAGK;;WAEN;;WAEA;;;UAIM;;WAEN;;WAEA,kBAAkB;;WAElB;;WAEA,cAAc;;WAEd,UAAU;;;UAIJ;WACN;WACA;WACA;WACA;;;UAIM;;WAEN;;;UAIM,sCAAsC;;WAE5C;;WAEA,gBAAgB;;WAEhB,UAAU;;WAEV,QAAQ;;WAER,OAAO;;;KAIN,4BAA4B;;WAIvB;;WAEA,QAAQ,iBAAiB;WACzB;WACA;;;WAIA;WACA;;WAEA,SAAS;WACT;;;KAKL;;UAGK;;WAEN,MAAM;;WAEN;;WAEA;;WAEA,gBAAgB,iBAAiB;;;UAI3B;WACN,MAAM;WACN;WACA;;;KAIC,sBAAsB;WAGjB;;WAEA,QAAQ,iBAAiB;WACzB;WACA,SAAS;;WAGT;WACA;;WAEA,SAAS;WACT,SAAS;;;KAKd,kCAAkC,4BAA4B;;UAGzD;;WAEN;;WAEA,mBAAmB;;;UAIb;WACN,YAAY;WACZ,YAAY;;;UAIN;WACN;WACA,mBAAmB;;;UAIb;WACN,YAAY;WACZ,YAAY;;;UAIN;;WAEN;;WAEA,oBAAoB;;WAEpB,iBAAiB;;WAEjB,SAAS;;WAET,QAAQ;;WAER,UAAU;;WAEV,QAAQ;;WAER,OAAO;;;UAID,0CAA0C;;WAEhD,SAAS;;;UAIH;;WAEN;;WAEA,oBAAoB;;;UAId;WACN;aACE,YAAY;aACZ,YAAY;;;;UAKR;;WAEN;;WAEA;;WAEA,UAAU;;;UAIJ;WACN;WACA,oBAAoB;;;UAId;WACN;aACE,YAAY;aACZ,YAAY;;;;UAKR;WACN;WACA;WACA,UAAU;;;KAIT;;UAGK;;WAEN,SAAS;;WAET,MAAM;;WAEN,uBAAuB;;WAEvB,gBAAgB;;;UAIV;WACN,SAAS;WACT,MAAM;WACN,uBAAuB;WACvB,gBAAgB;;;KAIf;;UAGK,8BAA8B;WACpC;WACA,MAAM;WACN;WACA,SAAS;;;UAIH;WACN;WACA;WACA;WACA;;;UAIM;WACN;WACA,MAAM;WACN,YAAY;WACZ,UAAU;WACV,WAAW;;WAEX,cAAc,SAAS,eAAe;WACtC;WACA;WACA;WACA;WACA;WACA;WACA,OAAO;;;KAIN;;UAGK;WACN;WACA;WACA;;;UAIM;WACN,QAAQ;WACR;WACA,QAAQ;WACR;WACA;WACA,MAAM,SAAS,QAAQ,OAAO,UAAU;WACxC,UAAU,SAAS,eAAe;WAClC,WAAW;;;KAIV;;UAYK;WACN,QAAQ;WACR,OAAO;;;UAID;WACN;WACA;WACA,OAAO;;;UAID;WACN;WACA;WACA,OAAO;;;UAID,wCAAwC;WAC9C;;;UAIM,sCAAsC;WAC5C;WACA;WACA;;;UAIM,qCAAqC;WAC3C;WACA;;;UAIM,+BAA+B;WACrC;WACA;WACA;WACA;;;UAIM;WACN,OAAO;WACP,QAAQ;WACR,kBAAkB;WAClB,WAAW;WACX,cAAc;WACd,gBAAgB;WAChB,WAAW;WACX,aAAa;WACb,OAAO;WACP,OAAO;WACP,SAAS;;;UAIH;EACf,SAAS;EACT;EACA;EACA;EACA,KAAK,qBAAqB;;EAE1B,aAAa,QAAQ;EACrB,OAAO;EACP,UAAU,oBAAoB;EAC9B,YAAY;EACZ,GAAG,wBAAwB,sBACzB,OAAO,WACP,WAAW,SAAS,qBAAqB;EAE3C;;;UAIe,qCAAqC,KAAK;EACzD,UAAU,oBAAoB,mBAAmB;;;KAIvC;;KA2BA,2BAA2B,SAAS;;UAG/B;;WAEN;;WAEA,UAAU"}
@@ -0,0 +1,2 @@
1
+ import { $ as Timeline, A as FrameByFrameBreakpointOverride, B as FrameByFrameOptions, C as FrameByFrameBindingBaseConfig, D as FrameByFrameBindingState, E as FrameByFrameBindingOverride, F as FrameByFrameErrorOptions, G as FrameByFrameUpdateReason, H as FrameByFrameState, I as FrameByFrameEventMap, J as ReducedMotionBehavior, K as FrameConfig, L as FrameByFrameFrameEvent, M as FrameByFrameErrorCode, N as FrameByFrameErrorDetails, O as FrameByFrameBreakpointChangeEvent, P as FrameByFrameErrorInfo, Q as ScrollUnit, R as FrameByFrameLoadProgressEvent, S as FrameByFrameAxisState, T as FrameByFrameBindingEvent, U as FrameByFrameStatus, V as FrameByFrameSeekRequestEvent, W as FrameByFrameUpdateEvent, X as ScrollSource, Y as RendererType, Z as ScrollSourceReference, _ as EasingName, a as CanvasFrameByFrameAxisConfig, at as VideoLoadProgress, b as FrameByFrameAxisConfig, c as CanvasFrameByFrameBindingOverride, ct as VideoLoadingTrigger, d as CanvasFrameByFrameController, dt as VideoSeekConfig, et as TimelineOptions, f as CanvasFrameByFrameOptions, ft as VideoSourceConfig, g as EasingFunction, h as Easing, i as CanvasFrameByFrameAxesConfig, it as VideoClipConfig, j as FrameByFrameController, k as FrameByFrameBreakpointConfig, l as CanvasFrameByFrameBreakpointConfig, lt as VideoPreload, m as CanvasRendererOverride, n as CanvasBindingConfig, nt as TimelineResolution, o as CanvasFrameByFrameAxisOverride, ot as VideoLoadState, p as CanvasRendererConfig, q as MediaCrossOrigin, r as CanvasFit, rt as TimelineSegment, s as CanvasFrameByFrameBindingConfig, st as VideoLoadingConfig, t as AxisName, tt as TimelinePhase, u as CanvasFrameByFrameBreakpointOverride, ut as VideoRendererConfig, v as ElementReference, w as FrameByFrameBindingConfig, x as FrameByFrameAxisOverride, y as FrameByFrameAxesConfig, z as FrameByFrameLoadedMetadataEvent } from "./types-BYfMRnsj.js";
2
+ export { AxisName, CanvasBindingConfig, CanvasFit, CanvasFrameByFrameAxesConfig, CanvasFrameByFrameAxisConfig, CanvasFrameByFrameAxisOverride, CanvasFrameByFrameBindingConfig, CanvasFrameByFrameBindingOverride, CanvasFrameByFrameBreakpointConfig, CanvasFrameByFrameBreakpointOverride, CanvasFrameByFrameController, CanvasFrameByFrameOptions, CanvasRendererConfig, CanvasRendererOverride, Easing, EasingFunction, EasingName, ElementReference, FrameByFrameAxesConfig, FrameByFrameAxisConfig, FrameByFrameAxisOverride, FrameByFrameAxisState, FrameByFrameBindingBaseConfig, FrameByFrameBindingConfig, FrameByFrameBindingEvent, FrameByFrameBindingOverride, FrameByFrameBindingState, FrameByFrameBreakpointChangeEvent, FrameByFrameBreakpointConfig, FrameByFrameBreakpointOverride, FrameByFrameController, FrameByFrameErrorCode, FrameByFrameErrorDetails, FrameByFrameErrorInfo, FrameByFrameErrorOptions, FrameByFrameEventMap, FrameByFrameFrameEvent, FrameByFrameLoadProgressEvent, FrameByFrameLoadedMetadataEvent, FrameByFrameOptions, FrameByFrameSeekRequestEvent, FrameByFrameState, FrameByFrameStatus, FrameByFrameUpdateEvent, FrameByFrameUpdateReason, FrameConfig, MediaCrossOrigin, ReducedMotionBehavior, RendererType, ScrollSource, ScrollSourceReference, ScrollUnit, Timeline, TimelineOptions, TimelinePhase, TimelineResolution, TimelineSegment, VideoClipConfig, VideoLoadProgress, VideoLoadState, VideoLoadingConfig, VideoLoadingTrigger, VideoPreload, VideoRendererConfig, VideoSeekConfig, VideoSourceConfig };
package/dist/types.js ADDED
File without changes
@@ -0,0 +1,4 @@
1
+ import { $ as Timeline, A as FrameByFrameBreakpointOverride, B as FrameByFrameOptions, D as FrameByFrameBindingState, E as FrameByFrameBindingOverride, F as FrameByFrameErrorOptions, G as FrameByFrameUpdateReason, H as FrameByFrameState, I as FrameByFrameEventMap, J as ReducedMotionBehavior, K as FrameConfig, L as FrameByFrameFrameEvent, M as FrameByFrameErrorCode, N as FrameByFrameErrorDetails, O as FrameByFrameBreakpointChangeEvent, P as FrameByFrameErrorInfo, Q as ScrollUnit, R as FrameByFrameLoadProgressEvent, S as FrameByFrameAxisState, T as FrameByFrameBindingEvent, U as FrameByFrameStatus, V as FrameByFrameSeekRequestEvent, W as FrameByFrameUpdateEvent, X as ScrollSource, Y as RendererType, Z as ScrollSourceReference, _ as EasingName, at as VideoLoadProgress, b as FrameByFrameAxisConfig, ct as VideoLoadingTrigger, dt as VideoSeekConfig, et as TimelineOptions, ft as VideoSourceConfig, g as EasingFunction, h as Easing, it as VideoClipConfig, j as FrameByFrameController, k as FrameByFrameBreakpointConfig, lt as VideoPreload, nt as TimelineResolution, ot as VideoLoadState, q as MediaCrossOrigin, rt as TimelineSegment, st as VideoLoadingConfig, t as AxisName, tt as TimelinePhase, ut as VideoRendererConfig, v as ElementReference, w as FrameByFrameBindingConfig, x as FrameByFrameAxisOverride, y as FrameByFrameAxesConfig, z as FrameByFrameLoadedMetadataEvent } from "./types-BYfMRnsj.js";
2
+ import { n as FrameByFrameError, t as createTimeline } from "./timeline-DDuRBPRJ.js";
3
+ import { t as createFrameByFrame } from "./index-DhdyeigP.js";
4
+ export { type AxisName, type Easing, type EasingFunction, type EasingName, type ElementReference, type FrameByFrameAxesConfig, type FrameByFrameAxisConfig, type FrameByFrameAxisOverride, type FrameByFrameAxisState, type FrameByFrameBindingConfig, type FrameByFrameBindingEvent, type FrameByFrameBindingOverride, type FrameByFrameBindingState, type FrameByFrameBreakpointChangeEvent, type FrameByFrameBreakpointConfig, type FrameByFrameBreakpointOverride, type FrameByFrameController, FrameByFrameError, type FrameByFrameErrorCode, type FrameByFrameErrorDetails, type FrameByFrameErrorInfo, type FrameByFrameErrorOptions, type FrameByFrameEventMap, type FrameByFrameFrameEvent, type FrameByFrameLoadProgressEvent, type FrameByFrameLoadedMetadataEvent, type FrameByFrameOptions, type FrameByFrameSeekRequestEvent, type FrameByFrameState, type FrameByFrameStatus, type FrameByFrameUpdateEvent, type FrameByFrameUpdateReason, type FrameConfig, type MediaCrossOrigin, type ReducedMotionBehavior, type RendererType, type ScrollSource, type ScrollSourceReference, type ScrollUnit, type Timeline, type TimelineOptions, type TimelinePhase, type TimelineResolution, type TimelineSegment, type VideoClipConfig, type VideoLoadProgress, type VideoLoadState, type VideoLoadingConfig, type VideoLoadingTrigger, type VideoPreload, type VideoRendererConfig, type VideoSeekConfig, type VideoSourceConfig, createFrameByFrame, createTimeline };
package/dist/video.js ADDED
@@ -0,0 +1,4 @@
1
+ import { m as FrameByFrameError, p as createTimeline, t as createFrameByFrame } from "./public-controller-jGcw6iqQ.js";
2
+ import "./index.js";
3
+
4
+ export { FrameByFrameError, createFrameByFrame, createTimeline };
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@frame-by-frame/core",
3
+ "version": "1.0.0-rc.1",
4
+ "description": "Framework-agnostic TypeScript library for mapping scroll position to video time.",
5
+ "keywords": [
6
+ "animation",
7
+ "canvas",
8
+ "scroll",
9
+ "scroll-animation",
10
+ "typescript",
11
+ "video",
12
+ "video-scrubbing"
13
+ ],
14
+ "homepage": "https://github.com/mariozenmedina/frame-by-frame#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/mariozenmedina/frame-by-frame/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/mariozenmedina/frame-by-frame.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Mário Veronesi Medina",
24
+ "type": "module",
25
+ "sideEffects": false,
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "main": "./dist/index.js",
30
+ "module": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js",
36
+ "default": "./dist/index.js"
37
+ },
38
+ "./video": {
39
+ "types": "./dist/video.d.ts",
40
+ "import": "./dist/video.js",
41
+ "default": "./dist/video.js"
42
+ },
43
+ "./canvas": {
44
+ "types": "./dist/canvas.d.ts",
45
+ "import": "./dist/canvas.js",
46
+ "default": "./dist/canvas.js"
47
+ },
48
+ "./types": {
49
+ "types": "./dist/types.d.ts",
50
+ "import": "./dist/types.js",
51
+ "default": "./dist/types.js"
52
+ },
53
+ "./package.json": "./package.json"
54
+ },
55
+ "engines": {
56
+ "node": "^22.18.0 || ^24.11.0"
57
+ },
58
+ "packageManager": "pnpm@11.5.3",
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "provenance": true
62
+ },
63
+ "browserslist": [
64
+ "baseline widely available"
65
+ ],
66
+ "scripts": {
67
+ "build": "tsdown",
68
+ "build:watch": "tsdown --watch",
69
+ "check": "pnpm format:check && pnpm check:docs && pnpm check:release && pnpm lint && pnpm typecheck && pnpm test:coverage && pnpm build && pnpm check:bundle && pnpm test:package",
70
+ "check:bundle": "node scripts/check-bundle-budget.mjs",
71
+ "check:docs": "node scripts/check-doc-links.mjs",
72
+ "check:release": "node scripts/check-release.mjs",
73
+ "format": "prettier --write .",
74
+ "format:check": "prettier --check .",
75
+ "generate:browser-media": "node scripts/generate-browser-media.mjs",
76
+ "lint": "eslint . --max-warnings 0",
77
+ "test": "vitest",
78
+ "test:browser": "pnpm build && playwright test --config playwright.config.ts",
79
+ "test:coverage": "vitest run --coverage",
80
+ "test:package": "node tests/package-imports.mjs && node tests/packed-consumer.mjs",
81
+ "test:run": "vitest run",
82
+ "typecheck": "tsc --noEmit"
83
+ },
84
+ "devDependencies": {
85
+ "@arethetypeswrong/core": "0.18.5",
86
+ "@eslint/js": "10.0.1",
87
+ "@playwright/test": "1.61.1",
88
+ "@types/node": "24.13.3",
89
+ "@vitest/coverage-v8": "4.1.10",
90
+ "eslint": "10.7.0",
91
+ "prettier": "3.9.5",
92
+ "publint": "0.3.21",
93
+ "tsdown": "0.22.7",
94
+ "typescript": "6.0.3",
95
+ "typescript-eslint": "8.64.0",
96
+ "vitest": "4.1.10"
97
+ }
98
+ }