@remotion/studio-shared 4.0.476 → 4.0.478

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.
@@ -1,6 +1,6 @@
1
1
  import type { AudioCodec, ChromeMode, Codec, ColorSpace, LogLevel, PixelFormat, StillImageFormat, VideoImageFormat, X264Preset } from '@remotion/renderer';
2
2
  import type { HardwareAccelerationOption } from '@remotion/renderer/client';
3
- import type { _InternalTypes, CannotUpdateSequenceReason, CanUpdateEffectPropsResponse, CanUpdateSequencePropsResponseFalse, CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, ExtrapolateType, SequenceNodePath, SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
3
+ import type { _InternalTypes, CannotUpdateSequenceReason, CanUpdateEffectPropsResponse, CanUpdateSequencePropsResponseFalse, CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, ExtrapolateType, JsxComponentIdentity, SequenceNodePath, SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
4
4
  import type { RecastCodemod, VisualControlChange } from './codemods';
5
5
  import type { ComponentProp } from './component-drag-data';
6
6
  import type { EffectClipboardParam, EffectClipboardPasteType, EffectClipboardSnapshot } from './effect-clipboard-data';
@@ -201,6 +201,7 @@ export type SubscribeToSequencePropsRequest = {
201
201
  line: number;
202
202
  column: number;
203
203
  nodePath: SequenceNodePath | null;
204
+ componentIdentity: JsxComponentIdentity | null;
204
205
  keys: string[];
205
206
  effects: string[][];
206
207
  clientId: string;
@@ -293,6 +294,19 @@ export type ReorderEffectResponse = {
293
294
  reason: string;
294
295
  stack: string;
295
296
  };
297
+ export type DuplicateEffectRequestItem = {
298
+ fileName: string;
299
+ sequenceNodePath: SequencePropsSubscriptionKey;
300
+ effectIndex: number;
301
+ };
302
+ export type DuplicateEffectRequest = DuplicateEffectRequestItem[];
303
+ export type DuplicateEffectResponse = {
304
+ success: true;
305
+ } | {
306
+ success: false;
307
+ reason: string;
308
+ stack: string;
309
+ };
296
310
  export type ReorderSequencePosition = 'before' | 'after';
297
311
  export type ReorderSequenceRequest = {
298
312
  fileName: string;
@@ -479,21 +493,28 @@ export type InsertableCompositionElement = {
479
493
  type: 'solid';
480
494
  width: number;
481
495
  height: number;
496
+ position: InsertableCompositionElementPosition | null;
482
497
  } | {
483
498
  type: 'component';
484
499
  componentName: string;
485
500
  importName: string;
486
501
  importPath: string;
487
502
  props: ComponentProp[];
503
+ position: InsertableCompositionElementPosition | null;
488
504
  } | {
489
505
  type: 'asset';
490
- assetType: 'image' | 'video' | 'gif' | 'audio';
506
+ assetType: 'image' | 'video' | 'gif' | 'animated-image' | 'audio';
491
507
  src: string;
492
508
  srcType: 'static' | 'remote';
493
509
  dimensions: {
494
510
  width: number;
495
511
  height: number;
496
512
  } | null;
513
+ position: InsertableCompositionElementPosition | null;
514
+ };
515
+ export type InsertableCompositionElementPosition = {
516
+ x: number;
517
+ y: number;
497
518
  };
498
519
  export type InsertJsxElementRequest = {
499
520
  compositionFile: string;
@@ -578,6 +599,7 @@ export type ApiRoutes = {
578
599
  '/api/save-effect-props': ReqAndRes<SaveEffectPropsRequest, SaveEffectPropsResponse>;
579
600
  '/api/add-effect': ReqAndRes<AddEffectRequest, AddEffectResponse>;
580
601
  '/api/reorder-effect': ReqAndRes<ReorderEffectRequest, ReorderEffectResponse>;
602
+ '/api/duplicate-effect': ReqAndRes<DuplicateEffectRequest, DuplicateEffectResponse>;
581
603
  '/api/reorder-sequence': ReqAndRes<ReorderSequenceRequest, ReorderSequenceResponse>;
582
604
  '/api/delete-keyframes': ReqAndRes<DeleteKeyframesRequest, DeleteKeyframesResponse>;
583
605
  '/api/move-keyframes': ReqAndRes<MoveKeyframesRequest, MoveKeyframesResponse>;
@@ -3,11 +3,16 @@ export type ComponentProp = {
3
3
  name: string;
4
4
  value: string | number | boolean;
5
5
  };
6
+ export type ComponentDimensions = {
7
+ height: number;
8
+ width: number;
9
+ };
6
10
  export type ComponentDragData = {
7
11
  type: 'remotion-component';
8
12
  version: 1;
9
13
  component: {
10
14
  componentName: string;
15
+ dimensions?: ComponentDimensions;
11
16
  importName: string;
12
17
  importPath: string;
13
18
  props: ComponentProp[];
@@ -18,8 +23,9 @@ export declare const isComponentImportPath: (value: unknown) => value is string;
18
23
  export declare const isComponentPropName: (value: unknown) => value is string;
19
24
  export declare const isComponentProp: (value: unknown) => value is ComponentProp;
20
25
  export declare const areComponentProps: (value: unknown) => value is ComponentProp[];
21
- export declare const makeComponentDragData: ({ componentName, importName, importPath, props, }: {
26
+ export declare const makeComponentDragData: ({ componentName, dimensions, importName, importPath, props, }: {
22
27
  componentName: string;
28
+ dimensions?: ComponentDimensions | null | undefined;
23
29
  importName: string;
24
30
  importPath: string;
25
31
  props: ComponentProp[];
@@ -51,12 +51,24 @@ const areComponentProps = (value) => {
51
51
  return true;
52
52
  };
53
53
  exports.areComponentProps = areComponentProps;
54
- const makeComponentDragData = ({ componentName, importName, importPath, props, }) => {
54
+ const isComponentDimensions = (value) => {
55
+ if (!isRecord(value)) {
56
+ return false;
57
+ }
58
+ return (typeof value.width === 'number' &&
59
+ Number.isFinite(value.width) &&
60
+ value.width >= 0 &&
61
+ typeof value.height === 'number' &&
62
+ Number.isFinite(value.height) &&
63
+ value.height >= 0);
64
+ };
65
+ const makeComponentDragData = ({ componentName, dimensions, importName, importPath, props, }) => {
55
66
  return {
56
67
  type: 'remotion-component',
57
68
  version: 1,
58
69
  component: {
59
70
  componentName,
71
+ ...(dimensions ? { dimensions } : {}),
60
72
  importName,
61
73
  importPath,
62
74
  props,
@@ -76,11 +88,12 @@ const parseComponentDragData = (value) => {
76
88
  if (!isRecord(parsed.component)) {
77
89
  return null;
78
90
  }
79
- const { componentName, importName, importPath, props } = parsed.component;
91
+ const { componentName, dimensions, importName, importPath, props } = parsed.component;
80
92
  if (!(0, exports.isComponentIdentifier)(componentName) ||
81
93
  !(0, exports.isComponentIdentifier)(importName) ||
82
94
  !(0, exports.isComponentImportPath)(importPath) ||
83
- !(0, exports.areComponentProps)(props)) {
95
+ !(0, exports.areComponentProps)(props) ||
96
+ (typeof dimensions !== 'undefined' && !isComponentDimensions(dimensions))) {
84
97
  return null;
85
98
  }
86
99
  return {
@@ -88,6 +101,7 @@ const parseComponentDragData = (value) => {
88
101
  version: 1,
89
102
  component: {
90
103
  componentName,
104
+ ...(dimensions ? { dimensions } : {}),
91
105
  importName,
92
106
  importPath,
93
107
  props,
@@ -47,6 +47,10 @@ export type PngType = {
47
47
  type: 'png';
48
48
  dimensions: FileDimensions | null;
49
49
  };
50
+ export type ApngType = {
51
+ type: 'apng';
52
+ dimensions: FileDimensions | null;
53
+ };
50
54
  export type JpegType = {
51
55
  type: 'jpeg';
52
56
  dimensions: FileDimensions | null;
@@ -65,7 +69,7 @@ export type PdfType = {
65
69
  export type UnknownType = {
66
70
  type: 'unknown';
67
71
  };
68
- export type FileType = JpegType | WebpType | RiffType | WebmType | WavType | PdfType | AacType | IsoBaseMediaType | TransportStreamType | Mp3Type | GifType | PngType | BmpType | AacType | FlacType | M3uType | UnknownType;
69
- export type ImageFileType = JpegType | WebpType | GifType | PngType | BmpType;
72
+ export type FileType = JpegType | WebpType | RiffType | WebmType | WavType | PdfType | AacType | IsoBaseMediaType | TransportStreamType | Mp3Type | GifType | PngType | ApngType | BmpType | AacType | FlacType | M3uType | UnknownType;
73
+ export type ImageFileType = JpegType | WebpType | GifType | PngType | ApngType | BmpType;
70
74
  export declare const isImageFileType: (fileType: FileType) => fileType is ImageFileType;
71
75
  export declare const detectFileType: (data: Uint8Array<ArrayBufferLike>) => FileType;
@@ -69,12 +69,15 @@ const isM3u = (data) => {
69
69
  return new TextDecoder('utf-8').decode(data.slice(0, 7)) === '#EXTM3U';
70
70
  };
71
71
  exports.isM3u = isM3u;
72
+ const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
73
+ const acTLChunkType = new Uint8Array([0x61, 0x63, 0x54, 0x4c]);
74
+ const idatChunkType = new Uint8Array([0x49, 0x44, 0x41, 0x54]);
75
+ const iendChunkType = new Uint8Array([0x49, 0x45, 0x4e, 0x44]);
72
76
  const getPngDimensions = (pngData) => {
73
77
  if (pngData.length < 24) {
74
78
  return null;
75
79
  }
76
80
  const view = new DataView(pngData.buffer, pngData.byteOffset);
77
- const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
78
81
  for (let i = 0; i < 8; i++) {
79
82
  if (pngData[i] !== pngSignature[i]) {
80
83
  return null;
@@ -85,11 +88,38 @@ const getPngDimensions = (pngData) => {
85
88
  height: view.getUint32(20, false),
86
89
  };
87
90
  };
91
+ const hasApngAnimationControlChunk = (pngData) => {
92
+ if (pngData.length < 16) {
93
+ return false;
94
+ }
95
+ const view = new DataView(pngData.buffer, pngData.byteOffset, pngData.byteLength);
96
+ let offset = 8;
97
+ while (offset + 8 <= pngData.length) {
98
+ const chunkLength = view.getUint32(offset, false);
99
+ const chunkType = pngData.subarray(offset + 4, offset + 8);
100
+ if ((0, exports.matchesPattern)(acTLChunkType)(chunkType)) {
101
+ return true;
102
+ }
103
+ if ((0, exports.matchesPattern)(idatChunkType)(chunkType) ||
104
+ (0, exports.matchesPattern)(iendChunkType)(chunkType)) {
105
+ return false;
106
+ }
107
+ const nextOffset = offset + 12 + chunkLength;
108
+ if (nextOffset <= offset) {
109
+ return false;
110
+ }
111
+ offset = nextOffset;
112
+ }
113
+ return false;
114
+ };
88
115
  const isPng = (data) => {
89
116
  const pngPattern = new Uint8Array([0x89, 0x50, 0x4e, 0x47]);
90
117
  if ((0, exports.matchesPattern)(pngPattern)(data.subarray(0, 4))) {
91
118
  const png = getPngDimensions(data);
92
- return { dimensions: png, type: 'png' };
119
+ return {
120
+ dimensions: png,
121
+ type: hasApngAnimationControlChunk(data) ? 'apng' : 'png',
122
+ };
93
123
  }
94
124
  return null;
95
125
  };
@@ -235,6 +265,7 @@ const isImageFileType = (fileType) => {
235
265
  fileType.type === 'webp' ||
236
266
  fileType.type === 'gif' ||
237
267
  fileType.type === 'png' ||
268
+ fileType.type === 'apng' ||
238
269
  fileType.type === 'bmp');
239
270
  };
240
271
  exports.isImageFileType = isImageFileType;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { splitAnsi, stripAnsi } from './ansi';
2
- export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddKeyframesRequest, AddKeyframesResponse, AddEffectRequest, AddEffectResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, CopyStillToClipboardRequest, DeleteEffectKeyframe, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, DeleteStaticFileRequest, DeleteStaticFileResponse, DownloadRemoteAssetRequest, DownloadRemoteAssetResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InsertJsxElementRequest, InsertJsxElementResponse, InsertableCompositionElement, InstallPackageRequest, InstallPackageResponse, LogStudioErrorRequest, LogStudioErrorResponse, MoveEffectKeyframe, MoveKeyframesRequest, MoveKeyframesResponse, MoveSequenceKeyframe, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, PasteEffectsRequest, PasteEffectsResponse, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, RenameStaticFileRequest, RenameStaticFileResponse, ReorderEffectRequest, ReorderEffectResponse, ReorderSequencePosition, ReorderSequenceRequest, ReorderSequenceResponse, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type KeyframeSettings, type AddEffectKeyframe, type AddSequenceKeyframe, } from './api-requests';
2
+ export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddKeyframesRequest, AddKeyframesResponse, AddEffectRequest, AddEffectResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, CopyStillToClipboardRequest, DeleteEffectKeyframe, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, DeleteStaticFileRequest, DeleteStaticFileResponse, DownloadRemoteAssetRequest, DownloadRemoteAssetResponse, DuplicateEffectRequest, DuplicateEffectRequestItem, DuplicateEffectResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InsertJsxElementRequest, InsertJsxElementResponse, InsertableCompositionElement, InsertableCompositionElementPosition, InstallPackageRequest, InstallPackageResponse, LogStudioErrorRequest, LogStudioErrorResponse, MoveEffectKeyframe, MoveKeyframesRequest, MoveKeyframesResponse, MoveSequenceKeyframe, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, PasteEffectsRequest, PasteEffectsResponse, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, RenameStaticFileRequest, RenameStaticFileResponse, ReorderEffectRequest, ReorderEffectResponse, ReorderSequencePosition, ReorderSequenceRequest, ReorderSequenceResponse, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type KeyframeSettings, type AddEffectKeyframe, type AddSequenceKeyframe, } from './api-requests';
3
3
  export { ASSET_DRAG_MIME_TYPE, makeAssetDragData, parseAssetDragData, type AssetDragData, } from './asset-drag-data';
4
4
  export type { ApplyVisualControlCodemod, RecastCodemod } from './codemods';
5
- export { COMPONENT_DRAG_MIME_TYPE, areComponentProps, isComponentIdentifier, isComponentImportPath, makeComponentDragData, parseComponentDragData, type ComponentDragData, type ComponentProp, } from './component-drag-data';
5
+ export { COMPONENT_DRAG_MIME_TYPE, areComponentProps, isComponentIdentifier, isComponentImportPath, makeComponentDragData, parseComponentDragData, type ComponentDimensions, type ComponentDragData, type ComponentProp, } from './component-drag-data';
6
6
  export { DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS } from './default-buffer-state-delay-in-milliseconds';
7
7
  export { KEYFRAME_EASING_PRESETS, type KeyframeEasingPreset, } from './keyframe-easing-presets';
8
8
  export { detectFileType, isImageFileType, type FileDimensions, type FileType, type ImageFileType, } from './detect-file-type';
@@ -26,6 +26,9 @@ const getRequiredPackageForInsertableElement = (element) => {
26
26
  if (element.assetType === 'gif') {
27
27
  return '@remotion/gif';
28
28
  }
29
+ if (element.assetType === 'animated-image') {
30
+ return null;
31
+ }
29
32
  return null;
30
33
  };
31
34
  exports.getRequiredPackageForInsertableElement = getRequiredPackageForInsertableElement;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-shared"
4
4
  },
5
5
  "name": "@remotion/studio-shared",
6
- "version": "4.0.476",
6
+ "version": "4.0.478",
7
7
  "description": "Internal package for shared objects between the Studio backend and frontend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -20,11 +20,11 @@
20
20
  "url": "https://github.com/remotion-dev/remotion/issues"
21
21
  },
22
22
  "dependencies": {
23
- "remotion": "4.0.476"
23
+ "remotion": "4.0.478"
24
24
  },
25
25
  "devDependencies": {
26
- "@remotion/renderer": "4.0.476",
27
- "@remotion/eslint-config-internal": "4.0.476",
26
+ "@remotion/renderer": "4.0.478",
27
+ "@remotion/eslint-config-internal": "4.0.478",
28
28
  "eslint": "9.19.0",
29
29
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
30
30
  },