@remotion/studio-shared 4.0.495 → 4.0.497

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.
@@ -252,10 +252,11 @@ export type SaveSequencePropEdit = {
252
252
  };
253
253
  export type SaveSequencePropsRequest = {
254
254
  edits: SaveSequencePropEdit[];
255
- movedKeyframes?: {
255
+ addedKeyframes: AddSequenceKeyframe[] | null;
256
+ movedKeyframes: {
256
257
  sequenceKeyframes: MoveSequenceKeyframe[];
257
258
  effectKeyframes: MoveEffectKeyframe[];
258
- };
259
+ } | null;
259
260
  clientId: string;
260
261
  undoLabel: string;
261
262
  redoLabel: string;
@@ -551,6 +552,7 @@ export type InsertableCompositionElement = {
551
552
  width: number;
552
553
  height: number;
553
554
  } | null;
555
+ durationInFrames: number | null;
554
556
  position: InsertableCompositionElementPosition | null;
555
557
  } | {
556
558
  type: 'svg';
@@ -574,6 +576,7 @@ export type InsertJsxElementRequest = {
574
576
  compositionFile: string;
575
577
  compositionId: string;
576
578
  element: InsertableCompositionElement;
579
+ from: number | null;
577
580
  };
578
581
  export type InsertJsxElementResponse = {
579
582
  success: true;
@@ -596,6 +599,7 @@ export type InsertElementRequest = {
596
599
  compositionFile: string;
597
600
  compositionId: string;
598
601
  element: ElementDragData['element'];
602
+ from: number | null;
599
603
  position: InsertableCompositionElementPosition | null;
600
604
  };
601
605
  export type InsertElementResponse = {
@@ -20,11 +20,19 @@ type KeyframeClipboardFieldTypeSupport = typeof KEYFRAME_CLIPBOARD_FIELD_TYPE_SU
20
20
  export type KeyframeClipboardFieldType = {
21
21
  [FieldType in keyof KeyframeClipboardFieldTypeSupport]: KeyframeClipboardFieldTypeSupport[FieldType] extends true ? FieldType : never;
22
22
  }[keyof KeyframeClipboardFieldTypeSupport];
23
+ export type KeyframeClipboardField = {
24
+ readonly type: 'sequence';
25
+ readonly fieldKey: string;
26
+ } | {
27
+ readonly type: 'effect';
28
+ readonly fieldKey: string;
29
+ };
23
30
  export type KeyframeClipboardData = {
24
31
  readonly type: 'keyframe';
25
32
  readonly version: 1;
26
33
  readonly remotionClipboard: 'keyframe';
27
34
  readonly fieldType: KeyframeClipboardFieldType | null;
35
+ readonly field: KeyframeClipboardField | null;
28
36
  readonly keyframes: readonly {
29
37
  readonly frameOffset: number;
30
38
  readonly value: unknown;
@@ -50,6 +50,11 @@ const areValidKeyframes = (value) => {
50
50
  }
51
51
  return ((_a = value[0]) === null || _a === void 0 ? void 0 : _a.frameOffset) === 0;
52
52
  };
53
+ const isKeyframeClipboardField = (value) => {
54
+ return (isRecord(value) &&
55
+ (value.type === 'sequence' || value.type === 'effect') &&
56
+ typeof value.fieldKey === 'string');
57
+ };
53
58
  const parseEasings = ({ value, keyframeCount, }) => {
54
59
  if (Array.isArray(value) &&
55
60
  value.length === Math.max(0, keyframeCount - 1) &&
@@ -76,6 +81,7 @@ const parseKeyframeClipboardDataResult = (value) => {
76
81
  if (parsed.type !== 'keyframe' ||
77
82
  !areValidKeyframes(parsed.keyframes) ||
78
83
  easing === null ||
84
+ (parsed.field !== null && !isKeyframeClipboardField(parsed.field)) ||
79
85
  (parsed.fieldType !== null &&
80
86
  !(0, exports.isKeyframeClipboardFieldType)(parsed.fieldType))) {
81
87
  return { status: 'invalid' };
@@ -87,6 +93,7 @@ const parseKeyframeClipboardDataResult = (value) => {
87
93
  version: 1,
88
94
  remotionClipboard: 'keyframe',
89
95
  fieldType: parsed.fieldType,
96
+ field: parsed.field,
90
97
  keyframes: parsed.keyframes,
91
98
  easing,
92
99
  },
@@ -18,7 +18,7 @@ export type EffectSchemaFieldInfo = SchemaFieldInfo & {
18
18
  };
19
19
  export type AnySchemaFieldInfo = InteractivitySchemaFieldInfo | EffectSchemaFieldInfo;
20
20
  export declare const SCHEMA_FIELD_ROW_HEIGHT = 22;
21
- export type SchemaFieldGroup = 'source' | 'controls' | 'transforms' | 'text';
21
+ export type SchemaFieldGroup = 'source' | 'controls' | 'transforms' | 'background' | 'border' | 'text';
22
22
  export type SchemaFieldGroupInfo = {
23
23
  readonly id: SchemaFieldGroup;
24
24
  readonly label: string;
@@ -35,6 +35,12 @@ export declare const SCHEMA_FIELD_GROUPS: readonly [{
35
35
  }, {
36
36
  readonly id: "text";
37
37
  readonly label: "Text";
38
+ }, {
39
+ readonly id: "background";
40
+ readonly label: "Background";
41
+ }, {
42
+ readonly id: "border";
43
+ readonly label: "Border";
38
44
  }];
39
45
  export declare const getSchemaFieldGroup: (key: string) => SchemaFieldGroup;
40
46
  declare const TIMELINE_SCHEMA_FIELD_TYPE_SUPPORT: {
@@ -9,6 +9,8 @@ exports.SCHEMA_FIELD_GROUPS = [
9
9
  { id: 'controls', label: 'Controls' },
10
10
  { id: 'transforms', label: 'Transform' },
11
11
  { id: 'text', label: 'Text' },
12
+ { id: 'background', label: 'Background' },
13
+ { id: 'border', label: 'Border' },
12
14
  ];
13
15
  const schemaFieldGroupOrder = exports.SCHEMA_FIELD_GROUPS.reduce((acc, group, index) => {
14
16
  acc[group.id] = index;
@@ -21,6 +23,12 @@ const TRANSFORM_FIELD_KEYS = new Set([
21
23
  'style.rotate',
22
24
  'style.opacity',
23
25
  ]);
26
+ const BORDER_FIELD_KEYS = new Set([
27
+ 'style.borderWidth',
28
+ 'style.borderStyle',
29
+ 'style.borderColor',
30
+ ]);
31
+ const BACKGROUND_FIELD_KEYS = new Set(['style.backgroundColor']);
24
32
  const TEXT_FIELD_KEYS = new Set([
25
33
  'children',
26
34
  'style.color',
@@ -39,6 +47,12 @@ const getSchemaFieldGroup = (key) => {
39
47
  if (TRANSFORM_FIELD_KEYS.has(key)) {
40
48
  return 'transforms';
41
49
  }
50
+ if (BORDER_FIELD_KEYS.has(key)) {
51
+ return 'border';
52
+ }
53
+ if (BACKGROUND_FIELD_KEYS.has(key)) {
54
+ return 'background';
55
+ }
42
56
  if (TEXT_FIELD_KEYS.has(key)) {
43
57
  return 'text';
44
58
  }
@@ -4,6 +4,16 @@ exports.studioHtml = void 0;
4
4
  const remotion_1 = require("remotion");
5
5
  const studioHtml = ({ publicPath, editorName, inputProps, envVariables, staticHash, remotionRoot, studioServerCommand, renderQueue, completedClientRenders, numberOfAudioTags, publicFiles, includeFavicon, title, renderDefaults, publicFolderExists, fileSystemPlatform, gitSource, projectName, installedDependencies, packageManager, audioLatencyHint, sampleRate, logLevel, mode, bundleScriptUrl, readOnlyStudio, studioRuntimeConfig, }) => {
6
6
  const scriptUrl = bundleScriptUrl !== null && bundleScriptUrl !== void 0 ? bundleScriptUrl : `${publicPath}bundle.js`;
7
+ const isRelativeBundle = mode === 'bundle' && publicPath === './';
8
+ const staticBaseValue = isRelativeBundle
9
+ ? `new URL(${JSON.stringify(staticHash)}, window.location.href).pathname`
10
+ : JSON.stringify(staticHash);
11
+ const staticFilesValue = isRelativeBundle
12
+ ? `${JSON.stringify(publicFiles)}.map((file) => ({...file, src: new URL(file.src, window.location.href).pathname}))`
13
+ : JSON.stringify(publicFiles);
14
+ const publicFolderExistsValue = isRelativeBundle && publicFolderExists
15
+ ? `new URL(${JSON.stringify(publicFolderExists)}, window.location.href).pathname`
16
+ : JSON.stringify(publicFolderExists);
7
17
  return `
8
18
  <!DOCTYPE html>
9
19
  <html lang="en">
@@ -21,7 +31,7 @@ const studioHtml = ({ publicPath, editorName, inputProps, envVariables, staticHa
21
31
  <script>window.remotion_sampleRate = ${sampleRate};</script>
22
32
  <script>window.remotion_previewSampleRate = ${sampleRate};</script>
23
33
  ${mode === 'dev' ? `<script>window.remotion_logLevel = "${logLevel}";</script>` : ''}
24
- <script>window.remotion_staticBase = "${staticHash}";</script>
34
+ <script>window.remotion_staticBase = ${staticBaseValue};</script>
25
35
  ${editorName
26
36
  ? `<script>window.remotion_editorName = "${editorName}";</script>`
27
37
  : '<script>window.remotion_editorName = null;</script>'}
@@ -54,11 +64,16 @@ const studioHtml = ({ publicPath, editorName, inputProps, envVariables, staticHa
54
64
  <script>window.remotion_isStudio = true;</script>
55
65
  <script>window.remotion_isReadOnlyStudio = ${readOnlyStudio ? 'true' : 'false'};</script>`.trimStart()
56
66
  : ''}
57
- <script>window.remotion_staticFiles = ${JSON.stringify(publicFiles)}</script>
67
+ <script>window.remotion_staticFiles = ${staticFilesValue}</script>
58
68
  <script>window.remotion_installedPackages = ${JSON.stringify(installedDependencies)}</script>
59
69
  <script>window.remotion_packageManager = ${JSON.stringify(packageManager)}</script>
60
- <script>window.remotion_publicFolderExists = ${JSON.stringify(publicFolderExists)};</script>
70
+ <script>window.remotion_publicFolderExists = ${publicFolderExistsValue};</script>
61
71
  <script>
72
+ // Increment this value when the generated bundle format or behavior changes
73
+ // in a backwards-incompatible way. It is not the Remotion package version
74
+ // and should not be bumped for every generated HTML change.
75
+ // Keep it synchronized with requiredVersion in
76
+ // packages/renderer/src/set-props-and-env.ts by incrementing both values.
62
77
  window.siteVersion = '11';
63
78
  window.remotion_version = '${remotion_1.VERSION}';
64
79
  </script>
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.495",
6
+ "version": "4.0.497",
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.495"
23
+ "remotion": "4.0.497"
24
24
  },
25
25
  "devDependencies": {
26
- "@remotion/renderer": "4.0.495",
27
- "@remotion/eslint-config-internal": "4.0.495",
26
+ "@remotion/renderer": "4.0.497",
27
+ "@remotion/eslint-config-internal": "4.0.497",
28
28
  "eslint": "9.19.0",
29
29
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
30
30
  },
@@ -1,7 +0,0 @@
1
- import { type CanUpdateSequencePropsResponse, type SequenceSchema } from 'remotion';
2
- export declare const optimisticUpdateForCodeValues: ({ previous, fieldKey, value, schema, }: {
3
- previous: CanUpdateSequencePropsResponse;
4
- fieldKey: string;
5
- value: unknown;
6
- schema: SequenceSchema;
7
- }) => CanUpdateSequencePropsResponse;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optimisticUpdateForCodeValues = void 0;
4
- const no_react_1 = require("remotion/no-react");
5
- const optimisticUpdateForCodeValues = ({ previous, fieldKey, value, schema, }) => {
6
- var _a;
7
- if (!previous.canUpdate) {
8
- return previous;
9
- }
10
- const props = {
11
- ...previous.props,
12
- [fieldKey]: { status: 'static', codeValue: value },
13
- };
14
- if (((_a = schema[fieldKey]) === null || _a === void 0 ? void 0 : _a.type) === 'enum') {
15
- const propsToDelete = no_react_1.NoReactInternals.findPropsToDelete({
16
- schema,
17
- key: fieldKey,
18
- value,
19
- });
20
- for (const propToDelete of propsToDelete) {
21
- delete props[propToDelete];
22
- }
23
- }
24
- return {
25
- canUpdate: true,
26
- props,
27
- effects: previous.effects,
28
- };
29
- };
30
- exports.optimisticUpdateForCodeValues = optimisticUpdateForCodeValues;
@@ -1,8 +0,0 @@
1
- import { type CanUpdateSequencePropsResponse, type SequenceSchema } from 'remotion';
2
- export declare const optimisticUpdateForEffectCodeValues: ({ previous, effectIndex, fieldKey, value, schema, }: {
3
- previous: CanUpdateSequencePropsResponse;
4
- effectIndex: number;
5
- fieldKey: string;
6
- value: unknown;
7
- schema: SequenceSchema;
8
- }) => CanUpdateSequencePropsResponse;
@@ -1,43 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optimisticUpdateForEffectCodeValues = void 0;
4
- const no_react_1 = require("remotion/no-react");
5
- const optimisticUpdateForEffectCodeValues = ({ previous, effectIndex, fieldKey, value, schema, }) => {
6
- var _a;
7
- if (!previous.canUpdate) {
8
- return previous;
9
- }
10
- const targetIndex = previous.effects.findIndex((e) => e.effectIndex === effectIndex);
11
- if (targetIndex === -1) {
12
- return previous;
13
- }
14
- const target = previous.effects[targetIndex];
15
- if (!target.canUpdate) {
16
- return previous;
17
- }
18
- const props = {
19
- ...target.props,
20
- [fieldKey]: { status: 'static', codeValue: value },
21
- };
22
- if (((_a = schema[fieldKey]) === null || _a === void 0 ? void 0 : _a.type) === 'enum') {
23
- const propsToDelete = no_react_1.NoReactInternals.findPropsToDelete({
24
- schema,
25
- key: fieldKey,
26
- value,
27
- });
28
- for (const propToDelete of propsToDelete) {
29
- delete props[propToDelete];
30
- }
31
- }
32
- const updatedEffect = {
33
- ...target,
34
- props,
35
- };
36
- const effects = [...previous.effects];
37
- effects[targetIndex] = updatedEffect;
38
- return {
39
- ...previous,
40
- effects,
41
- };
42
- };
43
- exports.optimisticUpdateForEffectCodeValues = optimisticUpdateForEffectCodeValues;
@@ -1,22 +0,0 @@
1
- export declare const SHAPE_DRAG_MIME_TYPE = "application/vnd.remotion.shape+json";
2
- export declare const shapeNames: readonly ["Arrow", "Circle", "Ellipse", "Heart", "Pie", "Polygon", "Rect", "Star", "Triangle"];
3
- export type ShapeName = (typeof shapeNames)[number];
4
- export type ShapeAttribute = {
5
- name: string;
6
- value: string | number | boolean;
7
- };
8
- export type ShapeDragData = {
9
- type: 'remotion-shape';
10
- version: 1;
11
- shape: ShapeName;
12
- attributes: ShapeAttribute[];
13
- };
14
- export declare const isShapeName: (value: unknown) => value is "Arrow" | "Circle" | "Ellipse" | "Heart" | "Pie" | "Polygon" | "Rect" | "Star" | "Triangle";
15
- export declare const isShapeAttributeName: (value: unknown) => value is string;
16
- export declare const isShapeAttribute: (value: unknown) => value is ShapeAttribute;
17
- export declare const areShapeAttributes: (value: unknown) => value is ShapeAttribute[];
18
- export declare const makeShapeDragData: ({ attributes, shape, }: {
19
- attributes: ShapeAttribute[];
20
- shape: "Arrow" | "Circle" | "Ellipse" | "Heart" | "Pie" | "Polygon" | "Rect" | "Star" | "Triangle";
21
- }) => ShapeDragData;
22
- export declare const parseShapeDragData: (value: string) => ShapeDragData | null;
@@ -1,90 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseShapeDragData = exports.makeShapeDragData = exports.areShapeAttributes = exports.isShapeAttribute = exports.isShapeAttributeName = exports.isShapeName = exports.shapeNames = exports.SHAPE_DRAG_MIME_TYPE = void 0;
4
- exports.SHAPE_DRAG_MIME_TYPE = 'application/vnd.remotion.shape+json';
5
- exports.shapeNames = [
6
- 'Arrow',
7
- 'Circle',
8
- 'Ellipse',
9
- 'Heart',
10
- 'Pie',
11
- 'Polygon',
12
- 'Rect',
13
- 'Star',
14
- 'Triangle',
15
- ];
16
- const isRecord = (value) => {
17
- return typeof value === 'object' && value !== null && !Array.isArray(value);
18
- };
19
- const isShapeName = (value) => {
20
- return typeof value === 'string' && exports.shapeNames.includes(value);
21
- };
22
- exports.isShapeName = isShapeName;
23
- const isShapeAttributeName = (value) => {
24
- return (typeof value === 'string' &&
25
- value !== 'style' &&
26
- /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value));
27
- };
28
- exports.isShapeAttributeName = isShapeAttributeName;
29
- const isShapeAttribute = (value) => {
30
- if (!isRecord(value)) {
31
- return false;
32
- }
33
- if (!(0, exports.isShapeAttributeName)(value.name)) {
34
- return false;
35
- }
36
- return (typeof value.value === 'string' ||
37
- typeof value.value === 'boolean' ||
38
- (typeof value.value === 'number' && Number.isFinite(value.value)));
39
- };
40
- exports.isShapeAttribute = isShapeAttribute;
41
- const areShapeAttributes = (value) => {
42
- if (!Array.isArray(value)) {
43
- return false;
44
- }
45
- const seen = new Set();
46
- for (const attribute of value) {
47
- if (!(0, exports.isShapeAttribute)(attribute) || seen.has(attribute.name)) {
48
- return false;
49
- }
50
- seen.add(attribute.name);
51
- }
52
- return true;
53
- };
54
- exports.areShapeAttributes = areShapeAttributes;
55
- const makeShapeDragData = ({ attributes, shape, }) => {
56
- return {
57
- type: 'remotion-shape',
58
- version: 1,
59
- shape,
60
- attributes,
61
- };
62
- };
63
- exports.makeShapeDragData = makeShapeDragData;
64
- const parseShapeDragData = (value) => {
65
- try {
66
- const parsed = JSON.parse(value);
67
- if (!isRecord(parsed)) {
68
- return null;
69
- }
70
- if (parsed.type !== 'remotion-shape' || parsed.version !== 1) {
71
- return null;
72
- }
73
- if (!(0, exports.isShapeName)(parsed.shape)) {
74
- return null;
75
- }
76
- if (!(0, exports.areShapeAttributes)(parsed.attributes)) {
77
- return null;
78
- }
79
- return {
80
- type: 'remotion-shape',
81
- version: 1,
82
- shape: parsed.shape,
83
- attributes: parsed.attributes,
84
- };
85
- }
86
- catch (_a) {
87
- return null;
88
- }
89
- };
90
- exports.parseShapeDragData = parseShapeDragData;