@cntrl-site/sdk 1.25.11-components.0 → 1.25.12

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.
@@ -3,7 +3,6 @@ import { Project } from '../types/project/Project';
3
3
  import { Layout } from '../types/project/Layout';
4
4
  import { Article } from '../types/article/Article';
5
5
  import { KeyframeAny } from '../types/keyframe/Keyframe';
6
- import { CustomComponentMeta } from '../types/customComponent/CustomComponentMeta';
7
6
  export declare class Client {
8
7
  private fetchImpl;
9
8
  private url;
@@ -12,8 +11,6 @@ export declare class Client {
12
11
  getPageData(pageSlug: string, buildMode?: 'default' | 'self-hosted'): Promise<CntrlPageData>;
13
12
  getProjectPagesPaths(): Promise<string[]>;
14
13
  getLayouts(): Promise<Layout[]>;
15
- fetchCustomComponents(buildMode?: 'default' | 'self-hosted'): Promise<CustomComponentMeta[]>;
16
- fetchCustomComponentBundle(componentId: string, buildMode?: 'default' | 'self-hosted'): Promise<string>;
17
14
  private fetchProject;
18
15
  private fetchArticle;
19
16
  private findArticleIdByPageSlug;
@@ -21,7 +18,6 @@ export declare class Client {
21
18
  interface FetchImplResponse {
22
19
  ok: boolean;
23
20
  json(): Promise<any>;
24
- text(): Promise<string>;
25
21
  statusText: string;
26
22
  }
27
23
  type FetchImpl = (url: string, init?: RequestInit) => Promise<FetchImplResponse>;
@@ -81,36 +81,6 @@ class Client {
81
81
  }
82
82
  });
83
83
  }
