@remotion/studio-shared 4.0.470 → 4.0.472

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.
@@ -2,6 +2,7 @@ import type { AudioCodec, ChromeMode, Codec, ColorSpace, LogLevel, PixelFormat,
2
2
  import type { HardwareAccelerationOption } from '@remotion/renderer/client';
3
3
  import type { _InternalTypes, CannotUpdateSequenceReason, CanUpdateEffectPropsResponse, CanUpdateSequencePropsResponseFalse, CanUpdateSequencePropsResponseTrue, CanUpdateSequencePropStatus, SequenceNodePath, SequencePropsSubscriptionKey, SequenceSchema } from 'remotion';
4
4
  import type { RecastCodemod, VisualControlChange } from './codemods';
5
+ import type { EffectClipboardPasteType, EffectClipboardSnapshot } from './effect-clipboard-data';
5
6
  import type { PackageManager } from './package-manager';
6
7
  import type { ProjectInfo } from './project-info';
7
8
  import type { CompletedClientRender, RequiredChromiumOptions } from './render-job';
@@ -188,6 +189,7 @@ export type SubscribeToSequencePropsRequest = {
188
189
  fileName: string;
189
190
  line: number;
190
191
  column: number;
192
+ nodePath: SequenceNodePath | null;
191
193
  keys: string[];
192
194
  effects: string[][];
193
195
  clientId: string;
@@ -245,15 +247,42 @@ export type SaveEffectPropsRequest = {
245
247
  clientId: string;
246
248
  };
247
249
  export type SaveEffectPropsResponse = CanUpdateEffectPropsResponse;
248
- export type DeleteSequenceKeyframeRequest = {
250
+ export type AddEffectRequest = {
251
+ fileName: string;
252
+ sequenceNodePath: SequencePropsSubscriptionKey;
253
+ effectName: string;
254
+ effectImportPath: string;
255
+ effectConfig: Record<string, unknown>;
256
+ clientId: string;
257
+ };
258
+ export type AddEffectResponse = {
259
+ success: true;
260
+ } | {
261
+ success: false;
262
+ reason: string;
263
+ stack: string;
264
+ };
265
+ export type ReorderEffectRequest = {
266
+ fileName: string;
267
+ sequenceNodePath: SequencePropsSubscriptionKey;
268
+ fromIndex: number;
269
+ toIndex: number;
270
+ clientId: string;
271
+ };
272
+ export type ReorderEffectResponse = {
273
+ success: true;
274
+ } | {
275
+ success: false;
276
+ reason: string;
277
+ stack: string;
278
+ };
279
+ export type DeleteSequenceKeyframe = {
249
280
  fileName: string;
250
281
  nodePath: SequencePropsSubscriptionKey;
251
282
  key: string;
252
283
  frame: number;
253
284
  schema: SequenceSchema;
254
- clientId: string;
255
285
  };
256
- export type DeleteSequenceKeyframeResponse = SaveSequencePropsResponse;
257
286
  export type AddSequenceKeyframeRequest = {
258
287
  fileName: string;
259
288
  nodePath: SequencePropsSubscriptionKey;
@@ -264,16 +293,22 @@ export type AddSequenceKeyframeRequest = {
264
293
  clientId: string;
265
294
  };
266
295
  export type AddSequenceKeyframeResponse = SaveSequencePropsResponse;
267
- export type DeleteEffectKeyframeRequest = {
296
+ export type DeleteEffectKeyframe = {
268
297
  fileName: string;
269
298
  sequenceNodePath: SequencePropsSubscriptionKey;
270
299
  effectIndex: number;
271
300
  key: string;
272
301
  frame: number;
273
302
  schema: SequenceSchema;
303
+ };
304
+ export type DeleteKeyframesRequest = {
305
+ sequenceKeyframes: DeleteSequenceKeyframe[];
306
+ effectKeyframes: DeleteEffectKeyframe[];
274
307
  clientId: string;
275
308
  };
276
- export type DeleteEffectKeyframeResponse = SaveEffectPropsResponse;
309
+ export type DeleteKeyframesResponse = {
310
+ success: true;
311
+ };
277
312
  export type AddEffectKeyframeRequest = {
278
313
  fileName: string;
279
314
  sequenceNodePath: SequencePropsSubscriptionKey;
@@ -303,6 +338,20 @@ export type DeleteEffectResponse = {
303
338
  reason: string;
304
339
  stack: string;
305
340
  };
341
+ export type PasteEffectsRequest = {
342
+ targetFileName: string;
343
+ targetSequenceNodePath: SequencePropsSubscriptionKey;
344
+ type: EffectClipboardPasteType;
345
+ effects: EffectClipboardSnapshot[];
346
+ clientId: string;
347
+ };
348
+ export type PasteEffectsResponse = {
349
+ success: true;
350
+ } | {
351
+ success: false;
352
+ reason: string;
353
+ stack: string;
354
+ };
306
355
  export type DeleteJsxNodeRequestItem = {
307
356
  fileName: string;
308
357
  nodePath: SequenceNodePath;
@@ -328,6 +377,31 @@ export type DuplicateJsxNodeResponse = {
328
377
  reason: string;
329
378
  stack: string;
330
379
  };
380
+ export type InsertableCompositionElement = {
381
+ type: 'solid';
382
+ width: number;
383
+ height: number;
384
+ } | {
385
+ type: 'asset';
386
+ assetType: 'image' | 'video' | 'gif';
387
+ src: string;
388
+ dimensions: {
389
+ width: number;
390
+ height: number;
391
+ } | null;
392
+ };
393
+ export type InsertJsxElementRequest = {
394
+ compositionFile: string;
395
+ compositionId: string;
396
+ element: InsertableCompositionElement;
397
+ };
398
+ export type InsertJsxElementResponse = {
399
+ success: true;
400
+ } | {
401
+ success: false;
402
+ reason: string;
403
+ stack: string;
404
+ };
331
405
  export type UpdateAvailableRequest = {};
332
406
  export type UpdateAvailableResponse = {
333
407
  currentVersion: string;
@@ -381,13 +455,16 @@ export type ApiRoutes = {
381
455
  '/api/unsubscribe-from-sequence-props': ReqAndRes<UnsubscribeFromSequencePropsRequest, undefined>;
382
456
  '/api/save-sequence-props': ReqAndRes<SaveSequencePropsRequest, SaveSequencePropsResponse>;
383
457
  '/api/save-effect-props': ReqAndRes<SaveEffectPropsRequest, SaveEffectPropsResponse>;
384
- '/api/delete-sequence-keyframe': ReqAndRes<DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse>;
458
+ '/api/add-effect': ReqAndRes<AddEffectRequest, AddEffectResponse>;
459
+ '/api/reorder-effect': ReqAndRes<ReorderEffectRequest, ReorderEffectResponse>;
460
+ '/api/delete-keyframes': ReqAndRes<DeleteKeyframesRequest, DeleteKeyframesResponse>;
385
461
  '/api/add-sequence-keyframe': ReqAndRes<AddSequenceKeyframeRequest, AddSequenceKeyframeResponse>;
386
- '/api/delete-effect-keyframe': ReqAndRes<DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse>;
387
462
  '/api/add-effect-keyframe': ReqAndRes<AddEffectKeyframeRequest, AddEffectKeyframeResponse>;
388
463
  '/api/delete-effect': ReqAndRes<DeleteEffectRequest, DeleteEffectResponse>;
464
+ '/api/paste-effects': ReqAndRes<PasteEffectsRequest, PasteEffectsResponse>;
389
465
  '/api/delete-jsx-node': ReqAndRes<DeleteJsxNodeRequest, DeleteJsxNodeResponse>;
390
466
  '/api/duplicate-jsx-node': ReqAndRes<DuplicateJsxNodeRequest, DuplicateJsxNodeResponse>;
467
+ '/api/insert-jsx-element': ReqAndRes<InsertJsxElementRequest, InsertJsxElementResponse>;
391
468
  '/api/update-available': ReqAndRes<UpdateAvailableRequest, UpdateAvailableResponse>;
392
469
  '/api/apply-codemod': ReqAndRes<ApplyCodemodRequest, ApplyCodemodResponse>;
393
470
  '/api/project-info': ReqAndRes<ProjectInfoRequest, ProjectInfoResponse>;
@@ -25,4 +25,13 @@ export type RecastCodemod = {
25
25
  } | {
26
26
  type: 'delete-composition';
27
27
  idToDelete: string;
28
+ } | {
29
+ type: 'rename-folder';
30
+ folderName: string;
31
+ parentName: string | null;
32
+ newName: string;
33
+ } | {
34
+ type: 'delete-folder';
35
+ folderName: string;
36
+ parentName: string | null;
28
37
  } | ApplyVisualControlCodemod;
@@ -0,0 +1,48 @@
1
+ import { type KeyframeInterpolationFunction } from './keyframe-interpolation-function';
2
+ export type EffectClipboardPasteType = 'effects-additive' | 'effects-replacing';
3
+ export type EffectClipboardStaticParam = {
4
+ readonly type: 'static';
5
+ readonly value: unknown;
6
+ };
7
+ export type EffectClipboardInterpolationFunction = KeyframeInterpolationFunction;
8
+ export type EffectClipboardKeyframe = {
9
+ readonly frame: number;
10
+ readonly value: unknown;
11
+ };
12
+ export type EffectClipboardEasing = 'linear' | [number, number, number, number];
13
+ export type EffectClipboardExtrapolateType = 'extend' | 'identity' | 'clamp' | 'wrap';
14
+ export type EffectClipboardClamping = {
15
+ readonly left: EffectClipboardExtrapolateType;
16
+ readonly right: EffectClipboardExtrapolateType;
17
+ };
18
+ export type EffectClipboardKeyframedParam = {
19
+ readonly type: 'keyframed';
20
+ readonly interpolationFunction: EffectClipboardInterpolationFunction;
21
+ readonly keyframes: EffectClipboardKeyframe[];
22
+ readonly easing: EffectClipboardEasing[];
23
+ readonly clamping: EffectClipboardClamping;
24
+ readonly posterize?: number;
25
+ };
26
+ export type EffectClipboardParam = EffectClipboardStaticParam | EffectClipboardKeyframedParam;
27
+ export type EffectClipboardSnapshot = {
28
+ readonly callee: string;
29
+ readonly importPath: string;
30
+ readonly params: Record<string, EffectClipboardParam>;
31
+ };
32
+ export type EffectClipboardData = {
33
+ readonly type: EffectClipboardPasteType;
34
+ readonly version: 3;
35
+ readonly remotionClipboard: 'effects';
36
+ readonly effects: EffectClipboardSnapshot[];
37
+ };
38
+ export type EffectClipboardDataParseResult = {
39
+ readonly status: 'valid';
40
+ readonly data: EffectClipboardData;
41
+ } | {
42
+ readonly status: 'unsupported-version';
43
+ readonly version: unknown;
44
+ } | {
45
+ readonly status: 'invalid';
46
+ };
47
+ export declare const parseEffectClipboardDataResult: (value: string) => EffectClipboardDataParseResult;
48
+ export declare const parseEffectClipboardData: (value: string) => EffectClipboardData | null;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEffectClipboardData = exports.parseEffectClipboardDataResult = void 0;
4
+ const keyframe_interpolation_function_1 = require("./keyframe-interpolation-function");
5
+ const isRecord = (value) => {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ };
8
+ const extrapolateTypes = new Set(['extend', 'identity', 'clamp', 'wrap']);
9
+ const isFiniteNumber = (value) => {
10
+ return typeof value === 'number' && Number.isFinite(value);
11
+ };
12
+ const isEasing = (value) => {
13
+ return (value === 'linear' ||
14
+ (Array.isArray(value) &&
15
+ value.length === 4 &&
16
+ value.every((item) => isFiniteNumber(item))));
17
+ };
18
+ const isKeyframe = (value) => {
19
+ return isRecord(value) && isFiniteNumber(value.frame) && 'value' in value;
20
+ };
21
+ const isClamping = (value) => {
22
+ return (isRecord(value) &&
23
+ typeof value.left === 'string' &&
24
+ extrapolateTypes.has(value.left) &&
25
+ typeof value.right === 'string' &&
26
+ extrapolateTypes.has(value.right));
27
+ };
28
+ const isEffectClipboardParam = (value) => {
29
+ if (!isRecord(value)) {
30
+ return false;
31
+ }
32
+ if (value.type === 'static') {
33
+ return 'value' in value;
34
+ }
35
+ if (value.type !== 'keyframed') {
36
+ return false;
37
+ }
38
+ const { posterize } = value;
39
+ const easingLength = Array.isArray(value.keyframes) && value.keyframes.length > 0
40
+ ? value.keyframes.length - 1
41
+ : null;
42
+ return (typeof value.interpolationFunction === 'string' &&
43
+ (0, keyframe_interpolation_function_1.isKeyframeInterpolationFunction)(value.interpolationFunction) &&
44
+ Array.isArray(value.keyframes) &&
45
+ value.keyframes.length > 0 &&
46
+ value.keyframes.every(isKeyframe) &&
47
+ Array.isArray(value.easing) &&
48
+ value.easing.length === easingLength &&
49
+ value.easing.every(isEasing) &&
50
+ isClamping(value.clamping) &&
51
+ (posterize === undefined || (isFiniteNumber(posterize) && posterize > 0)));
52
+ };
53
+ const isEffectClipboardSnapshotV3 = (value) => {
54
+ if (!isRecord(value)) {
55
+ return false;
56
+ }
57
+ return (typeof value.callee === 'string' &&
58
+ typeof value.importPath === 'string' &&
59
+ isRecord(value.params) &&
60
+ Object.values(value.params).every(isEffectClipboardParam));
61
+ };
62
+ const parseEffectClipboardDataResult = (value) => {
63
+ try {
64
+ const parsed = JSON.parse(value);
65
+ if (!isRecord(parsed)) {
66
+ return { status: 'invalid' };
67
+ }
68
+ if (parsed.remotionClipboard !== 'effects') {
69
+ return { status: 'invalid' };
70
+ }
71
+ if (parsed.version !== 3) {
72
+ return {
73
+ status: 'unsupported-version',
74
+ version: parsed.version,
75
+ };
76
+ }
77
+ if (parsed.type !== 'effects-additive' &&
78
+ parsed.type !== 'effects-replacing') {
79
+ return { status: 'invalid' };
80
+ }
81
+ if (!Array.isArray(parsed.effects)) {
82
+ return { status: 'invalid' };
83
+ }
84
+ const effects = [];
85
+ for (const effect of parsed.effects) {
86
+ if (!isEffectClipboardSnapshotV3(effect)) {
87
+ return { status: 'invalid' };
88
+ }
89
+ effects.push(effect);
90
+ }
91
+ return {
92
+ status: 'valid',
93
+ data: {
94
+ type: parsed.type,
95
+ version: 3,
96
+ remotionClipboard: 'effects',
97
+ effects,
98
+ },
99
+ };
100
+ }
101
+ catch (_a) {
102
+ return { status: 'invalid' };
103
+ }
104
+ };
105
+ exports.parseEffectClipboardDataResult = parseEffectClipboardDataResult;
106
+ const parseEffectClipboardData = (value) => {
107
+ const result = (0, exports.parseEffectClipboardDataResult)(value);
108
+ if (result.status !== 'valid') {
109
+ return null;
110
+ }
111
+ return result.data;
112
+ };
113
+ exports.parseEffectClipboardData = parseEffectClipboardData;
@@ -0,0 +1,11 @@
1
+ export declare const EFFECT_DRAG_MIME_TYPE = "application/vnd.remotion.effect+json";
2
+ export type EffectDragData = {
3
+ type: 'remotion-effect';
4
+ version: 1;
5
+ effect: {
6
+ name: string;
7
+ importPath: string;
8
+ config: Record<string, unknown>;
9
+ };
10
+ };
11
+ export declare const parseEffectDragData: (value: string) => EffectDragData | null;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEffectDragData = exports.EFFECT_DRAG_MIME_TYPE = void 0;
4
+ exports.EFFECT_DRAG_MIME_TYPE = 'application/vnd.remotion.effect+json';
5
+ const isRecord = (value) => {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ };
8
+ const parseEffectDragData = (value) => {
9
+ try {
10
+ const parsed = JSON.parse(value);
11
+ if (!isRecord(parsed)) {
12
+ return null;
13
+ }
14
+ if (parsed.type !== 'remotion-effect' || parsed.version !== 1) {
15
+ return null;
16
+ }
17
+ if (!isRecord(parsed.effect)) {
18
+ return null;
19
+ }
20
+ const { name, importPath, config } = parsed.effect;
21
+ if (typeof name !== 'string' ||
22
+ typeof importPath !== 'string' ||
23
+ !isRecord(config)) {
24
+ return null;
25
+ }
26
+ return {
27
+ type: 'remotion-effect',
28
+ version: 1,
29
+ effect: {
30
+ name,
31
+ importPath,
32
+ config,
33
+ },
34
+ };
35
+ }
36
+ catch (_a) {
37
+ return null;
38
+ }
39
+ };
40
+ exports.parseEffectDragData = parseEffectDragData;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export { splitAnsi, stripAnsi } from './ansi';
2
- export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, AddRenderRequest, AddSequenceKeyframeRequest, AddSequenceKeyframeResponse, ApiRoutes, ApplyCodemodRequest, ApplyCodemodResponse, ApplyVisualControlRequest, ApplyVisualControlResponse, CanUpdateDefaultPropsResponse, CanUpdateSequencePropsRequest, CancelRenderRequest, CancelRenderResponse, CompositionComponentInfoRequest, CompositionComponentInfoResponse, CopyStillToClipboardRequest, DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse, DeleteEffectRequest, DeleteEffectRequestItem, DeleteEffectResponse, DeleteJsxNodeRequest, DeleteJsxNodeRequestItem, DeleteJsxNodeResponse, DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse, DeleteStaticFileRequest, DeleteStaticFileResponse, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InstallPackageRequest, InstallPackageResponse, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, } from './api-requests';
2
+ export { AddEffectKeyframeRequest, AddEffectKeyframeResponse, 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, DuplicateJsxNodeRequest, DuplicateJsxNodeResponse, InsertJsxElementRequest, InsertJsxElementResponse, InsertableCompositionElement, InstallPackageRequest, InstallPackageResponse, OpenInEditorRequest, OpenInEditorResponse, OpenInFileExplorerRequest, PasteEffectsRequest, PasteEffectsResponse, ProjectInfoRequest, ProjectInfoResponse, RedoRequest, RedoResponse, RemoveRenderRequest, ReorderEffectRequest, ReorderEffectResponse, RestartStudioRequest, RestartStudioResponse, SaveEffectPropsRequest, SaveEffectPropsResponse, SaveSequencePropEdit, SaveSequencePropsRequest, SaveSequencePropsResponse, SaveSequencePropsResult, SimpleDiff, SubscribeToDefaultPropsRequest, SubscribeToDefaultPropsResponse, SubscribeToFileExistenceRequest, SubscribeToFileExistenceResponse, SubscribeToSequencePropsRequest, SubscribeToSequencePropsResponse, UndoRequest, UndoResponse, UnsubscribeFromDefaultPropsRequest, UnsubscribeFromFileExistenceRequest, UnsubscribeFromSequencePropsRequest, UpdateAvailableRequest, UpdateAvailableResponse, UpdateDefaultPropsRequest, UpdateDefaultPropsResponse, } from './api-requests';
3
3
  export type { ApplyVisualControlCodemod, RecastCodemod } from './codemods';
4
4
  export { DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS } from './default-buffer-state-delay-in-milliseconds';
5
+ export { parseEffectClipboardData, parseEffectClipboardDataResult, type EffectClipboardClamping, type EffectClipboardData, type EffectClipboardDataParseResult, type EffectClipboardEasing, type EffectClipboardExtrapolateType, type EffectClipboardInterpolationFunction, type EffectClipboardKeyframe, type EffectClipboardKeyframedParam, type EffectClipboardParam, type EffectClipboardPasteType, type EffectClipboardSnapshot, type EffectClipboardStaticParam, } from './effect-clipboard-data';
6
+ export { EFFECT_DRAG_MIME_TYPE, parseEffectDragData, type EffectDragData, } from './effect-drag-data';
5
7
  export { EventSourceEvent } from './event-source-event';
6
8
  export { formatBytes } from './format-bytes';
7
9
  export { getAllSchemaKeys } from './get-all-keys';
@@ -10,6 +12,7 @@ export { ErrorLocation, getLocationFromBuildError, } from './get-location-from-b
10
12
  export { getProjectName } from './get-project-name';
11
13
  export type { GitSource } from './git-source';
12
14
  export { HotMiddlewareMessage, HotMiddlewareOptions, ModuleMap, hotMiddlewareOptions, } from './hot-middleware';
15
+ export { getKeyframeInterpolationFunction, getKeyframeInterpolationFunctionForSchemaField, isKeyframeInterpolationFunction, isSchemaFieldKeyframable, isSequenceFieldSchemaKeyframable, keyframeInterpolationFunctions, type KeyframeInterpolationFunction, } from './keyframe-interpolation-function';
13
16
  export { DEFAULT_TIMELINE_TRACKS } from './max-timeline-tracks';
14
17
  export { Pkgs, apiDocs, descriptions, extraPackages, installableMap, packages, type ExtraPackage, } from './package-info';
15
18
  export { PackageManager } from './package-manager';
@@ -23,7 +26,7 @@ export { ScriptLine, SomeStackFrame, StackFrame, SymbolicatedStackFrame, } from
23
26
  export { EnumPath, stringifyDefaultProps } from './stringify-default-props';
24
27
  export type { VisualControlChange } from './codemods';
25
28
  export { optimisticAddEffectKeyframe, optimisticAddSequenceKeyframe, } from './optimistic-add-keyframe';
26
- export { optimisticDeleteEffectKeyframe, optimisticDeleteSequenceKeyframe, } from './optimistic-delete-keyframe';
29
+ export { optimisticDeleteEffectKeyframe, optimisticDeleteEffectKeyframes, optimisticDeleteSequenceKeyframe, optimisticDeleteSequenceKeyframes, } from './optimistic-delete-keyframe';
27
30
  export { optimisticUpdateForCodeValues } from './optimistic-update-for-code-values';
28
31
  export { optimisticUpdateForEffectCodeValues } from './optimistic-update-for-effect-code-values';
29
32
  export { stringifySequenceExpandedRowKey, stringifySequenceSubscriptionKey, } from './stringify-sequence-subscription-key';
package/dist/index.js CHANGED
@@ -1,11 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringifySequenceSubscriptionKey = exports.stringifySequenceExpandedRowKey = exports.optimisticUpdateForEffectCodeValues = exports.optimisticUpdateForCodeValues = exports.optimisticDeleteSequenceKeyframe = exports.optimisticDeleteEffectKeyframe = exports.optimisticAddSequenceKeyframe = exports.optimisticAddEffectKeyframe = exports.stringifyDefaultProps = exports.getFieldsToShow = exports.getEffectFieldsToShow = exports.SCHEMA_FIELD_ROW_HEIGHT = exports.packages = exports.installableMap = exports.extraPackages = exports.descriptions = exports.apiDocs = exports.DEFAULT_TIMELINE_TRACKS = exports.hotMiddlewareOptions = exports.getProjectName = exports.getLocationFromBuildError = exports.getDefaultOutLocation = exports.getAllSchemaKeys = exports.formatBytes = exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = exports.stripAnsi = exports.splitAnsi = void 0;
3
+ exports.stringifySequenceSubscriptionKey = exports.stringifySequenceExpandedRowKey = exports.optimisticUpdateForEffectCodeValues = exports.optimisticUpdateForCodeValues = exports.optimisticDeleteSequenceKeyframes = exports.optimisticDeleteSequenceKeyframe = exports.optimisticDeleteEffectKeyframes = exports.optimisticDeleteEffectKeyframe = exports.optimisticAddSequenceKeyframe = exports.optimisticAddEffectKeyframe = exports.stringifyDefaultProps = exports.getFieldsToShow = exports.getEffectFieldsToShow = exports.SCHEMA_FIELD_ROW_HEIGHT = exports.packages = exports.installableMap = exports.extraPackages = exports.descriptions = exports.apiDocs = exports.DEFAULT_TIMELINE_TRACKS = exports.keyframeInterpolationFunctions = exports.isSequenceFieldSchemaKeyframable = exports.isSchemaFieldKeyframable = exports.isKeyframeInterpolationFunction = exports.getKeyframeInterpolationFunctionForSchemaField = exports.getKeyframeInterpolationFunction = exports.hotMiddlewareOptions = exports.getProjectName = exports.getLocationFromBuildError = exports.getDefaultOutLocation = exports.getAllSchemaKeys = exports.formatBytes = exports.parseEffectDragData = exports.EFFECT_DRAG_MIME_TYPE = exports.parseEffectClipboardDataResult = exports.parseEffectClipboardData = exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = exports.stripAnsi = exports.splitAnsi = void 0;
4
4
  const ansi_1 = require("./ansi");
5
5
  Object.defineProperty(exports, "splitAnsi", { enumerable: true, get: function () { return ansi_1.splitAnsi; } });
6
6
  Object.defineProperty(exports, "stripAnsi", { enumerable: true, get: function () { return ansi_1.stripAnsi; } });
7
7
  const default_buffer_state_delay_in_milliseconds_1 = require("./default-buffer-state-delay-in-milliseconds");
8
8
  Object.defineProperty(exports, "DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS", { enumerable: true, get: function () { return default_buffer_state_delay_in_milliseconds_1.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS; } });
9
+ const effect_clipboard_data_1 = require("./effect-clipboard-data");
10
+ Object.defineProperty(exports, "parseEffectClipboardData", { enumerable: true, get: function () { return effect_clipboard_data_1.parseEffectClipboardData; } });
11
+ Object.defineProperty(exports, "parseEffectClipboardDataResult", { enumerable: true, get: function () { return effect_clipboard_data_1.parseEffectClipboardDataResult; } });
12
+ const effect_drag_data_1 = require("./effect-drag-data");
13
+ Object.defineProperty(exports, "EFFECT_DRAG_MIME_TYPE", { enumerable: true, get: function () { return effect_drag_data_1.EFFECT_DRAG_MIME_TYPE; } });
14
+ Object.defineProperty(exports, "parseEffectDragData", { enumerable: true, get: function () { return effect_drag_data_1.parseEffectDragData; } });
9
15
  const format_bytes_1 = require("./format-bytes");
10
16
  Object.defineProperty(exports, "formatBytes", { enumerable: true, get: function () { return format_bytes_1.formatBytes; } });
11
17
  const get_all_keys_1 = require("./get-all-keys");
@@ -18,6 +24,13 @@ const get_project_name_1 = require("./get-project-name");
18
24
  Object.defineProperty(exports, "getProjectName", { enumerable: true, get: function () { return get_project_name_1.getProjectName; } });
19
25
  const hot_middleware_1 = require("./hot-middleware");
20
26
  Object.defineProperty(exports, "hotMiddlewareOptions", { enumerable: true, get: function () { return hot_middleware_1.hotMiddlewareOptions; } });
27
+ const keyframe_interpolation_function_1 = require("./keyframe-interpolation-function");
28
+ Object.defineProperty(exports, "getKeyframeInterpolationFunction", { enumerable: true, get: function () { return keyframe_interpolation_function_1.getKeyframeInterpolationFunction; } });
29
+ Object.defineProperty(exports, "getKeyframeInterpolationFunctionForSchemaField", { enumerable: true, get: function () { return keyframe_interpolation_function_1.getKeyframeInterpolationFunctionForSchemaField; } });
30
+ Object.defineProperty(exports, "isKeyframeInterpolationFunction", { enumerable: true, get: function () { return keyframe_interpolation_function_1.isKeyframeInterpolationFunction; } });
31
+ Object.defineProperty(exports, "isSchemaFieldKeyframable", { enumerable: true, get: function () { return keyframe_interpolation_function_1.isSchemaFieldKeyframable; } });
32
+ Object.defineProperty(exports, "isSequenceFieldSchemaKeyframable", { enumerable: true, get: function () { return keyframe_interpolation_function_1.isSequenceFieldSchemaKeyframable; } });
33
+ Object.defineProperty(exports, "keyframeInterpolationFunctions", { enumerable: true, get: function () { return keyframe_interpolation_function_1.keyframeInterpolationFunctions; } });
21
34
  const max_timeline_tracks_1 = require("./max-timeline-tracks");
22
35
  Object.defineProperty(exports, "DEFAULT_TIMELINE_TRACKS", { enumerable: true, get: function () { return max_timeline_tracks_1.DEFAULT_TIMELINE_TRACKS; } });
23
36
  const package_info_1 = require("./package-info");
@@ -37,7 +50,9 @@ Object.defineProperty(exports, "optimisticAddEffectKeyframe", { enumerable: true
37
50
  Object.defineProperty(exports, "optimisticAddSequenceKeyframe", { enumerable: true, get: function () { return optimistic_add_keyframe_1.optimisticAddSequenceKeyframe; } });
38
51
  const optimistic_delete_keyframe_1 = require("./optimistic-delete-keyframe");
39
52
  Object.defineProperty(exports, "optimisticDeleteEffectKeyframe", { enumerable: true, get: function () { return optimistic_delete_keyframe_1.optimisticDeleteEffectKeyframe; } });
53
+ Object.defineProperty(exports, "optimisticDeleteEffectKeyframes", { enumerable: true, get: function () { return optimistic_delete_keyframe_1.optimisticDeleteEffectKeyframes; } });
40
54
  Object.defineProperty(exports, "optimisticDeleteSequenceKeyframe", { enumerable: true, get: function () { return optimistic_delete_keyframe_1.optimisticDeleteSequenceKeyframe; } });
55
+ Object.defineProperty(exports, "optimisticDeleteSequenceKeyframes", { enumerable: true, get: function () { return optimistic_delete_keyframe_1.optimisticDeleteSequenceKeyframes; } });
41
56
  const optimistic_update_for_code_values_1 = require("./optimistic-update-for-code-values");
42
57
  Object.defineProperty(exports, "optimisticUpdateForCodeValues", { enumerable: true, get: function () { return optimistic_update_for_code_values_1.optimisticUpdateForCodeValues; } });
43
58
  const optimistic_update_for_effect_code_values_1 = require("./optimistic-update-for-effect-code-values");
@@ -0,0 +1,19 @@
1
+ import type { SequenceFieldSchema, SequenceSchema } from 'remotion';
2
+ export declare const keyframeInterpolationFunctions: readonly ["interpolate", "interpolateColors"];
3
+ export type KeyframeInterpolationFunction = (typeof keyframeInterpolationFunctions)[number];
4
+ export declare const isKeyframeInterpolationFunction: (name: string) => name is "interpolate" | "interpolateColors";
5
+ export declare const isSequenceFieldSchemaKeyframable: (field: SequenceFieldSchema | undefined) => boolean;
6
+ export declare const isSchemaFieldKeyframable: ({ schema, key, }: {
7
+ schema: SequenceSchema | null;
8
+ key: string;
9
+ }) => boolean;
10
+ export declare const getKeyframeInterpolationFunctionForSchemaField: ({ schema, key, }: {
11
+ schema: SequenceSchema | null;
12
+ key: string;
13
+ }) => "interpolate" | "interpolateColors" | null;
14
+ export declare const getKeyframeInterpolationFunction: ({ schema, key, staticValue, newValue, }: {
15
+ schema: SequenceSchema | null;
16
+ key: string;
17
+ staticValue: unknown;
18
+ newValue: unknown;
19
+ }) => "interpolate" | "interpolateColors";
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getKeyframeInterpolationFunction = exports.getKeyframeInterpolationFunctionForSchemaField = exports.isSchemaFieldKeyframable = exports.isSequenceFieldSchemaKeyframable = exports.isKeyframeInterpolationFunction = exports.keyframeInterpolationFunctions = void 0;
4
+ exports.keyframeInterpolationFunctions = [
5
+ 'interpolate',
6
+ 'interpolateColors',
7
+ ];
8
+ const isKeyframeInterpolationFunction = (name) => {
9
+ return exports.keyframeInterpolationFunctions.includes(name);
10
+ };
11
+ exports.isKeyframeInterpolationFunction = isKeyframeInterpolationFunction;
12
+ const isSequenceFieldSchemaKeyframable = (field) => {
13
+ if (!field) {
14
+ return true;
15
+ }
16
+ if (field.type === 'array' || field.type === 'enum') {
17
+ return false;
18
+ }
19
+ return field.keyframable !== false;
20
+ };
21
+ exports.isSequenceFieldSchemaKeyframable = isSequenceFieldSchemaKeyframable;
22
+ const findFieldInSchema = (schema, key) => {
23
+ if (key in schema) {
24
+ return schema[key];
25
+ }
26
+ for (const field of Object.values(schema)) {
27
+ if (field.type !== 'enum') {
28
+ continue;
29
+ }
30
+ for (const variant of Object.values(field.variants)) {
31
+ const found = findFieldInSchema(variant, key);
32
+ if (found) {
33
+ return found;
34
+ }
35
+ }
36
+ }
37
+ return undefined;
38
+ };
39
+ const isSchemaFieldKeyframable = ({ schema, key, }) => {
40
+ const field = schema ? findFieldInSchema(schema, key) : undefined;
41
+ return (0, exports.isSequenceFieldSchemaKeyframable)(field);
42
+ };
43
+ exports.isSchemaFieldKeyframable = isSchemaFieldKeyframable;
44
+ const getKeyframeInterpolationFunctionForSchemaField = ({ schema, key, }) => {
45
+ const field = schema ? findFieldInSchema(schema, key) : undefined;
46
+ if ((field === null || field === void 0 ? void 0 : field.type) === 'color') {
47
+ return 'interpolateColors';
48
+ }
49
+ if ((field === null || field === void 0 ? void 0 : field.type) === 'scale' ||
50
+ (field === null || field === void 0 ? void 0 : field.type) === 'translate' ||
51
+ (field === null || field === void 0 ? void 0 : field.type) === 'rotation-css') {
52
+ return 'interpolate';
53
+ }
54
+ return null;
55
+ };
56
+ exports.getKeyframeInterpolationFunctionForSchemaField = getKeyframeInterpolationFunctionForSchemaField;
57
+ const getKeyframeInterpolationFunction = ({ schema, key, staticValue, newValue, }) => {
58
+ const schemaFunction = (0, exports.getKeyframeInterpolationFunctionForSchemaField)({
59
+ schema,
60
+ key,
61
+ });
62
+ if (schemaFunction) {
63
+ return schemaFunction;
64
+ }
65
+ return typeof staticValue === 'string' && typeof newValue === 'string'
66
+ ? 'interpolateColors'
67
+ : 'interpolate';
68
+ };
69
+ exports.getKeyframeInterpolationFunction = getKeyframeInterpolationFunction;
@@ -1,14 +1,16 @@
1
- import { type CanUpdateSequencePropsResponse } from 'remotion';
2
- export declare const optimisticAddSequenceKeyframe: ({ previous, fieldKey, frame, value, }: {
1
+ import { type CanUpdateSequencePropsResponse, type SequenceSchema } from 'remotion';
2
+ export declare const optimisticAddSequenceKeyframe: ({ previous, fieldKey, frame, value, schema, }: {
3
3
  previous: CanUpdateSequencePropsResponse;
4
4
  fieldKey: string;
5
5
  frame: number;
6
6
  value: unknown;
7
+ schema?: SequenceSchema | undefined;
7
8
  }) => CanUpdateSequencePropsResponse;
8
- export declare const optimisticAddEffectKeyframe: ({ previous, effectIndex, fieldKey, frame, value, }: {
9
+ export declare const optimisticAddEffectKeyframe: ({ previous, effectIndex, fieldKey, frame, value, schema, }: {
9
10
  previous: CanUpdateSequencePropsResponse;
10
11
  effectIndex: number;
11
12
  fieldKey: string;
12
13
  frame: number;
13
14
  value: unknown;
15
+ schema?: SequenceSchema | undefined;
14
16
  }) => CanUpdateSequencePropsResponse;
@@ -1,57 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.optimisticAddEffectKeyframe = exports.optimisticAddSequenceKeyframe = void 0;
4
- const getInterpolationFunction = (staticValue, newValue) => {
5
- return typeof staticValue === 'string' && typeof newValue === 'string'
6
- ? 'interpolateColors'
7
- : 'interpolate';
8
- };
9
- const addKeyframeToPropStatus = ({ status, frame, value, }) => {
4
+ const keyframe_interpolation_function_1 = require("./keyframe-interpolation-function");
5
+ const addKeyframeToPropStatus = ({ status, fieldKey, frame, value, schema, }) => {
10
6
  var _a;
11
- if (status.canUpdate) {
12
- const staticValue = (_a = status.codeValue) !== null && _a !== void 0 ? _a : value;
13
- const initialKeyframes = frame === 0
14
- ? [{ frame, value }]
15
- : [
16
- { frame: 0, value: staticValue },
17
- { frame, value },
18
- ];
7
+ if (status.status === 'keyframed') {
8
+ const existingIndex = status.keyframes.findIndex((kf) => kf.frame === frame);
9
+ if (existingIndex !== -1) {
10
+ const updatedKeyframes = status.keyframes.map((keyframe, index) => index === existingIndex ? { frame, value } : keyframe);
11
+ return {
12
+ ...status,
13
+ keyframes: updatedKeyframes,
14
+ };
15
+ }
16
+ const keyframes = [...status.keyframes, { frame, value }].sort((first, second) => first.frame - second.frame);
17
+ const easing = [...status.easing];
18
+ while (easing.length < keyframes.length - 1) {
19
+ easing.push('linear');
20
+ }
19
21
  return {
20
- canUpdate: false,
21
- reason: 'keyframed',
22
- interpolationFunction: getInterpolationFunction(staticValue, value),
23
- keyframes: initialKeyframes,
24
- easing: frame === 0 ? [] : ['linear'],
25
- clamping: { left: 'extend', right: 'extend' },
26
- posterize: undefined,
22
+ ...status,
23
+ keyframes,
24
+ easing,
27
25
  };
28
26
  }
29
- if (status.reason !== 'keyframed') {
30
- return status;
31
- }
32
- const existingIndex = status.keyframes.findIndex((kf) => kf.frame === frame);
33
- if (existingIndex !== -1) {
34
- const updatedKeyframes = status.keyframes.map((keyframe, index) => index === existingIndex ? { frame, value } : keyframe);
27
+ if (status.status === 'static') {
28
+ const staticValue = (_a = status.codeValue) !== null && _a !== void 0 ? _a : value;
35
29
  return {
36
- ...status,
37
- keyframes: updatedKeyframes,
30
+ status: 'keyframed',
31
+ codeValue: undefined,
32
+ interpolationFunction: (0, keyframe_interpolation_function_1.getKeyframeInterpolationFunction)({
33
+ schema,
34
+ key: fieldKey,
35
+ staticValue,
36
+ newValue: value,
37
+ }),
38
+ keyframes: [{ frame, value }],
39
+ easing: [],
40
+ clamping: { left: 'clamp', right: 'clamp' },
41
+ posterize: undefined,
38
42
  };
39
43
  }
40
- const keyframes = [...status.keyframes, { frame, value }].sort((first, second) => first.frame - second.frame);
41
- const easing = [...status.easing];
42
- while (easing.length < keyframes.length - 1) {
43
- easing.push('linear');
44
- }
45
- return {
46
- ...status,
47
- keyframes,
48
- easing,
49
- };
44
+ return status;
50
45
  };
51
- const optimisticAddSequenceKeyframe = ({ previous, fieldKey, frame, value, }) => {
46
+ const optimisticAddSequenceKeyframe = ({ previous, fieldKey, frame, value, schema, }) => {
52
47
  if (!previous.canUpdate) {
53
48
  return previous;
54
49
  }
50
+ if (!(0, keyframe_interpolation_function_1.isSchemaFieldKeyframable)({ schema: schema !== null && schema !== void 0 ? schema : null, key: fieldKey })) {
51
+ return previous;
52
+ }
55
53
  const status = previous.props[fieldKey];
56
54
  if (!status) {
57
55
  return previous;
@@ -60,15 +58,24 @@ const optimisticAddSequenceKeyframe = ({ previous, fieldKey, frame, value, }) =>
60
58
  ...previous,
61
59
  props: {
62
60
  ...previous.props,
63
- [fieldKey]: addKeyframeToPropStatus({ status, frame, value }),
61
+ [fieldKey]: addKeyframeToPropStatus({
62
+ status,
63
+ fieldKey,
64
+ frame,
65
+ value,
66
+ schema: schema !== null && schema !== void 0 ? schema : null,
67
+ }),
64
68
  },
65
69
  };
66
70
  };
67
71
  exports.optimisticAddSequenceKeyframe = optimisticAddSequenceKeyframe;
68
- const optimisticAddEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, value, }) => {
72
+ const optimisticAddEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, value, schema, }) => {
69
73
  if (!previous.canUpdate) {
70
74
  return previous;
71
75
  }
76
+ if (!(0, keyframe_interpolation_function_1.isSchemaFieldKeyframable)({ schema: schema !== null && schema !== void 0 ? schema : null, key: fieldKey })) {
77
+ return previous;
78
+ }
72
79
  const targetIndex = previous.effects.findIndex((e) => e.effectIndex === effectIndex);
73
80
  if (targetIndex === -1) {
74
81
  return previous;
@@ -85,7 +92,13 @@ const optimisticAddEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, v
85
92
  ...target,
86
93
  props: {
87
94
  ...target.props,
88
- [fieldKey]: addKeyframeToPropStatus({ status, frame, value }),
95
+ [fieldKey]: addKeyframeToPropStatus({
96
+ status,
97
+ fieldKey,
98
+ frame,
99
+ value,
100
+ schema: schema !== null && schema !== void 0 ? schema : null,
101
+ }),
89
102
  },
90
103
  };
91
104
  const effects = [...previous.effects];
@@ -4,9 +4,24 @@ export declare const optimisticDeleteSequenceKeyframe: ({ previous, fieldKey, fr
4
4
  fieldKey: string;
5
5
  frame: number;
6
6
  }) => CanUpdateSequencePropsResponse;
7
+ export declare const optimisticDeleteSequenceKeyframes: ({ previous, keyframes, }: {
8
+ previous: CanUpdateSequencePropsResponse;
9
+ keyframes: {
10
+ fieldKey: string;
11
+ frame: number;
12
+ }[];
13
+ }) => CanUpdateSequencePropsResponse;
7
14
  export declare const optimisticDeleteEffectKeyframe: ({ previous, effectIndex, fieldKey, frame, }: {
8
15
  previous: CanUpdateSequencePropsResponse;
9
16
  effectIndex: number;
10
17
  fieldKey: string;
11
18
  frame: number;
12
19
  }) => CanUpdateSequencePropsResponse;
20
+ export declare const optimisticDeleteEffectKeyframes: ({ previous, keyframes, }: {
21
+ previous: CanUpdateSequencePropsResponse;
22
+ keyframes: {
23
+ effectIndex: number;
24
+ fieldKey: string;
25
+ frame: number;
26
+ }[];
27
+ }) => CanUpdateSequencePropsResponse;
@@ -1,11 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.optimisticDeleteEffectKeyframe = exports.optimisticDeleteSequenceKeyframe = void 0;
3
+ exports.optimisticDeleteEffectKeyframes = exports.optimisticDeleteEffectKeyframe = exports.optimisticDeleteSequenceKeyframes = exports.optimisticDeleteSequenceKeyframe = void 0;
4
4
  const removeKeyframeFromPropStatus = ({ status, frame, }) => {
5
- if (status.canUpdate) {
6
- return status;
7
- }
8
- if (status.reason !== 'keyframed') {
5
+ if (status.status !== 'keyframed') {
9
6
  return status;
10
7
  }
11
8
  const index = status.keyframes.findIndex((kf) => kf.frame === frame);
@@ -13,6 +10,12 @@ const removeKeyframeFromPropStatus = ({ status, frame, }) => {
13
10
  return status;
14
11
  }
15
12
  const keyframes = status.keyframes.filter((_, i) => i !== index);
13
+ if (keyframes.length === 0) {
14
+ return {
15
+ status: 'static',
16
+ codeValue: status.keyframes[index].value,
17
+ };
18
+ }
16
19
  // Easing holds one segment per gap between consecutive keyframes
17
20
  // (keyframes.length - 1 entries). Drop the segment adjacent to the removed
18
21
  // keyframe so the invariant keeps holding until the server responds.
@@ -44,6 +47,14 @@ const optimisticDeleteSequenceKeyframe = ({ previous, fieldKey, frame, }) => {
44
47
  };
45
48
  };
46
49
  exports.optimisticDeleteSequenceKeyframe = optimisticDeleteSequenceKeyframe;
50
+ const optimisticDeleteSequenceKeyframes = ({ previous, keyframes, }) => {
51
+ return keyframes.reduce((current, keyframe) => (0, exports.optimisticDeleteSequenceKeyframe)({
52
+ previous: current,
53
+ fieldKey: keyframe.fieldKey,
54
+ frame: keyframe.frame,
55
+ }), previous);
56
+ };
57
+ exports.optimisticDeleteSequenceKeyframes = optimisticDeleteSequenceKeyframes;
47
58
  const optimisticDeleteEffectKeyframe = ({ previous, effectIndex, fieldKey, frame, }) => {
48
59
  if (!previous.canUpdate) {
49
60
  return previous;
@@ -75,3 +86,12 @@ const optimisticDeleteEffectKeyframe = ({ previous, effectIndex, fieldKey, frame
75
86
  };
76
87
  };
77
88
  exports.optimisticDeleteEffectKeyframe = optimisticDeleteEffectKeyframe;
89
+ const optimisticDeleteEffectKeyframes = ({ previous, keyframes, }) => {
90
+ return keyframes.reduce((current, keyframe) => (0, exports.optimisticDeleteEffectKeyframe)({
91
+ previous: current,
92
+ effectIndex: keyframe.effectIndex,
93
+ fieldKey: keyframe.fieldKey,
94
+ frame: keyframe.frame,
95
+ }), previous);
96
+ };
97
+ exports.optimisticDeleteEffectKeyframes = optimisticDeleteEffectKeyframes;
@@ -9,7 +9,7 @@ const optimisticUpdateForCodeValues = ({ previous, fieldKey, value, schema, }) =
9
9
  }
10
10
  const props = {
11
11
  ...previous.props,
12
- [fieldKey]: { canUpdate: true, codeValue: value },
12
+ [fieldKey]: { status: 'static', codeValue: value },
13
13
  };
14
14
  if (((_a = schema[fieldKey]) === null || _a === void 0 ? void 0 : _a.type) === 'enum') {
15
15
  const propsToDelete = no_react_1.NoReactInternals.findPropsToDelete({
@@ -17,7 +17,7 @@ const optimisticUpdateForEffectCodeValues = ({ previous, effectIndex, fieldKey,
17
17
  }
18
18
  const props = {
19
19
  ...target.props,
20
- [fieldKey]: { canUpdate: true, codeValue: value },
20
+ [fieldKey]: { status: 'static', codeValue: value },
21
21
  };
22
22
  if (((_a = schema[fieldKey]) === null || _a === void 0 ? void 0 : _a.type) === 'enum') {
23
23
  const propsToDelete = no_react_1.NoReactInternals.findPropsToDelete({
@@ -17,7 +17,7 @@ export type EffectSchemaFieldInfo = SchemaFieldInfo & {
17
17
  };
18
18
  export type AnySchemaFieldInfo = SequenceSchemaFieldInfo | EffectSchemaFieldInfo;
19
19
  export declare const SCHEMA_FIELD_ROW_HEIGHT = 22;
20
- declare const SUPPORTED_SCHEMA_TYPES: readonly ["number", "boolean", "rotation", "translate", "uv-coordinate", "color", "enum", "hidden"];
20
+ declare const SUPPORTED_SCHEMA_TYPES: readonly ["number", "boolean", "rotation-css", "rotation-degrees", "translate", "scale", "uv-coordinate", "color", "array", "enum", "hidden"];
21
21
  type SupportedSchemaType = (typeof SUPPORTED_SCHEMA_TYPES)[number];
22
22
  export declare const getFieldsToShow: ({ getDragOverrides, codeValues, nodePath, schema, currentRuntimeValueDotNotation, }: {
23
23
  schema: SequenceSchema;
@@ -7,13 +7,49 @@ exports.SCHEMA_FIELD_ROW_HEIGHT = 22;
7
7
  const SUPPORTED_SCHEMA_TYPES = [
8
8
  'number',
9
9
  'boolean',
10
- 'rotation',
10
+ 'rotation-css',
11
+ 'rotation-degrees',
11
12
  'translate',
13
+ 'scale',
12
14
  'uv-coordinate',
13
15
  'color',
16
+ 'array',
14
17
  'enum',
15
18
  'hidden',
16
19
  ];
20
+ const getArrayRowCount = ({ fieldSchema, value, }) => {
21
+ var _a, _b;
22
+ const items = Array.isArray(value)
23
+ ? value
24
+ : Array.isArray(fieldSchema.default)
25
+ ? fieldSchema.default
26
+ : Array.from({ length: (_a = fieldSchema.minLength) !== null && _a !== void 0 ? _a : 0 });
27
+ const canAdd = items.length < ((_b = fieldSchema.maxLength) !== null && _b !== void 0 ? _b : Infinity);
28
+ return Math.max(1, items.length + (canAdd ? 1 : 0));
29
+ };
30
+ const getSchemaFieldRowHeight = ({ fieldSchema, value, }) => {
31
+ if (fieldSchema.type === 'array') {
32
+ return (getArrayRowCount({
33
+ fieldSchema,
34
+ value,
35
+ }) * exports.SCHEMA_FIELD_ROW_HEIGHT);
36
+ }
37
+ return exports.SCHEMA_FIELD_ROW_HEIGHT;
38
+ };
39
+ const getEffectFieldValue = ({ key, dragOverrides, effectStatus, }) => {
40
+ const dragOverride = remotion_1.Internals.getStaticDragOverrideValue(dragOverrides[key]);
41
+ if (dragOverride !== undefined) {
42
+ return dragOverride;
43
+ }
44
+ if ((effectStatus === null || effectStatus === void 0 ? void 0 : effectStatus.type) !== 'can-update-effect') {
45
+ return undefined;
46
+ }
47
+ const propStatus = effectStatus.props[key];
48
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'static') {
49
+ return undefined;
50
+ }
51
+ return propStatus.codeValue;
52
+ };
17
53
  const getFieldsToShow = ({ getDragOverrides, codeValues, nodePath, schema, currentRuntimeValueDotNotation, }) => {
18
54
  const { merged: valuesDotNotation } = remotion_1.Internals.computeEffectiveSchemaValuesDotNotation({
19
55
  schema,
@@ -32,6 +68,9 @@ const getFieldsToShow = ({ getDragOverrides, codeValues, nodePath, schema, curre
32
68
  if (typeName === 'hidden') {
33
69
  return null;
34
70
  }
71
+ if (fieldSchema.type === 'number' && fieldSchema.hiddenFromList) {
72
+ return null;
73
+ }
35
74
  // `hidden` is represented as the eye/speaker icon on the timeline track,
36
75
  // so we don't render it as a regular field in the expanded section.
37
76
  if (key === 'hidden') {
@@ -42,7 +81,10 @@ const getFieldsToShow = ({ getDragOverrides, codeValues, nodePath, schema, curre
42
81
  key,
43
82
  description: fieldSchema.description,
44
83
  typeName,
45
- rowHeight: exports.SCHEMA_FIELD_ROW_HEIGHT,
84
+ rowHeight: getSchemaFieldRowHeight({
85
+ fieldSchema,
86
+ value: valuesDotNotation[key],
87
+ }),
46
88
  fieldSchema,
47
89
  };
48
90
  })
@@ -59,18 +101,7 @@ const getEffectFieldsToShow = ({ effect, effectIndex, nodePath, codeValues, getE
59
101
  });
60
102
  const dragOverrides = nodePath === null ? {} : getEffectDragOverrides(nodePath, effectIndex);
61
103
  const activeSchema = remotion_1.Internals.flattenActiveSchema(effect.schema, (key) => {
62
- const dragOverride = dragOverrides[key];
63
- if (dragOverride !== undefined) {
64
- return dragOverride;
65
- }
66
- if ((effectStatus === null || effectStatus === void 0 ? void 0 : effectStatus.type) !== 'can-update-effect') {
67
- return undefined;
68
- }
69
- const propStatus = effectStatus.props[key];
70
- if (!propStatus || !propStatus.canUpdate) {
71
- return undefined;
72
- }
73
- return propStatus.codeValue;
104
+ return getEffectFieldValue({ key, dragOverrides, effectStatus });
74
105
  });
75
106
  return Object.entries(activeSchema)
76
107
  .map(([key, fieldSchema]) => {
@@ -78,6 +109,9 @@ const getEffectFieldsToShow = ({ effect, effectIndex, nodePath, codeValues, getE
78
109
  if (typeName === 'hidden') {
79
110
  return null;
80
111
  }
112
+ if (fieldSchema.type === 'number' && fieldSchema.hiddenFromList) {
113
+ return null;
114
+ }
81
115
  // `disabled` is represented as the eye icon on the effect timeline row,
82
116
  // so we don't render it as a regular field in the expanded section.
83
117
  if (key === 'disabled') {
@@ -91,7 +125,10 @@ const getEffectFieldsToShow = ({ effect, effectIndex, nodePath, codeValues, getE
91
125
  key,
92
126
  description: fieldSchema.description,
93
127
  typeName,
94
- rowHeight: exports.SCHEMA_FIELD_ROW_HEIGHT,
128
+ rowHeight: getSchemaFieldRowHeight({
129
+ fieldSchema,
130
+ value: getEffectFieldValue({ key, dragOverrides, effectStatus }),
131
+ }),
95
132
  fieldSchema,
96
133
  effectSchema: effect.schema,
97
134
  effectIndex,
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.470",
6
+ "version": "4.0.472",
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.470"
23
+ "remotion": "4.0.472"
24
24
  },
25
25
  "devDependencies": {
26
- "@remotion/renderer": "4.0.470",
27
- "@remotion/eslint-config-internal": "4.0.470",
26
+ "@remotion/renderer": "4.0.472",
27
+ "@remotion/eslint-config-internal": "4.0.472",
28
28
  "eslint": "9.19.0",
29
29
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
30
30
  },