@remotion/serverless-client 4.0.471 → 4.0.473

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,4 +1,121 @@
1
1
  // ../core/dist/esm/no-react.mjs
2
+ var normalizeNumber = (value) => {
3
+ return Math.round(value * 1e6) / 1e6;
4
+ };
5
+ var angleUnits = new Set(["deg", "rad", "grad", "turn"]);
6
+ var lengthUnits = new Set([
7
+ "%",
8
+ "cap",
9
+ "ch",
10
+ "cm",
11
+ "cqb",
12
+ "cqh",
13
+ "cqi",
14
+ "cqmax",
15
+ "cqmin",
16
+ "cqw",
17
+ "dvh",
18
+ "dvw",
19
+ "em",
20
+ "ex",
21
+ "ic",
22
+ "in",
23
+ "lh",
24
+ "lvh",
25
+ "lvw",
26
+ "mm",
27
+ "pc",
28
+ "pt",
29
+ "px",
30
+ "q",
31
+ "rem",
32
+ "rlh",
33
+ "svh",
34
+ "svw",
35
+ "vb",
36
+ "vh",
37
+ "vi",
38
+ "vmax",
39
+ "vmin",
40
+ "vw"
41
+ ]);
42
+ var cssNumberRegex = /^([+-]?(?:\d+\.?\d*|\.\d+))([a-zA-Z%]+)?$/;
43
+ var stringifyNumber = (value) => {
44
+ return String(normalizeNumber(value));
45
+ };
46
+ var parseStringInterpolationComponent = (component, value) => {
47
+ const match = cssNumberRegex.exec(component);
48
+ if (match === null) {
49
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not a supported scale, translate, or rotate value`);
50
+ }
51
+ const unit = match[2] ?? null;
52
+ const numberValue = Number(match[1]);
53
+ if (!Number.isFinite(numberValue)) {
54
+ throw new TypeError(`Cannot interpolate "${value}" because "${component}" is not finite`);
55
+ }
56
+ if (unit === null) {
57
+ return { kind: "scale", value: numberValue, unit: null };
58
+ }
59
+ if (angleUnits.has(unit)) {
60
+ return { kind: "rotate", value: numberValue, unit };
61
+ }
62
+ if (lengthUnits.has(unit)) {
63
+ return { kind: "translate", value: numberValue, unit };
64
+ }
65
+ throw new TypeError(`Cannot interpolate "${value}" because "${unit}" is not a supported translate or rotate unit`);
66
+ };
67
+ var parseStringInterpolationValue = (output) => {
68
+ if (typeof output === "number") {
69
+ if (!Number.isFinite(output)) {
70
+ throw new Error(`outputRange must contain only finite numbers, but got [${output}]`);
71
+ }
72
+ return {
73
+ kind: "scale",
74
+ values: [output, output, 1],
75
+ units: [null, null, null],
76
+ dimensions: 1
77
+ };
78
+ }
79
+ const parts = output.trim().split(/\s+/);
80
+ if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
81
+ throw new TypeError(`String outputRange values must contain 1 to 3 components, but got "${output}"`);
82
+ }
83
+ const parsed = parts.map((part) => parseStringInterpolationComponent(part, output));
84
+ const [{ kind }] = parsed;
85
+ for (const part of parsed) {
86
+ if (part.kind !== kind) {
87
+ throw new TypeError(`Cannot interpolate "${output}" because it mixes ${kind} and ${part.kind} values`);
88
+ }
89
+ }
90
+ if (kind === "scale") {
91
+ const x = parsed[0].value;
92
+ const y = parsed[1]?.value ?? x;
93
+ const z = parsed[2]?.value ?? 1;
94
+ return {
95
+ kind,
96
+ values: [x, y, z],
97
+ units: [null, null, null],
98
+ dimensions: parsed.length
99
+ };
100
+ }
101
+ return {
102
+ kind,
103
+ values: [parsed[0].value, parsed[1]?.value ?? 0, parsed[2]?.value ?? 0],
104
+ units: [parsed[0].unit, parsed[1]?.unit ?? null, parsed[2]?.unit ?? null],
105
+ dimensions: parsed.length
106
+ };
107
+ };
108
+ var serializeStringInterpolationValue = ({
109
+ kind,
110
+ values,
111
+ units,
112
+ dimensions
113
+ }) => {
114
+ if (kind === "scale") {
115
+ return values.slice(0, dimensions).map((value) => stringifyNumber(value)).join(" ");
116
+ }
117
+ return values.slice(0, dimensions).map((value, index) => `${stringifyNumber(value)}${units[index]}`).join(" ");
118
+ };
2
119
  function interpolateFunction(input, inputRange, outputRange, options) {
3
120
  const { extrapolateLeft, extrapolateRight, easing } = options;
4
121
  let result = input;
@@ -43,6 +160,130 @@ function findRange(input, inputRange) {
43
160
  }
44
161
  return i - 1;
45
162
  }
163
+ var defaultEasing = (num) => num;
164
+ var interpolateNumber = ({
165
+ input,
166
+ inputRange,
167
+ outputRange,
168
+ options
169
+ }) => {
170
+ if (inputRange.length === 1) {
171
+ return outputRange[0];
172
+ }
173
+ const easingOption = options?.easing;
174
+ const resolveEasingForSegment = (segmentIndex) => {
175
+ if (easingOption === undefined) {
176
+ return defaultEasing;
177
+ }
178
+ if (typeof easingOption === "function") {
179
+ return easingOption;
180
+ }
181
+ return easingOption[segmentIndex];
182
+ };
183
+ let extrapolateLeft = "extend";
184
+ if (options?.extrapolateLeft !== undefined) {
185
+ extrapolateLeft = options.extrapolateLeft;
186
+ }
187
+ let extrapolateRight = "extend";
188
+ if (options?.extrapolateRight !== undefined) {
189
+ extrapolateRight = options.extrapolateRight;
190
+ }
191
+ const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
192
+ const range = findRange(posterizedInput, inputRange);
193
+ return interpolateFunction(posterizedInput, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
194
+ easing: resolveEasingForSegment(range),
195
+ extrapolateLeft,
196
+ extrapolateRight
197
+ });
198
+ };
199
+ var interpolateString = ({
200
+ input,
201
+ inputRange,
202
+ outputRange,
203
+ options
204
+ }) => {
205
+ const parsedOutputRange = outputRange.map(parseStringInterpolationValue);
206
+ const kind = parsedOutputRange[0]?.kind;
207
+ if (kind === undefined) {
208
+ throw new Error("outputRange must have at least 1 element");
209
+ }
210
+ for (const parsed of parsedOutputRange) {
211
+ if (parsed.kind !== kind) {
212
+ throw new TypeError(`Cannot interpolate ${kind} values with ${parsed.kind} values`);
213
+ }
214
+ }
215
+ const dimensions = Math.max(...parsedOutputRange.map((parsed) => parsed.dimensions));
216
+ const units = [
217
+ null,
218
+ null,
219
+ null
220
+ ];
221
+ if (kind !== "scale") {
222
+ for (let axis = 0;axis < dimensions; axis++) {
223
+ for (const parsed of parsedOutputRange) {
224
+ const unit = parsed.units[axis];
225
+ if (unit === null) {
226
+ continue;
227
+ }
228
+ if (units[axis] === null) {
229
+ units[axis] = unit;
230
+ continue;
231
+ }
232
+ if (units[axis] !== unit) {
233
+ throw new TypeError(`Cannot interpolate ${kind} values with different units on axis ${axis + 1}: ${units[axis]} and ${unit}`);
234
+ }
235
+ }
236
+ if (units[axis] === null) {
237
+ throw new TypeError(`Cannot interpolate ${kind} values because axis ${axis + 1} has no unit`);
238
+ }
239
+ }
240
+ }
241
+ return serializeStringInterpolationValue({
242
+ kind,
243
+ values: [0, 0, 0].map((_, axis) => interpolateNumber({
244
+ input,
245
+ inputRange,
246
+ outputRange: parsedOutputRange.map((parsed) => parsed.values[axis]),
247
+ options
248
+ })),
249
+ units,
250
+ dimensions
251
+ });
252
+ };
253
+ var validateTupleOutputRange = (outputRange) => {
254
+ const dimensions = outputRange[0]?.length;
255
+ if (dimensions === undefined) {
256
+ throw new Error("outputRange must have at least 1 element");
257
+ }
258
+ if (dimensions === 0) {
259
+ throw new TypeError("outputRange tuples must contain at least 1 number");
260
+ }
261
+ for (const output of outputRange) {
262
+ if (output.length !== dimensions) {
263
+ throw new TypeError(`outputRange tuples must all have the same length, but got ${dimensions} and ${output.length}`);
264
+ }
265
+ for (const value of output) {
266
+ if (typeof value !== "number" || !Number.isFinite(value)) {
267
+ throw new TypeError(`outputRange tuples must contain only finite numbers, but got [${output.join(",")}]`);
268
+ }
269
+ }
270
+ }
271
+ return dimensions;
272
+ };
273
+ var interpolateTuple = ({
274
+ input,
275
+ inputRange,
276
+ outputRange,
277
+ options
278
+ }) => {
279
+ const dimensions = validateTupleOutputRange(outputRange);
280
+ return new Array(dimensions).fill(true).map((_, axis) => interpolateNumber({
281
+ input,
282
+ inputRange,
283
+ outputRange: outputRange.map((output) => output[axis]),
284
+ options
285
+ }));
286
+ };
46
287
  function checkValidInputRange(arr) {
47
288
  for (let i = 1;i < arr.length; ++i) {
48
289
  if (!(arr[i] > arr[i - 1])) {
@@ -102,42 +343,30 @@ function interpolate(input, inputRange, outputRange, options) {
102
343
  throw new Error("inputRange (" + inputRange.length + ") and outputRange (" + outputRange.length + ") must have the same length");
103
344
  }
104
345
  checkInfiniteRange("inputRange", inputRange);
105
- checkInfiniteRange("outputRange", outputRange);
106
346
  checkValidInputRange(inputRange);
107
347
  assertValidInterpolateEasingOption(options?.easing, inputRange.length);
108
348
  assertValidInterpolatePosterizeOption(options?.posterize);
109
- const easingOption = options?.easing;
110
- const defaultEasing = (num) => num;
111
- const resolveEasingForSegment = (segmentIndex) => {
112
- if (easingOption === undefined) {
113
- return defaultEasing;
114
- }
115
- if (typeof easingOption === "function") {
116
- return easingOption;
117
- }
118
- return easingOption[segmentIndex];
119
- };
120
- let extrapolateLeft = "extend";
121
- if (options?.extrapolateLeft !== undefined) {
122
- extrapolateLeft = options.extrapolateLeft;
123
- }
124
- let extrapolateRight = "extend";
125
- if (options?.extrapolateRight !== undefined) {
126
- extrapolateRight = options.extrapolateRight;
127
- }
128
349
  if (typeof input !== "number") {
129
350
  throw new TypeError("Cannot interpolate an input which is not a number");
130
351
  }
131
- if (inputRange.length === 1) {
132
- return outputRange[0];
352
+ if (!Array.isArray(outputRange)) {
353
+ throw new Error("outputRange must contain only numbers");
133
354
  }
134
- const posterizedInput = options?.posterize === undefined ? input : Math.floor(input / options.posterize) * options.posterize;
135
- const range = findRange(posterizedInput, inputRange);
136
- return interpolateFunction(posterizedInput, [inputRange[range], inputRange[range + 1]], [outputRange[range], outputRange[range + 1]], {
137
- easing: resolveEasingForSegment(range),
138
- extrapolateLeft,
139
- extrapolateRight
140
- });
355
+ const hasStringOutput = outputRange.some((output) => typeof output === "string");
356
+ if (hasStringOutput) {
357
+ if (!outputRange.every((output) => typeof output === "string" || typeof output === "number")) {
358
+ throw new TypeError("outputRange must contain only numbers, or supported scale, translate, and rotate strings");
359
+ }
360
+ return interpolateString({ input, inputRange, outputRange, options });
361
+ }
362
+ if (outputRange.every((output) => Array.isArray(output))) {
363
+ return interpolateTuple({ input, inputRange, outputRange, options });
364
+ }
365
+ if (!outputRange.every((output) => typeof output === "number")) {
366
+ throw new TypeError("outputRange must contain only numbers, numeric tuples, or supported scale, translate, and rotate strings");
367
+ }
368
+ checkInfiniteRange("outputRange", outputRange);
369
+ return interpolateNumber({ input, inputRange, outputRange, options });
141
370
  }
142
371
  function mulberry32(a) {
143
372
  let t = a + 1831565813;
@@ -720,6 +949,45 @@ var proResProfileOptions = [
720
949
  "light",
721
950
  "proxy"
722
951
  ];
952
+ var defaultScaleValue = [1, 1, 1];
953
+ var parseScaleString = (value) => {
954
+ const parts = value.trim().split(/\s+/);
955
+ if (parts.length < 1 || parts.length > 3 || parts[0] === "") {
956
+ return null;
957
+ }
958
+ const parsed = parts.map((part) => Number(part));
959
+ if (!parsed.every((part) => Number.isFinite(part))) {
960
+ return null;
961
+ }
962
+ const x = parsed[0];
963
+ const y = parsed[1] ?? x;
964
+ const z = parsed[2] ?? 1;
965
+ return [x, y, z];
966
+ };
967
+ var parseValidScaleValue = (value) => {
968
+ if (typeof value === "number") {
969
+ return Number.isFinite(value) ? [value, value, 1] : null;
970
+ }
971
+ if (typeof value === "string") {
972
+ return parseScaleString(value);
973
+ }
974
+ return null;
975
+ };
976
+ var parseScaleValue = (value) => {
977
+ return parseValidScaleValue(value) ?? defaultScaleValue;
978
+ };
979
+ var serializeScaleValue = ([x, y, z]) => {
980
+ const normalizedX = normalizeNumber(x);
981
+ const normalizedY = normalizeNumber(y);
982
+ const normalizedZ = normalizeNumber(z);
983
+ if (normalizedX === normalizedY && normalizedZ === 1) {
984
+ return normalizedX;
985
+ }
986
+ if (normalizedZ === 1) {
987
+ return `${normalizedX} ${normalizedY}`;
988
+ }
989
+ return `${normalizedX} ${normalizedY} ${normalizedZ}`;
990
+ };
723
991
  var sequenceVisualStyleSchema = {
724
992
  "style.translate": {
725
993
  type: "translate",
@@ -728,15 +996,14 @@ var sequenceVisualStyleSchema = {
728
996
  description: "Offset"
729
997
  },
730
998
  "style.scale": {
731
- type: "number",
732
- min: 0.05,
999
+ type: "scale",
733
1000
  max: 100,
734
1001
  step: 0.01,
735
1002
  default: 1,
736
1003
  description: "Scale"
737
1004
  },
738
1005
  "style.rotate": {
739
- type: "rotation",
1006
+ type: "rotation-css",
740
1007
  step: 1,
741
1008
  default: "0deg",
742
1009
  description: "Rotation"
@@ -747,7 +1014,8 @@ var sequenceVisualStyleSchema = {
747
1014
  max: 1,
748
1015
  step: 0.01,
749
1016
  default: 1,
750
- description: "Opacity"
1017
+ description: "Opacity",
1018
+ hiddenFromList: false
751
1019
  }
752
1020
  };
753
1021
  var sequencePremountSchema = {
@@ -756,10 +1024,15 @@ var sequencePremountSchema = {
756
1024
  default: 0,
757
1025
  description: "Premount For",
758
1026
  min: 0,
759
- step: 1
1027
+ step: 1,
1028
+ hiddenFromList: false
760
1029
  },
761
1030
  postmountFor: {
762
- type: "hidden"
1031
+ type: "number",
1032
+ default: 0,
1033
+ min: 0,
1034
+ step: 1,
1035
+ hiddenFromList: true
763
1036
  },
764
1037
  styleWhilePremounted: {
765
1038
  type: "hidden"
@@ -777,8 +1050,23 @@ var hiddenField = {
777
1050
  default: false,
778
1051
  description: "Hidden"
779
1052
  };
1053
+ var durationInFramesField = {
1054
+ type: "number",
1055
+ default: undefined,
1056
+ min: 1,
1057
+ step: 1,
1058
+ hiddenFromList: true
1059
+ };
1060
+ var fromField = {
1061
+ type: "number",
1062
+ default: 0,
1063
+ step: 1,
1064
+ hiddenFromList: true
1065
+ };
780
1066
  var sequenceSchema = {
781
1067
  hidden: hiddenField,
1068
+ from: fromField,
1069
+ durationInFrames: durationInFramesField,
782
1070
  layout: {
783
1071
  type: "enum",
784
1072
  default: "absolute-fill",
@@ -789,6 +1077,11 @@ var sequenceSchema = {
789
1077
  }
790
1078
  }
791
1079
  };
1080
+ var sequenceSchemaWithoutFrom = {
1081
+ hidden: hiddenField,
1082
+ durationInFrames: durationInFramesField,
1083
+ layout: sequenceSchema.layout
1084
+ };
792
1085
  var sequenceSchemaDefaultLayoutNone = {
793
1086
  ...sequenceSchema,
794
1087
  layout: {
@@ -960,7 +1253,9 @@ var NoReactInternals = {
960
1253
  validateCodec,
961
1254
  proResProfileOptions,
962
1255
  findPropsToDelete,
963
- sequenceSchema
1256
+ sequenceSchema,
1257
+ parseScaleValue,
1258
+ serializeScaleValue
964
1259
  };
965
1260
 
966
1261
  // src/constants.ts
@@ -1149,7 +1444,7 @@ var validateFramesPerFunction = ({
1149
1444
  import * as tty from "tty";
1150
1445
 
1151
1446
  // ../core/dist/esm/version.mjs
1152
- var VERSION = "4.0.471";
1447
+ var VERSION = "4.0.473";
1153
1448
 
1154
1449
  // ../renderer/dist/esm/error-handling.mjs
1155
1450
  var isColorSupported = () => {
@@ -2609,6 +2904,51 @@ var getExpectedOutName = ({
2609
2904
  }
2610
2905
  throw new TypeError("no type passed");
2611
2906
  };
2907
+ // src/find-output-file-in-bucket.ts
2908
+ var findOutputFileInBucket = async ({
2909
+ region,
2910
+ renderMetadata,
2911
+ bucketName,
2912
+ customCredentials,
2913
+ currentRegion,
2914
+ providerSpecifics,
2915
+ forcePathStyle,
2916
+ requestHandler
2917
+ }) => {
2918
+ const { renderBucketName, key } = getExpectedOutName({
2919
+ renderMetadata,
2920
+ bucketName,
2921
+ customCredentials,
2922
+ bucketNamePrefix: providerSpecifics.getBucketPrefix()
2923
+ });
2924
+ try {
2925
+ const metadata = await providerSpecifics.headFile({
2926
+ bucketName: renderBucketName,
2927
+ key,
2928
+ region,
2929
+ customCredentials,
2930
+ forcePathStyle,
2931
+ requestHandler
2932
+ });
2933
+ return {
2934
+ url: providerSpecifics.getOutputUrl({
2935
+ renderMetadata,
2936
+ bucketName,
2937
+ customCredentials,
2938
+ currentRegion
2939
+ }).url,
2940
+ sizeInBytes: metadata.ContentLength ?? null
2941
+ };
2942
+ } catch (err) {
2943
+ if (err.name === "NotFound") {
2944
+ return null;
2945
+ }
2946
+ if (err.message === "UnknownError" || err.$metadata?.httpStatusCode === 403) {
2947
+ throw new Error(`Unable to access item "${key}" from bucket "${renderBucketName}" ${customCredentials?.endpoint ? `(S3 Endpoint = ${customCredentials?.endpoint})` : ""} - got a 403 error when heading the file. Check your credentials and permissions. The Lambda role must have permission for both "s3:GetObject" and "s3:ListBucket" actions.`, { cause: err });
2948
+ }
2949
+ throw err;
2950
+ }
2951
+ };
2612
2952
  // src/format-costs-info.ts
2613
2953
  var display = (accrued) => {
2614
2954
  if (accrued < 0.001) {
@@ -3054,6 +3394,76 @@ var getProgress = async ({
3054
3394
  });
3055
3395
  const isBeyondTimeoutAndMissingChunks = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds + 20000 && missingChunks && missingChunks.length > 0;
3056
3396
  const isBeyondTimeoutAndHasStitchTimeout = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds * 2 + 20000;
3397
+ const shouldCheckForCompletedOutput = allChunks && (isBeyondTimeoutAndHasStitchTimeout || overallProgress.combinedFrames >= frameCount && overallProgress.timeToCombine !== null);
3398
+ if (shouldCheckForCompletedOutput) {
3399
+ const outputFile = await findOutputFileInBucket({
3400
+ bucketName,
3401
+ customCredentials,
3402
+ renderMetadata,
3403
+ region,
3404
+ currentRegion: region,
3405
+ providerSpecifics,
3406
+ forcePathStyle,
3407
+ requestHandler
3408
+ });
3409
+ if (outputFile) {
3410
+ const outData = getExpectedOutName({
3411
+ renderMetadata,
3412
+ bucketName,
3413
+ customCredentials,
3414
+ bucketNamePrefix: providerSpecifics.getBucketPrefix()
3415
+ });
3416
+ const now = Date.now();
3417
+ const timeToFinishChunks = calculateChunkTimes({
3418
+ type: "absolute-time",
3419
+ timings: overallProgress.timings
3420
+ });
3421
+ return {
3422
+ framesRendered: frameCount,
3423
+ bucket: bucketName,
3424
+ renderSize: outputFile.sizeInBytes ?? 0,
3425
+ chunks: renderMetadata.totalChunks,
3426
+ cleanup: {
3427
+ doneIn: null,
3428
+ filesDeleted: 0,
3429
+ minFilesToDelete: 0
3430
+ },
3431
+ costs: priceFromBucket ? formatCostsInfo(priceFromBucket.accruedSoFar) : formatCostsInfo(0),
3432
+ currentTime: now,
3433
+ done: true,
3434
+ encodingStatus: {
3435
+ framesEncoded: frameCount,
3436
+ combinedFrames: frameCount,
3437
+ timeToCombine: overallProgress.timeToCombine
3438
+ },
3439
+ errors: errorExplanations,
3440
+ fatalErrorEncountered: false,
3441
+ lambdasInvoked: renderMetadata.totalChunks,
3442
+ outputFile: outputFile.url,
3443
+ renderId,
3444
+ timeToFinish: now - renderMetadata.startedDate,
3445
+ timeToFinishChunks,
3446
+ timeToRenderFrames: overallProgress.timeToRenderFrames,
3447
+ overallProgress: 1,
3448
+ retriesInfo: overallProgress.retries ?? [],
3449
+ outKey: outData.key,
3450
+ outBucket: outData.renderBucketName,
3451
+ mostExpensiveFrameRanges: null,
3452
+ timeToEncode: overallProgress.timeToEncode,
3453
+ outputSizeInBytes: outputFile.sizeInBytes ?? 0,
3454
+ type: "success",
3455
+ estimatedBillingDurationInMilliseconds: priceFromBucket?.estimatedBillingDurationInMilliseconds ?? null,
3456
+ timeToCombine: overallProgress.timeToCombine,
3457
+ combinedFrames: frameCount,
3458
+ renderMetadata,
3459
+ timeoutTimestamp: overallProgress.timeoutTimestamp,
3460
+ compositionValidated: overallProgress.compositionValidated,
3461
+ functionLaunched: overallProgress.functionLaunched,
3462
+ serveUrlOpened: overallProgress.serveUrlOpened,
3463
+ artifacts: overallProgress.receivedArtifact
3464
+ };
3465
+ }
3466
+ }
3057
3467
  const allErrors = [
3058
3468
  isBeyondTimeoutAndMissingChunks || isBeyondTimeoutAndHasStitchTimeout ? makeTimeoutError({
3059
3469
  timeoutInMilliseconds,
@@ -3237,6 +3647,7 @@ export {
3237
3647
  getCredentialsFromOutName,
3238
3648
  formatMap,
3239
3649
  formatCostsInfo,
3650
+ findOutputFileInBucket,
3240
3651
  expiryDays,
3241
3652
  estimatePriceFromMetadata,
3242
3653
  errorIsOutOfSpaceError,
@@ -0,0 +1,18 @@
1
+ import type { CustomCredentials } from './constants';
2
+ import type { ProviderSpecifics } from './provider-implementation';
3
+ import type { RenderMetadata } from './render-metadata';
4
+ import type { CloudProvider } from './types';
5
+ export type OutputFileMetadata = {
6
+ url: string;
7
+ sizeInBytes: number | null;
8
+ };
9
+ export declare const findOutputFileInBucket: <Provider extends CloudProvider<string, Record<string, unknown>, Record<string, unknown>, string, object>>({ region, renderMetadata, bucketName, customCredentials, currentRegion, providerSpecifics, forcePathStyle, requestHandler, }: {
10
+ region: Provider["region"];
11
+ renderMetadata: RenderMetadata<Provider>;
12
+ bucketName: string;
13
+ customCredentials: CustomCredentials<Provider> | null;
14
+ currentRegion: Provider["region"];
15
+ providerSpecifics: ProviderSpecifics<Provider>;
16
+ forcePathStyle: boolean;
17
+ requestHandler: Provider["requestHandler"] | null;
18
+ }) => Promise<OutputFileMetadata | null>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findOutputFileInBucket = void 0;
4
+ const expected_out_name_1 = require("./expected-out-name");
5
+ const findOutputFileInBucket = async ({ region, renderMetadata, bucketName, customCredentials, currentRegion, providerSpecifics, forcePathStyle, requestHandler, }) => {
6
+ var _a;
7
+ var _b;
8
+ const { renderBucketName, key } = (0, expected_out_name_1.getExpectedOutName)({
9
+ renderMetadata,
10
+ bucketName,
11
+ customCredentials,
12
+ bucketNamePrefix: providerSpecifics.getBucketPrefix(),
13
+ });
14
+ try {
15
+ const metadata = await providerSpecifics.headFile({
16
+ bucketName: renderBucketName,
17
+ key,
18
+ region,
19
+ customCredentials,
20
+ forcePathStyle,
21
+ requestHandler,
22
+ });
23
+ return {
24
+ url: providerSpecifics.getOutputUrl({
25
+ renderMetadata,
26
+ bucketName,
27
+ customCredentials,
28
+ currentRegion,
29
+ }).url,
30
+ sizeInBytes: (_b = metadata.ContentLength) !== null && _b !== void 0 ? _b : null,
31
+ };
32
+ }
33
+ catch (err) {
34
+ if (err.name === 'NotFound') {
35
+ return null;
36
+ }
37
+ if (err.message === 'UnknownError' ||
38
+ ((_a = err.$metadata) === null || _a === void 0 ? void 0 : _a.httpStatusCode) === 403) {
39
+ throw new Error(`Unable to access item "${key}" from bucket "${renderBucketName}" ${(customCredentials === null || customCredentials === void 0 ? void 0 : customCredentials.endpoint)
40
+ ? `(S3 Endpoint = ${customCredentials === null || customCredentials === void 0 ? void 0 : customCredentials.endpoint})`
41
+ : ''} - got a 403 error when heading the file. Check your credentials and permissions. The Lambda role must have permission for both "s3:GetObject" and "s3:ListBucket" actions.`, { cause: err });
42
+ }
43
+ throw err;
44
+ }
45
+ };
46
+ exports.findOutputFileInBucket = findOutputFileInBucket;
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export { DOCS_URL } from './docs-url';
20
20
  export { errorIsOutOfSpaceError, isBrowserCrashedError, isErrInsufficientResourcesErr, } from './error-category';
21
21
  export { estimatePriceFromMetadata } from './estimate-price-from-bucket';
22
22
  export { getCredentialsFromOutName, getExpectedOutName, } from './expected-out-name';
23
+ export { findOutputFileInBucket, type OutputFileMetadata, } from './find-output-file-in-bucket';
23
24
  export { formatCostsInfo } from './format-costs-info';
24
25
  export { FileNameAndSize, GetFolderFiles } from './get-files-in-folder';
25
26
  export { GetOrCreateBucketInput, GetOrCreateBucketOutput, internalGetOrCreateBucket, } from './get-or-create-bucket';
package/dist/index.js CHANGED
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.validatePrivacy = exports.validateOutname = exports.validateBucketName = exports.truthy = exports.messageTypeIdToMessageType = exports.makeStreamPayload = exports.formatMap = exports.streamToString = exports.getProgress = exports.OVERHEAD_TIME_PER_LAMBDA = exports.getMostExpensiveChunks = exports.makeBucketName = exports.inspectErrors = exports.resolvedPropsKey = exports.inputPropsKey = exports.getRemotionVersionFromIndexHtml = exports.getOverallProgressFromStorage = exports.internalGetOrCreateBucket = exports.formatCostsInfo = exports.getExpectedOutName = exports.getCredentialsFromOutName = exports.estimatePriceFromMetadata = exports.isErrInsufficientResourcesErr = exports.isBrowserCrashedError = exports.errorIsOutOfSpaceError = exports.DOCS_URL = exports.MAX_FUNCTIONS_PER_RENDER = exports.serializeOrThrow = exports.getNeedsToUpload = exports.decompressInputProps = exports.compressInputProps = exports.calculateChunkTimes = exports.VERSION = exports.makeStreamPayloadMessage = exports.makeStreamer = exports.wrapWithErrorHandling = exports.validateFramesPerFunction = exports.validateDownloadBehavior = exports.serializeArtifact = exports.deserializeArtifact = exports.ServerlessRoutines = exports.serverlessCodecs = exports.rendersPrefix = exports.overallProgressKey = exports.outStillName = exports.outName = exports.MINIMUM_FRAMES_PER_FUNCTION = exports.expiryDays = exports.customOutName = exports.artifactName = void 0;
18
- exports.validateCodec = exports.validateDurationInFrames = exports.validateDimension = exports.validateFps = exports.serializeJSONWithSpecialTypes = exports.ENABLE_V5_BREAKING_CHANGES = exports.random = exports.interpolate = exports.validateWebhook = void 0;
17
+ exports.validateOutname = exports.validateBucketName = exports.truthy = exports.messageTypeIdToMessageType = exports.makeStreamPayload = exports.formatMap = exports.streamToString = exports.getProgress = exports.OVERHEAD_TIME_PER_LAMBDA = exports.getMostExpensiveChunks = exports.makeBucketName = exports.inspectErrors = exports.resolvedPropsKey = exports.inputPropsKey = exports.getRemotionVersionFromIndexHtml = exports.getOverallProgressFromStorage = exports.internalGetOrCreateBucket = exports.formatCostsInfo = exports.findOutputFileInBucket = exports.getExpectedOutName = exports.getCredentialsFromOutName = exports.estimatePriceFromMetadata = exports.isErrInsufficientResourcesErr = exports.isBrowserCrashedError = exports.errorIsOutOfSpaceError = exports.DOCS_URL = exports.MAX_FUNCTIONS_PER_RENDER = exports.serializeOrThrow = exports.getNeedsToUpload = exports.decompressInputProps = exports.compressInputProps = exports.calculateChunkTimes = exports.VERSION = exports.makeStreamPayloadMessage = exports.makeStreamer = exports.wrapWithErrorHandling = exports.validateFramesPerFunction = exports.validateDownloadBehavior = exports.serializeArtifact = exports.deserializeArtifact = exports.ServerlessRoutines = exports.serverlessCodecs = exports.rendersPrefix = exports.overallProgressKey = exports.outStillName = exports.outName = exports.MINIMUM_FRAMES_PER_FUNCTION = exports.expiryDays = exports.customOutName = exports.artifactName = void 0;
18
+ exports.validateCodec = exports.validateDurationInFrames = exports.validateDimension = exports.validateFps = exports.serializeJSONWithSpecialTypes = exports.ENABLE_V5_BREAKING_CHANGES = exports.random = exports.interpolate = exports.validateWebhook = exports.validatePrivacy = void 0;
19
19
  const no_react_1 = require("remotion/no-react");
20
20
  Object.defineProperty(exports, "interpolate", { enumerable: true, get: function () { return no_react_1.interpolate; } });
21
21
  Object.defineProperty(exports, "random", { enumerable: true, get: function () { return no_react_1.random; } });
@@ -65,6 +65,8 @@ Object.defineProperty(exports, "estimatePriceFromMetadata", { enumerable: true,
65
65
  const expected_out_name_1 = require("./expected-out-name");
66
66
  Object.defineProperty(exports, "getCredentialsFromOutName", { enumerable: true, get: function () { return expected_out_name_1.getCredentialsFromOutName; } });
67
67
  Object.defineProperty(exports, "getExpectedOutName", { enumerable: true, get: function () { return expected_out_name_1.getExpectedOutName; } });
68
+ const find_output_file_in_bucket_1 = require("./find-output-file-in-bucket");
69
+ Object.defineProperty(exports, "findOutputFileInBucket", { enumerable: true, get: function () { return find_output_file_in_bucket_1.findOutputFileInBucket; } });
68
70
  const format_costs_info_1 = require("./format-costs-info");
69
71
  Object.defineProperty(exports, "formatCostsInfo", { enumerable: true, get: function () { return format_costs_info_1.formatCostsInfo; } });
70
72
  const get_or_create_bucket_1 = require("./get-or-create-bucket");
package/dist/progress.js CHANGED
@@ -5,6 +5,7 @@ const pure_1 = require("@remotion/renderer/pure");
5
5
  const calculate_chunk_times_1 = require("./calculate-chunk-times");
6
6
  const estimate_price_from_bucket_1 = require("./estimate-price-from-bucket");
7
7
  const expected_out_name_1 = require("./expected-out-name");
8
+ const find_output_file_in_bucket_1 = require("./find-output-file-in-bucket");
8
9
  const format_costs_info_1 = require("./format-costs-info");
9
10
  const get_overall_progress_1 = require("./get-overall-progress");
10
11
  const get_overall_progress_from_storage_1 = require("./get-overall-progress-from-storage");
@@ -14,7 +15,7 @@ const render_has_audio_video_1 = require("./render-has-audio-video");
14
15
  const truthy_1 = require("./truthy");
15
16
  const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region, memorySizeInMb, timeoutInMilliseconds, customCredentials, providerSpecifics, forcePathStyle, functionName, requestHandler, }) => {
16
17
  var _a;
17
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
18
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
18
19
  const overallProgress = await (0, get_overall_progress_from_storage_1.getOverallProgressFromStorage)({
19
20
  renderId,
20
21
  bucketName,
@@ -183,6 +184,81 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
183
184
  missingChunks.length > 0;
184
185
  // 2. If we have no missing chunks, but the encoding is not done, even after the additional `merge` function has been spawned, we consider it timed out
185
186
  const isBeyondTimeoutAndHasStitchTimeout = Date.now() > renderMetadata.startedDate + timeoutInMilliseconds * 2 + 20000;
187
+ const shouldCheckForCompletedOutput = allChunks &&
188
+ (isBeyondTimeoutAndHasStitchTimeout ||
189
+ (overallProgress.combinedFrames >= frameCount &&
190
+ overallProgress.timeToCombine !== null));
191
+ if (shouldCheckForCompletedOutput) {
192
+ const outputFile = await (0, find_output_file_in_bucket_1.findOutputFileInBucket)({
193
+ bucketName,
194
+ customCredentials,
195
+ renderMetadata,
196
+ region,
197
+ currentRegion: region,
198
+ providerSpecifics,
199
+ forcePathStyle,
200
+ requestHandler,
201
+ });
202
+ if (outputFile) {
203
+ const outData = (0, expected_out_name_1.getExpectedOutName)({
204
+ renderMetadata,
205
+ bucketName,
206
+ customCredentials,
207
+ bucketNamePrefix: providerSpecifics.getBucketPrefix(),
208
+ });
209
+ const now = Date.now();
210
+ const timeToFinishChunks = (0, calculate_chunk_times_1.calculateChunkTimes)({
211
+ type: 'absolute-time',
212
+ timings: overallProgress.timings,
213
+ });
214
+ return {
215
+ framesRendered: frameCount,
216
+ bucket: bucketName,
217
+ renderSize: (_q = outputFile.sizeInBytes) !== null && _q !== void 0 ? _q : 0,
218
+ chunks: renderMetadata.totalChunks,
219
+ cleanup: {
220
+ doneIn: null,
221
+ filesDeleted: 0,
222
+ minFilesToDelete: 0,
223
+ },
224
+ costs: priceFromBucket
225
+ ? (0, format_costs_info_1.formatCostsInfo)(priceFromBucket.accruedSoFar)
226
+ : (0, format_costs_info_1.formatCostsInfo)(0),
227
+ currentTime: now,
228
+ done: true,
229
+ encodingStatus: {
230
+ framesEncoded: frameCount,
231
+ combinedFrames: frameCount,
232
+ timeToCombine: overallProgress.timeToCombine,
233
+ },
234
+ errors: errorExplanations,
235
+ fatalErrorEncountered: false,
236
+ lambdasInvoked: renderMetadata.totalChunks,
237
+ outputFile: outputFile.url,
238
+ renderId,
239
+ timeToFinish: now - renderMetadata.startedDate,
240
+ timeToFinishChunks,
241
+ timeToRenderFrames: overallProgress.timeToRenderFrames,
242
+ overallProgress: 1,
243
+ retriesInfo: (_r = overallProgress.retries) !== null && _r !== void 0 ? _r : [],
244
+ outKey: outData.key,
245
+ outBucket: outData.renderBucketName,
246
+ mostExpensiveFrameRanges: null,
247
+ timeToEncode: overallProgress.timeToEncode,
248
+ outputSizeInBytes: (_s = outputFile.sizeInBytes) !== null && _s !== void 0 ? _s : 0,
249
+ type: 'success',
250
+ estimatedBillingDurationInMilliseconds: (_t = priceFromBucket === null || priceFromBucket === void 0 ? void 0 : priceFromBucket.estimatedBillingDurationInMilliseconds) !== null && _t !== void 0 ? _t : null,
251
+ timeToCombine: overallProgress.timeToCombine,
252
+ combinedFrames: frameCount,
253
+ renderMetadata,
254
+ timeoutTimestamp: overallProgress.timeoutTimestamp,
255
+ compositionValidated: overallProgress.compositionValidated,
256
+ functionLaunched: overallProgress.functionLaunched,
257
+ serveUrlOpened: overallProgress.serveUrlOpened,
258
+ artifacts: overallProgress.receivedArtifact,
259
+ };
260
+ }
261
+ }
186
262
  const allErrors = [
187
263
  isBeyondTimeoutAndMissingChunks || isBeyondTimeoutAndHasStitchTimeout
188
264
  ? (0, make_timeout_error_1.makeTimeoutError)({
@@ -198,7 +274,7 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
198
274
  ...errorExplanations,
199
275
  ].filter(truthy_1.truthy);
200
276
  return {
201
- framesRendered: (_q = overallProgress.framesRendered) !== null && _q !== void 0 ? _q : 0,
277
+ framesRendered: (_u = overallProgress.framesRendered) !== null && _u !== void 0 ? _u : 0,
202
278
  chunks: chunkCount,
203
279
  done: false,
204
280
  encodingStatus: {
@@ -219,7 +295,7 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
219
295
  fatalErrorEncountered: allErrors.some((f) => f.isFatal && !f.willRetry),
220
296
  currentTime: Date.now(),
221
297
  renderSize: 0,
222
- lambdasInvoked: (_r = overallProgress.lambdasInvoked) !== null && _r !== void 0 ? _r : 0,
298
+ lambdasInvoked: (_v = overallProgress.lambdasInvoked) !== null && _v !== void 0 ? _v : 0,
223
299
  cleanup,
224
300
  timeToFinishChunks: allChunks && overallProgress
225
301
  ? (0, calculate_chunk_times_1.calculateChunkTimes)({
@@ -229,17 +305,17 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
229
305
  : null,
230
306
  overallProgress: (0, get_overall_progress_1.getOverallProgress)({
231
307
  encoding: frameCount
232
- ? ((_s = overallProgress.framesEncoded) !== null && _s !== void 0 ? _s : 0) / frameCount
308
+ ? ((_w = overallProgress.framesEncoded) !== null && _w !== void 0 ? _w : 0) / frameCount
233
309
  : 0,
234
- invoking: ((_t = overallProgress.lambdasInvoked) !== null && _t !== void 0 ? _t : 0) /
310
+ invoking: ((_x = overallProgress.lambdasInvoked) !== null && _x !== void 0 ? _x : 0) /
235
311
  renderMetadata.estimatedRenderLambdaInvokations,
236
- frames: ((_u = overallProgress.framesRendered) !== null && _u !== void 0 ? _u : 0) / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
312
+ frames: ((_y = overallProgress.framesRendered) !== null && _y !== void 0 ? _y : 0) / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
237
313
  gotComposition: overallProgress.compositionValidated,
238
314
  visitedServeUrl: overallProgress.serveUrlOpened,
239
315
  invokedLambda: overallProgress.lambdasInvoked,
240
316
  combining: overallProgress.combinedFrames / (frameCount !== null && frameCount !== void 0 ? frameCount : 1),
241
317
  }),
242
- retriesInfo: (_v = overallProgress.retries) !== null && _v !== void 0 ? _v : [],
318
+ retriesInfo: (_z = overallProgress.retries) !== null && _z !== void 0 ? _z : [],
243
319
  outKey: null,
244
320
  outBucket: null,
245
321
  mostExpensiveFrameRanges: null,
@@ -248,8 +324,8 @@ const getProgress = async ({ bucketName, renderId, expectedBucketOwner, region,
248
324
  estimatedBillingDurationInMilliseconds: priceFromBucket
249
325
  ? priceFromBucket.estimatedBillingDurationInMilliseconds
250
326
  : null,
251
- combinedFrames: (_w = overallProgress.combinedFrames) !== null && _w !== void 0 ? _w : 0,
252
- timeToCombine: (_x = overallProgress.timeToCombine) !== null && _x !== void 0 ? _x : null,
327
+ combinedFrames: (_0 = overallProgress.combinedFrames) !== null && _0 !== void 0 ? _0 : 0,
328
+ timeToCombine: (_1 = overallProgress.timeToCombine) !== null && _1 !== void 0 ? _1 : null,
253
329
  timeoutTimestamp: overallProgress.timeoutTimestamp,
254
330
  type: 'success',
255
331
  compositionValidated: overallProgress.compositionValidated,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/serverless-client"
4
4
  },
5
5
  "name": "@remotion/serverless-client",
6
- "version": "4.0.471",
6
+ "version": "4.0.473",
7
7
  "main": "dist",
8
8
  "scripts": {
9
9
  "lint": "eslint src",
@@ -23,10 +23,10 @@
23
23
  },
24
24
  "dependencies": {},
25
25
  "devDependencies": {
26
- "remotion": "4.0.471",
27
- "@remotion/streaming": "4.0.471",
28
- "@remotion/renderer": "4.0.471",
29
- "@remotion/eslint-config-internal": "4.0.471",
26
+ "remotion": "4.0.473",
27
+ "@remotion/streaming": "4.0.473",
28
+ "@remotion/renderer": "4.0.473",
29
+ "@remotion/eslint-config-internal": "4.0.473",
30
30
  "eslint": "9.19.0",
31
31
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
32
32
  },