@cntrl-site/sdk 1.25.12 → 1.26.0
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/lib/Client/Client.d.ts +4 -0
- package/lib/Client/Client.js +30 -0
- package/lib/ScrollPlaybackVideoManager/ScrollPlaybackVideoManager.d.ts +0 -13
- package/lib/ScrollPlaybackVideoManager/ScrollPlaybackVideoManager.js +4 -76
- package/lib/index.d.ts +2 -1
- package/lib/schemas/article/Item.schema.js +2 -10
- package/lib/types/article/Item.d.ts +1 -9
- package/lib/types/customComponent/CustomComponentMeta.d.ts +5 -0
- package/lib/types/customComponent/CustomComponentMeta.js +2 -0
- package/package.json +1 -1
package/lib/Client/Client.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ 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';
|
|
6
7
|
export declare class Client {
|
|
7
8
|
private fetchImpl;
|
|
8
9
|
private url;
|
|
@@ -11,6 +12,8 @@ export declare class Client {
|
|
|
11
12
|
getPageData(pageSlug: string, buildMode?: 'default' | 'self-hosted'): Promise<CntrlPageData>;
|
|
12
13
|
getProjectPagesPaths(): Promise<string[]>;
|
|
13
14
|
getLayouts(): Promise<Layout[]>;
|
|
15
|
+
fetchCustomComponents(buildMode?: 'default' | 'self-hosted'): Promise<CustomComponentMeta[]>;
|
|
16
|
+
fetchCustomComponentBundle(componentId: string, buildMode?: 'default' | 'self-hosted'): Promise<string>;
|
|
14
17
|
private fetchProject;
|
|
15
18
|
private fetchArticle;
|
|
16
19
|
private findArticleIdByPageSlug;
|
|
@@ -18,6 +21,7 @@ export declare class Client {
|
|
|
18
21
|
interface FetchImplResponse {
|
|
19
22
|
ok: boolean;
|
|
20
23
|
json(): Promise<any>;
|
|
24
|
+
text(): Promise<string>;
|
|
21
25
|
statusText: string;
|
|
22
26
|
}
|
|
23
27
|
type FetchImpl = (url: string, init?: RequestInit) => Promise<FetchImplResponse>;
|
package/lib/Client/Client.js
CHANGED
|
@@ -81,6 +81,36 @@ 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
|
+
}
|
|
84
114
|
fetchProject() {
|
|
85
115
|
return __awaiter(this, arguments, void 0, function* (buildMode = 'default') {
|
|
86
116
|
const { username: projectId, password: apiKey, origin } = this.url;
|
|
@@ -1,13 +1,6 @@
|
|
|
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;
|
|
11
4
|
}
|
|
12
5
|
export declare class ScrollPlaybackVideoManager {
|
|
13
6
|
private container?;
|
|
@@ -25,13 +18,7 @@ export declare class ScrollPlaybackVideoManager {
|
|
|
25
18
|
private transitionSpeed;
|
|
26
19
|
private useWebCodecs;
|
|
27
20
|
private resizeObserver;
|
|
28
|
-
private serverFrameData?;
|
|
29
|
-
private serverFrameBaseUrl?;
|
|
30
|
-
private serverFrameImages;
|
|
31
|
-
private currentServerFrameIdx;
|
|
32
21
|
constructor(options: ScrollVideoOptions);
|
|
33
|
-
private loadServerFrames;
|
|
34
|
-
private paintServerFrame;
|
|
35
22
|
private setCoverStyle;
|
|
36
23
|
private resize;
|
|
37
24
|
private decodeVideo;
|
|
@@ -1,13 +1,4 @@
|
|
|
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
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -28,21 +19,16 @@ class ScrollPlaybackVideoManager {
|
|
|
28
19
|
this.frameThreshold = 0.1;
|
|
29
20
|
this.transitionSpeed = 10;
|
|
30
21
|
this.useWebCodecs = true;
|
|
31
|
-
this.serverFrameImages = [];
|
|
32
|
-
this.currentServerFrameIdx = 0;
|
|
33
22
|
this.resize = () => {
|
|
34
23
|
if (this.debug)
|
|
35
24
|
console.info('ScrollVideo resizing...');
|
|
36
|
-
if (this.
|
|
37
|
-
this.paintServerFrame(this.currentServerFrameIdx);
|
|
38
|
-
}
|
|
39
|
-
else if (this.canvas) {
|
|
25
|
+
if (this.canvas) {
|
|
40
26
|
this.setCoverStyle(this.canvas);
|
|
41
|
-
this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
|
|
42
27
|
}
|
|
43
28
|
else if (this.video) {
|
|
44
29
|
this.setCoverStyle(this.video);
|
|
45
30
|
}
|
|
31
|
+
this.paintCanvasFrame(Math.floor(this.currentTime * this.frameRate));
|
|
46
32
|
};
|
|
47
33
|
this.decodeVideo = () => {
|
|
48
34
|
if (!this.video)
|
|
@@ -77,7 +63,7 @@ class ScrollPlaybackVideoManager {
|
|
|
77
63
|
this.resizeObserver = new ResizeObserver(() => {
|
|
78
64
|
this.resize();
|
|
79
65
|
});
|
|
80
|
-
const { src, videoContainer
|
|
66
|
+
const { src, videoContainer } = options;
|
|
81
67
|
if (typeof document !== 'object') {
|
|
82
68
|
console.error('ScrollVideo must be initiated in a DOM context');
|
|
83
69
|
return;
|
|
@@ -92,12 +78,6 @@ class ScrollPlaybackVideoManager {
|
|
|
92
78
|
}
|
|
93
79
|
this.container = typeof videoContainer === 'string' ? document.getElementById(videoContainer) : videoContainer;
|
|
94
80
|
this.resizeObserver.observe(this.container);
|
|
95
|
-
if (frameData && frameBaseUrl) {
|
|
96
|
-
this.serverFrameData = frameData;
|
|
97
|
-
this.serverFrameBaseUrl = frameBaseUrl;
|
|
98
|
-
this.loadServerFrames();
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
81
|
this.video = document.createElement('video');
|
|
102
82
|
this.video.src = src;
|
|
103
83
|
this.video.preload = 'auto';
|
|
@@ -107,8 +87,7 @@ class ScrollPlaybackVideoManager {
|
|
|
107
87
|
this.video.pause();
|
|
108
88
|
this.video.load();
|
|
109
89
|
this.container.appendChild(this.video);
|
|
110
|
-
const
|
|
111
|
-
const browserEngine = ua.getEngine();
|
|
90
|
+
const browserEngine = new ua_parser_js_1.default().getEngine();
|
|
112
91
|
this.isSafari = browserEngine.name === 'WebKit';
|
|
113
92
|
if (this.debug && this.isSafari)
|
|
114
93
|
console.info('Safari browser detected');
|
|
@@ -116,52 +95,6 @@ class ScrollPlaybackVideoManager {
|
|
|
116
95
|
this.video.addEventListener('progress', this.resize);
|
|
117
96
|
this.decodeVideo();
|
|
118
97
|
}
|
|
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
|
-
}
|
|
165
98
|
setCoverStyle(el) {
|
|
166
99
|
if (el && this.container) {
|
|
167
100
|
el.style.position = 'absolute';
|
|
@@ -262,11 +195,6 @@ class ScrollPlaybackVideoManager {
|
|
|
262
195
|
}
|
|
263
196
|
}
|
|
264
197
|
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
|
-
}
|
|
270
198
|
if (!this.video)
|
|
271
199
|
return;
|
|
272
200
|
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
|
|
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';
|
|
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,3 +21,4 @@ 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,19 +52,10 @@ 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
|
-
});
|
|
63
55
|
const VideoItemSchema = ItemBase_schema_1.ItemBaseSchema.extend({
|
|
64
56
|
type: zod_1.z.literal(ArticleItemType_1.ArticleItemType.Video),
|
|
65
57
|
commonParams: zod_1.z.object({
|
|
66
58
|
coverUrl: zod_1.z.string().nullable(),
|
|
67
|
-
scrollPlaybackFrameData: ScrollPlaybackFrameDataSchema.nullable().optional(),
|
|
68
59
|
pointerEvents
|
|
69
60
|
}).merge(FXParams),
|
|
70
61
|
sticky: zod_1.z.record(zod_1.z.object({
|
|
@@ -200,7 +191,8 @@ const ComponentItemSchema = ItemBase_schema_1.ItemBaseSchema.extend({
|
|
|
200
191
|
type: zod_1.z.literal(ArticleItemType_1.ArticleItemType.Component),
|
|
201
192
|
commonParams: zod_1.z.object({
|
|
202
193
|
componentId: zod_1.z.string(),
|
|
203
|
-
content: zod_1.z.any().optional()
|
|
194
|
+
content: zod_1.z.any().optional(),
|
|
195
|
+
parameters: zod_1.z.record(zod_1.z.any()).optional()
|
|
204
196
|
}),
|
|
205
197
|
sticky: zod_1.z.record(zod_1.z.object({
|
|
206
198
|
from: zod_1.z.number(),
|
|
@@ -55,7 +55,6 @@ interface MediaCommonParams extends CommonParamsBase {
|
|
|
55
55
|
}
|
|
56
56
|
interface VideoCommonParams extends MediaCommonParams {
|
|
57
57
|
coverUrl: string | null;
|
|
58
|
-
scrollPlaybackFrameData?: ScrollPlaybackFrameData | null;
|
|
59
58
|
}
|
|
60
59
|
interface ImageCommonParams extends MediaCommonParams {
|
|
61
60
|
}
|
|
@@ -90,6 +89,7 @@ interface YoutubeEmbedCommonParams extends CommonParamsBase {
|
|
|
90
89
|
interface ComponentCommonParams extends CommonParamsBase {
|
|
91
90
|
componentId: string;
|
|
92
91
|
content?: any;
|
|
92
|
+
parameters?: Record<string, any>;
|
|
93
93
|
}
|
|
94
94
|
interface MediaLayoutParams {
|
|
95
95
|
opacity: number;
|
|
@@ -227,14 +227,6 @@ 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
|
-
}
|
|
238
230
|
export interface StickyParams {
|
|
239
231
|
from: number;
|
|
240
232
|
to?: number;
|