@remotion/studio-shared 4.0.493 → 4.0.495

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.
@@ -353,6 +353,7 @@ export type DeleteSequenceKeyframe = {
353
353
  key: string;
354
354
  frame: number;
355
355
  schema: InteractivitySchema;
356
+ valueWhenLastKeyframeDeleted?: unknown;
356
357
  };
357
358
  export type MoveSequenceKeyframe = {
358
359
  fileName: string;
@@ -380,6 +381,7 @@ export type DeleteEffectKeyframe = {
380
381
  key: string;
381
382
  frame: number;
382
383
  schema: InteractivitySchema;
384
+ valueWhenLastKeyframeDeleted?: unknown;
383
385
  };
384
386
  export type MoveEffectKeyframe = {
385
387
  fileName: string;
@@ -550,6 +552,10 @@ export type InsertableCompositionElement = {
550
552
  height: number;
551
553
  } | null;
552
554
  position: InsertableCompositionElementPosition | null;
555
+ } | {
556
+ type: 'svg';
557
+ markup: string;
558
+ position: InsertableCompositionElementPosition | null;
553
559
  } | {
554
560
  type: 'composition';
555
561
  compositionId: string;
@@ -576,6 +582,16 @@ export type InsertJsxElementResponse = {
576
582
  reason: string;
577
583
  stack: string;
578
584
  };
585
+ export type ConvertFigmaClipboardToSvgRequest = {
586
+ html: string;
587
+ };
588
+ export type ConvertFigmaClipboardToSvgResponse = {
589
+ success: true;
590
+ svg: string;
591
+ } | {
592
+ success: false;
593
+ reason: string;
594
+ };
579
595
  export type InsertElementRequest = {
580
596
  compositionFile: string;
581
597
  compositionId: string;
@@ -695,6 +711,7 @@ export type ApiRoutes = {
695
711
  '/api/duplicate-jsx-node': ReqAndRes<DuplicateJsxNodeRequest, DuplicateJsxNodeResponse>;
696
712
  '/api/split-jsx-sequence': ReqAndRes<SplitJsxSequenceRequest, SplitJsxSequenceResponse>;
697
713
  '/api/insert-jsx-element': ReqAndRes<InsertJsxElementRequest, InsertJsxElementResponse>;
714
+ '/api/convert-figma-clipboard-to-svg': ReqAndRes<ConvertFigmaClipboardToSvgRequest, ConvertFigmaClipboardToSvgResponse>;
698
715
  '/api/insert-element': ReqAndRes<InsertElementRequest, InsertElementResponse>;
699
716
  '/api/update-element-install-target': ReqAndRes<UpdateElementInstallTargetRequest, UpdateElementInstallTargetResponse>;
700
717
  '/api/download-remote-asset': ReqAndRes<DownloadRemoteAssetRequest, DownloadRemoteAssetResponse>;
@@ -58,6 +58,7 @@ export type JpegType = {
58
58
  export type WebpType = {
59
59
  type: 'webp';
60
60
  dimensions: FileDimensions | null;
61
+ animated: boolean;
61
62
  };
62
63
  export type BmpType = {
63
64
  type: 'bmp';
@@ -225,12 +225,33 @@ const getWebPDimensions = (bytes) => {
225
225
  }
226
226
  return null;
227
227
  };
228
+ const isAnimatedWebp = (data) => {
229
+ const animationChunk = new Uint8Array([0x41, 0x4e, 0x49, 0x4d]);
230
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
231
+ let offset = 12;
232
+ while (offset + 8 <= data.length) {
233
+ const chunkType = data.subarray(offset, offset + 4);
234
+ if ((0, exports.matchesPattern)(animationChunk)(chunkType)) {
235
+ return true;
236
+ }
237
+ const chunkLength = view.getUint32(offset + 4, true);
238
+ const nextOffset = offset + 8 + chunkLength + (chunkLength % 2);
239
+ if (nextOffset <= offset) {
240
+ return false;
241
+ }
242
+ offset = nextOffset;
243
+ }
244
+ return false;
245
+ };
228
246
  const isWebp = (data) => {
229
- const webpPattern = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
230
- if ((0, exports.matchesPattern)(webpPattern)(data.subarray(0, 4))) {
247
+ const riffPattern = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
248
+ const webpPattern = new Uint8Array([0x57, 0x45, 0x42, 0x50]);
249
+ if ((0, exports.matchesPattern)(riffPattern)(data.subarray(0, 4)) &&
250
+ (0, exports.matchesPattern)(webpPattern)(data.subarray(8, 12))) {
231
251
  return {
232
252
  type: 'webp',
233
253
  dimensions: getWebPDimensions(data),
254
+ animated: isAnimatedWebp(data),
234
255
  };
235
256
  }
236
257
  return null;
@@ -1,5 +1,4 @@
1
- import type { StaticFile } from 'remotion';
2
- import type { CanUpdateSequencePropsResponse, SequencePropsSubscriptionKey } from 'remotion';
1
+ import type { CanUpdateSequencePropsResponse, SequencePropsSubscriptionKey, StaticFile } from 'remotion';
3
2
  import type { CanUpdateDefaultPropsResponse, ElementInstallRequest } from './api-requests';
4
3
  import type { HotMiddlewareMessage } from './hot-middleware';
5
4
  import type { CompletedClientRender, RenderJob } from './render-job';
@@ -14,6 +13,8 @@ export type EventSourceEvent = {
14
13
  } | {
15
14
  type: 'new-env-variables';
16
15
  newEnvVariables: Record<string, string>;
16
+ } | {
17
+ type: 'config-file-changed';
17
18
  } | {
18
19
  type: 'root-file-changed';
19
20
  } | {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { splitAnsi, stripAnsi } from './ansi';
2
- export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddEffectRequest, AddEffectResponse, AddKeyframesRequest, AddKeyframesResponse, 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, ElementInstallRequest, GoogleFontSourceEdit, InsertElementRequest, InsertElementResponse, 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, SaveSequencePropSourceEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SplitJsxSequenceRequest, SplitJsxSequenceResponse, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateElementInstallTargetRequest, UpdateElementInstallTargetResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type AddEffectKeyframe, type AddSequenceKeyframe, type KeyframeSettings, } from './api-requests';
2
+ export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddEffectRequest, AddEffectResponse, AddKeyframesRequest, AddKeyframesResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, ConvertFigmaClipboardToSvgRequest, ConvertFigmaClipboardToSvgResponse, CopyStillToClipboardRequest, DeleteEffectKeyframe, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteKeyframesRequest, DeleteKeyframesResponse, DeleteSequenceKeyframe, DeleteStaticFileRequest, DeleteStaticFileResponse, DownloadRemoteAssetRequest, DownloadRemoteAssetResponse, DuplicateEffectRequest, DuplicateEffectRequestItem, DuplicateEffectResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, ElementInstallRequest, GoogleFontSourceEdit, InsertElementRequest, InsertElementResponse, 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, SaveSequencePropSourceEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SplitJsxSequenceRequest, SplitJsxSequenceResponse, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, UpdateEffectKeyframeSettingsRequest, UpdateEffectKeyframeSettingsResponse, UpdateElementInstallTargetRequest, UpdateElementInstallTargetResponse, UpdateSequenceKeyframeSettingsRequest, UpdateSequenceKeyframeSettingsResponse, type AddEffectKeyframe, type AddSequenceKeyframe, type KeyframeSettings, } 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
5
  export { COMPONENT_DRAG_MIME_TYPE, areComponentProps, isComponentIdentifier, isComponentImportPath, makeComponentDragData, parseComponentDragData, type ComponentDimensions, type ComponentDragData, type ComponentProp, } from './component-drag-data';
@@ -1,21 +1,24 @@
1
1
  import { type CanUpdateSequencePropsResponse } from 'remotion';
2
- export declare const optimisticDeleteSequenceKeyframe: ({ previous, fieldKey, frame, }: {
2
+ export declare const optimisticDeleteSequenceKeyframe: ({ previous, fieldKey, frame, valueWhenLastKeyframeDeleted, }: {
3
3
  previous: CanUpdateSequencePropsResponse;
4
4
  fieldKey: string;
5
5
  frame: number;
6
+ valueWhenLastKeyframeDeleted?: unknown;
6
7
  }) => CanUpdateSequencePropsResponse;
7
8
  export declare const optimisticDeleteSequenceKeyframes: ({ previous, keyframes, }: {
8
9
  previous: CanUpdateSequencePropsResponse;
9
10
  keyframes: {
10
11
  fieldKey: string;
11
12
  frame: number;
13
+ valueWhenLastKeyframeDeleted?: unknown;
12
14
  }[];
13
15
  }) => CanUpdateSequencePropsResponse;
14
- export declare const optimisticDeleteEffectKeyframe: ({ previous, effectIndex, fieldKey, frame, }: {
16
+ export declare const optimisticDeleteEffectKeyframe: ({ previous, effectIndex, fieldKey, frame, valueWhenLastKeyframeDeleted, }: {
15
17
  previous: CanUpdateSequencePropsResponse;
16
18
  effectIndex: number;
17
19
  fieldKey: string;
18
20
  frame: number;
21
+ valueWhenLastKeyframeDeleted?: unknown;
19
22
  }) => CanUpdateSequencePropsResponse;
20
23
  export declare const optimisticDeleteEffectKeyframes: ({ previous, keyframes, }: {
21
24
  previous: CanUpdateSequencePropsResponse;
@@ -23,5 +26,6 @@ export declare const optimisticDeleteEffectKeyframes: ({ previous, keyframes, }:
23
26
  effectIndex: number;
24
27
  fieldKey: string;
25
28
  frame: number;
29
+ valueWhenLastKeyframeDeleted?: unknown;
26
30
  }[];
27
31
  }) => CanUpdateSequencePropsResponse;
@@ -10,7 +10,7 @@ const getEasingIndexToRemove = ({ removedKeyframeIndex, keyframeCountBeforeRemov
10
10
  }
11
11
  return removedKeyframeIndex;
12
12
  };
13
- const removeKeyframeFromPropStatus = ({ status, frame, }) => {
13
+ const removeKeyframeFromPropStatus = ({ status, frame, valueWhenLastKeyframeDeleted, }) => {
14
14
  if (status.status !== 'keyframed') {
15
15
  return status;
16
16
  }
@@ -22,7 +22,9 @@ const removeKeyframeFromPropStatus = ({ status, frame, }) => {
22
22
  if (keyframes.length === 0) {
23
23
  return {
24
24
  status: 'static',
25
- codeValue: status.keyframes[index].value,
25
+ codeValue: valueWhenLastKeyframeDeleted === null
26
+ ? status.keyframes[index].value
27
+ : valueWhenLastKeyframeDeleted,
26
28
  };
27
29
  }
28
30
  // Easing holds one segment per gap between consecutive keyframes
@@ -42,7 +44,7 @@ const removeKeyframeFromPropStatus = ({ status, frame, }) => {
42
44
  easing,
43
45
  };
44
46
  };
45
- const optimisticDeleteSequenceKeyframe = ({ previous, fieldKey, frame, }) => {
47
+ const optimisticDeleteSequenceKeyframe = ({ previous, fieldKey, frame, valueWhenLastKeyframeDeleted, }) => {
46
48
  if (!previous.canUpdate) {
47
49
  return previous;
48
50
  }
@@ -54,7 +56,11 @@ const optimisticDeleteSequenceKeyframe = ({ previous, fieldKey, frame, }) => {
54
56
  ...previous,
55
57
  props: {
56
58
  ...previous.props,
57
- [fieldKey]: removeKeyframeFromPropStatus({ status, frame }),
59
+ [fieldKey]: removeKeyframeFromPropStatus({
60
+ status,
61
+ frame,
62
+ valueWhenLastKeyframeDeleted: valueWhenLastKeyframeDeleted !== null && valueWhenLastKeyframeDeleted !== void 0 ? valueWhenLastKeyframeDeleted : null,
63
+ }),
58
64
  },
59
65
  };
60
66
  };
@@ -64,10 +70,11 @@ const optimisticDeleteSequenceKeyframes = ({ previous, keyframes, }) => {
64
70
  previous: current,
65
71
  fieldKey: keyframe.fieldKey,
66
72
  frame: keyframe.frame,
73
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
67
74
  }), previous);
68
75
  };
69
76
  exports.optimisticDeleteSequenceKeyframes = optimisticDeleteSequenceKeyframes;
70
- const optimisticDeleteEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, }) => {
77
+ const optimisticDeleteEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, valueWhenLastKeyframeDeleted, }) => {
71
78
  if (!previous.canUpdate) {
72
79
  return previous;
73
80
  }
@@ -87,7 +94,11 @@ const optimisticDeleteEffectKeyframe = ({ previous, effectIndex, fieldKey, frame
87
94
  ...target,
88
95
  props: {
89
96
  ...target.props,
90
- [fieldKey]: removeKeyframeFromPropStatus({ status, frame }),
97
+ [fieldKey]: removeKeyframeFromPropStatus({
98
+ status,
99
+ frame,
100
+ valueWhenLastKeyframeDeleted: valueWhenLastKeyframeDeleted !== null && valueWhenLastKeyframeDeleted !== void 0 ? valueWhenLastKeyframeDeleted : null,
101
+ }),
91
102
  },
92
103
  };
93
104
  const effects = [...previous.effects];
@@ -104,6 +115,7 @@ const optimisticDeleteEffectKeyframes = ({ previous, keyframes, }) => {
104
115
  effectIndex: keyframe.effectIndex,
105
116
  fieldKey: keyframe.fieldKey,
106
117
  frame: keyframe.frame,
118
+ valueWhenLastKeyframeDeleted: keyframe.valueWhenLastKeyframeDeleted,
107
119
  }), previous);
108
120
  };
109
121
  exports.optimisticDeleteEffectKeyframes = optimisticDeleteEffectKeyframes;
@@ -20,7 +20,7 @@ const getRequiredPackageForImportPath = (importPath) => {
20
20
  };
21
21
  exports.getRequiredPackageForImportPath = getRequiredPackageForImportPath;
22
22
  const getRequiredPackageForInsertableElement = (element) => {
23
- if (element.type === 'solid') {
23
+ if (element.type === 'solid' || element.type === 'svg') {
24
24
  return null;
25
25
  }
26
26
  if (element.type === 'component') {
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.493",
6
+ "version": "4.0.495",
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.493"
23
+ "remotion": "4.0.495"
24
24
  },
25
25
  "devDependencies": {
26
- "@remotion/renderer": "4.0.493",
27
- "@remotion/eslint-config-internal": "4.0.493",
26
+ "@remotion/renderer": "4.0.495",
27
+ "@remotion/eslint-config-internal": "4.0.495",
28
28
  "eslint": "9.19.0",
29
29
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
30
30
  },