84
- fetchCustomComponents() {
85
- return __awaiter(this, arguments, void 0, function* (buildMode = 'default') {
86
- const { username: projectId, password: apiKey, origin } = this.url;
87
- const url = new url_1.URL(`/projects/${projectId}/custom-components?buildMode=${buildMode}`, origin);
88
- const response = yield this.fetchImpl(url.href, {
89
- headers: {
90
- Authorization: `Bearer ${apiKey}`
91
- }
92
- });
93
- if (!response.ok) {
94
- throw new Error(`Failed to fetch custom components for project #${projectId}: ${response.statusText}`);
95
- }
96
- return response.json();
97
- });
98
- }
99
- fetchCustomComponentBundle(componentId_1) {
100
- return __awaiter(this, arguments, void 0, function* (componentId, buildMode = 'default') {
101
- const { username: projectId, password: apiKey, origin } = this.url;
102
- const url = new url_1.URL(`/projects/${projectId}/custom-components/${componentId}/bundle.js?buildMode=${buildMode}`, origin);
103
- const response = yield this.fetchImpl(url.href, {
104
- headers: {
105
- Authorization: `Bearer ${apiKey}`
106
- }
107
- });
108
- if (!response.ok) {
109
- throw new Error(`Failed to fetch bundle for custom component #${componentId}: ${response.statusText}`);
110
- }
111
- return response.text();
112
- });
113
- }
114
84
  fetchProject() {
115
85
  return __awaiter(this, arguments, void 0, function* (buildMode = 'default') {
116
86
  const { username: projectId, password: apiKey, origin } = this.url;
@@ -1,6 +1,13 @@
1
1
  interface ScrollVideoOptions {
2
2
  src: string;
3
3
  videoContainer: HTMLElement | string;
4
+ frameData?: {
5
+ batchId: string;
6
+ frameCount: number;
7
+ frameRate: number;
8
+ frameFormat: string;
9
+ };
10
+ frameBaseUrl?: string;
4
11
  }
5
12
  export declare class ScrollPlaybackVideoManager {
6
13
  private container?;
@@ -18,7 +25,13 @@ export declare class ScrollPlaybackVideoManager {
18
25
  private transitionSpeed;
19
26
  private useWebCodecs;
20
27
  private resizeObserver;
28
+ private serverFrameData?;
29
+ private serverFrameBaseUrl?;
30
+ private serverFrameImages;
31
+ private currentServerFrameIdx;
21
32
  constructor(options: ScrollVideoOptions);
33
+ private loadServerFrames;
34
+ private paintServerFrame;
22
35
  private setCoverStyle;
23
36
  private resize;
24
37
  private decodeVideo;
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -19,16 +28,21 @@ class ScrollPlaybackVideoManager {
19
28
  this.frameThreshold = 0.1;
20
29
  this.transitionSpeed = 10;
21
30
  this.useWebCodecs = true;
31
+ this.serverFrameImages = [];
32
+ this.currentServerFrameIdx = 0;
22
33
  this.resize = () => {
23
34
  if (this.debug)
24
35
  console.info('ScrollVideo resizing...');
25
- if (this.canvas) {
36
+ if (this.serverFrameData && this.serverFrameImages.length > 0) {
37
+ this.paintServerFrame(this.currentServerFrameIdx);
38
+ }
39
+ else if (this.canvas) {
26
40
  this.setCoverStyle(this.canvas);
41
+ this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
27
42
  }
28
43
  else if (this.video) {
29
44
  this.setCoverStyle(this.video);
30
45
  }
31
- this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
32
46
  };
33
47
  this.decodeVideo = () => {
34
48
  if (!this.video)
@@ -63,7 +77,7 @@ class ScrollPlaybackVideoManager {
63
77
  this.resizeObserver = new ResizeObserver(() => {
64
78
  this.resize();
65
79
  });
66
- const { src, videoContainer } = options;
80
+ const { src, videoContainer, frameData, frameBaseUrl } = options;
67
81
  if (typeof document !== 'object') {
68
82
  console.error('ScrollVideo must be initiated in a DOM context');
69
83
  return;
@@ -78,6 +92,12 @@ class ScrollPlaybackVideoManager {
78
92
  }
79
93
  this.container = typeof videoContainer === 'string' ? document.getElementById(videoContainer) : videoContainer;
80
94
  this.resizeObserver.observe(this.container);
95
+ if (frameData && frameBaseUrl) {
96
+ this.serverFrameData = frameData;
97
+ this.serverFrameBaseUrl = frameBaseUrl;
98
+ this.loadServerFrames();
99
+ return;
100
+ }
81
101
  this.video = document.createElement('video');
82
102
  this.video.src = src;
83
103
  this.video.preload = 'auto';
@@ -87,7 +107,8 @@ class ScrollPlaybackVideoManager {
87
107
  this.video.pause();
88
108
  this.video.load();
89
109
  this.container.appendChild(this.video);
90
- const browserEngine = new ua_parser_js_1.default().getEngine();
110
+ const ua = new ua_parser_js_1.default();
111
+ const browserEngine = ua.getEngine();
91
112
  this.isSafari = browserEngine.name === 'WebKit';
92
113
  if (this.debug && this.isSafari)
93
114
  console.info('Safari browser detected');
@@ -95,6 +116,52 @@ class ScrollPlaybackVideoManager {
95
116
  this.video.addEventListener('progress', this.resize);
96
117
  this.decodeVideo();
97
118
  }
119
+ loadServerFrames() {
120
+ return __awaiter(this, void 0, void 0, function* () {
121
+ if (!this.serverFrameData || !this.serverFrameBaseUrl || !this.container)
122
+ return;
123
+ const { batchId, frameCount, frameRate } = this.serverFrameData;
124
+ const loadBatch = (start, end) => __awaiter(this, void 0, void 0, function* () {
125
+ const promises = [];
126
+ for (let i = start; i <= end; i++) {
127
+ const idx = String(i).padStart(4, '0');
128
+ const url = `${this.serverFrameBaseUrl}/${batchId}_${idx}.${this.serverFrameData.frameFormat}`;
129
+ const img = new Image();
130
+ this.serverFrameImages[i - 1] = img;
131
+ promises.push(new Promise((resolve) => {
132
+ img.onload = () => resolve();
133
+ img.onerror = () => resolve();
134
+ img.src = url;
135
+ }));
136
+ }
137
+ yield Promise.all(promises);
138
+ });
139
+ const initialBatch = Math.min(10, frameCount);
140
+ yield loadBatch(1, initialBatch);
141
+ this.frameRate = frameRate;
142
+ this.canvas = document.createElement('canvas');
143
+ this.context = this.canvas.getContext('2d');
144
+ this.container.appendChild(this.canvas);
145
+ this.paintServerFrame(0);
146
+ if (initialBatch < frameCount) {
147
+ loadBatch(initialBatch + 1, frameCount);
148
+ }
149
+ });
150
+ }
151
+ paintServerFrame(frameIdx) {
152
+ if (!this.canvas || !this.context || !this.container)
153
+ return;
154
+ const clampedIdx = Math.max(0, Math.min(frameIdx, this.serverFrameImages.length - 1));
155
+ const img = this.serverFrameImages[clampedIdx];
156
+ if (!img || !img.naturalWidth)
157
+ return;
158
+ this.currentServerFrameIdx = clampedIdx;
159
+ this.canvas.width = img.naturalWidth;
160
+ this.canvas.height = img.naturalHeight;
161
+ const { width, height } = this.container.getBoundingClientRect();
162
+ this.resetCanvasDimensions(width, height, img.naturalWidth, img.naturalHeight);
163
+ this.context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight);
164
+ }
98
165
  setCoverStyle(el) {
99
166
  if (el && this.container) {
100
167
  el.style.position = 'absolute';
@@ -195,6 +262,11 @@ class ScrollPlaybackVideoManager {
195
262
  }
196
263
  }
197
264
  setTargetTimePercent(setPercentage, jump = true) {
265
+ if (this.serverFrameData && this.serverFrameImages.length > 0) {
266
+ const frameIdx = Math.round(Math.max(0, Math.min(setPercentage, 1)) * (this.serverFrameImages.length - 1));
267
+ this.paintServerFrame(frameIdx);
268
+ return;
269
+ }
198
270
  if (!this.video)
199
271
  return;
200
272
  this.targetTime = Math.max(Math.min(setPercentage, 1), 0)
package/lib/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { AreaAnchor, AnchorSide, DimensionMode, PositionType, DimensionsType } f
10
10
  export { KeyframeType } from './types/keyframe/Keyframe';
11
11
  export type { Article } from './types/article/Article';
12
12
  export type { Section, SectionHeight } from './types/article/Section';
13
- export type { Item, ImageItem, ItemAny, CustomItem, ItemCommonParamsMap, ItemLayoutParamsMap, RectangleItem, StickyParams, VideoItem, RichTextItem, Link, VimeoEmbedItem, YoutubeEmbedItem, GroupItem, CodeEmbedItem, CompoundItem, ComponentItem, FillLayer } from './types/article/Item';
13
+ export type { Item, ImageItem, ItemAny, CustomItem, ItemCommonParamsMap, ItemLayoutParamsMap, RectangleItem, StickyParams, VideoItem, RichTextItem, Link, VimeoEmbedItem, YoutubeEmbedItem, GroupItem, CodeEmbedItem, CompoundItem, ComponentItem, FillLayer, ScrollPlaybackFrameData } from './types/article/Item';
14
14
  export type { RichTextBlock, RichTextEntity, RichTextStyle } from './types/article/RichText';
15
15
  export type { ItemArea } from './types/article/ItemArea';
16
16
  export type { ItemState, ItemStateParams, StateParams, ItemStatesMap } from './types/article/ItemState';
@@ -21,4 +21,3 @@ export type { Meta } from './types/project/Meta';
21
21
  export type { KeyframeValueMap, KeyframeAny } from './types/keyframe/Keyframe';
22
22
  export type { CompoundSettings } from './types/article/CompoundSettings';
23
23
  export type { Dimensions, Left, Position, RectCoordinates, RectObject, ScaleOrigin, Sides, Top } from './types/article/Rect';
24
- export type { CustomComponentMeta } from './types/customComponent/CustomComponentMeta';
@@ -52,10 +52,19 @@ const ImageItemSchema = ItemBase_schema_1.ItemBaseSchema.extend({
52
52
  })),
53
53
  state: zod_1.z.record(ItemState_schema_1.MediaStateParamsSchema)
54
54
  });
55
+ const ScrollPlaybackFrameDataSchema = zod_1.z.object({
56
+ status: zod_1.z.enum(['processing', 'ready', 'error']),
57
+ batchId: zod_1.z.string().optional(),
58
+ frameCount: zod_1.z.number().optional(),
59
+ frameRate: zod_1.z.number().optional(),
60
+ framesUrl: zod_1.z.string().optional(),
61
+ frameFormat: zod_1.z.string().optional()
62
+ });
55
63
  const VideoItemSchema = ItemBase_schema_1.ItemBaseSchema.extend({
56
64
  type: zod_1.z.literal(ArticleItemType_1.ArticleItemType.Video),
57
65
  commonParams: zod_1.z.object({
58
66
  coverUrl: zod_1.z.string().nullable(),
67
+ scrollPlaybackFrameData: ScrollPlaybackFrameDataSchema.nullable().optional(),
59
68
  pointerEvents
60
69
  }).merge(FXParams),
61
70
  sticky: zod_1.z.record(zod_1.z.object({
@@ -191,8 +200,7 @@ const ComponentItemSchema = ItemBase_schema_1.ItemBaseSchema.extend({
191
200
  type: zod_1.z.literal(ArticleItemType_1.ArticleItemType.Component),
192
201
  commonParams: zod_1.z.object({
193
202
  componentId: zod_1.z.string(),
194
- content: zod_1.z.any().optional(),
195
- parameters: zod_1.z.record(zod_1.z.any()).optional()
203
+ content: zod_1.z.any().optional()
196
204
  }),
197
205
  sticky: zod_1.z.record(zod_1.z.object({
198
206
  from: zod_1.z.number(),
@@ -55,6 +55,7 @@ interface MediaCommonParams extends CommonParamsBase {
55
55
  }
56
56
  interface VideoCommonParams extends MediaCommonParams {
57
57
  coverUrl: string | null;
58
+ scrollPlaybackFrameData?: ScrollPlaybackFrameData | null;
58
59
  }
59
60
  interface ImageCommonParams extends MediaCommonParams {
60
61
  }
@@ -89,7 +90,6 @@ interface YoutubeEmbedCommonParams extends CommonParamsBase {
89
90
  interface ComponentCommonParams extends CommonParamsBase {
90
91
  componentId: string;
91
92
  content?: any;
92
- parameters?: Record<string, any>;
93
93
  }
94
94
  interface MediaLayoutParams {
95
95
  opacity: number;
@@ -227,6 +227,14 @@ export interface ScrollPlaybackParams {
227
227
  from: number;
228
228
  to: number;
229
229
  }
230
+ export interface ScrollPlaybackFrameData {
231
+ status: 'processing' | 'ready' | 'error';
232
+ batchId?: string;
233
+ frameCount?: number;
234
+ frameRate?: number;
235
+ framesUrl?: string;
236
+ frameFormat?: string;
237
+ }
230
238
  export interface StickyParams {
231
239
  from: number;
232
240
  to?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk",
3
- "version": "1.25.11-components.0",
3
+ "version": "1.25.12",
4
4
  "description": "Generic SDK for use in public websites.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -1,5 +0,0 @@
1
- export type CustomComponentMeta = {
2
- id: string;
3
- name: string;
4
- schema: Record<string, unknown>;
5
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });