@hyperframes/aws-lambda 0.6.24 → 0.6.26

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.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/handler.ts
2
2
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, mkdtempSync, readFileSync, rmSync as rmSync2, statSync as statSync2 } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
- import { basename, join as join2 } from "node:path";
4
+ import { basename, join } from "node:path";
5
5
  import { S3Client } from "@aws-sdk/client-s3";
6
6
  import {
7
7
  assemble,
@@ -50,19 +50,14 @@ async function loadSparticuzChromium() {
50
50
  }
51
51
 
52
52
  // src/formatExtension.ts
53
+ var FORMAT_EXTENSIONS = {
54
+ mp4: ".mp4",
55
+ mov: ".mov",
56
+ webm: ".webm",
57
+ "png-sequence": ""
58
+ };
53
59
  function formatExtension(format) {
54
- switch (format) {
55
- case "mp4":
56
- return ".mp4";
57
- case "mov":
58
- return ".mov";
59
- case "png-sequence":
60
- return "";
61
- default: {
62
- const _exhaustive = format;
63
- throw new Error(`[formatExtension] unsupported format: ${_exhaustive}`);
64
- }
65
- }
60
+ return FORMAT_EXTENSIONS[format];
66
61
  }
67
62
 
68
63
  // src/s3Transport.ts
@@ -71,11 +66,10 @@ import {
71
66
  createWriteStream,
72
67
  existsSync as existsSync2,
73
68
  mkdirSync,
74
- readdirSync,
75
69
  rmSync,
76
70
  statSync
77
71
  } from "node:fs";
78
- import { dirname, join } from "node:path";
72
+ import { dirname } from "node:path";
79
73
  import { pipeline } from "node:stream/promises";
80
74
  import { GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
81
75
  import * as tar from "tar";
@@ -240,7 +234,7 @@ function primeRuntimeEnv() {
240
234
  if (runtimeEnvPrimed) return;
241
235
  runtimeEnvPrimed = true;
242
236
  const taskRoot = process.env.LAMBDA_TASK_ROOT ?? "/var/task";
243
- const bin = join2(taskRoot, "bin");
237
+ const bin = join(taskRoot, "bin");
244
238
  if (existsSync3(bin)) {
245
239
  process.env.PATH = `${bin}:${process.env.PATH ?? ""}`;
246
240
  }
@@ -249,10 +243,10 @@ async function handlePlan(event, deps) {
249
243
  const started = Date.now();
250
244
  const s3 = deps?.s3 ?? getS3Client();
251
245
  const primitive = deps?.primitives?.plan ?? plan;
252
- const work = mkdtempSync(join2(deps?.tmpRoot ?? tmpdir(), "hf-lambda-plan-"));
253
- const projectArchive = join2(work, "project.tar.gz");
254
- const projectDir = join2(work, "project");
255
- const planDir = join2(work, "plan");
246
+ const work = mkdtempSync(join(deps?.tmpRoot ?? tmpdir(), "hf-lambda-plan-"));
247
+ const projectArchive = join(work, "project.tar.gz");
248
+ const projectDir = join(work, "project");
249
+ const planDir = join(work, "plan");
256
250
  try {
257
251
  await downloadS3ObjectToFile(s3, event.ProjectS3Uri, projectArchive);
258
252
  await untarDirectory(projectArchive, projectDir);
@@ -260,10 +254,10 @@ async function handlePlan(event, deps) {
260
254
  ...event.Config
261
255
  };
262
256
  const result = await primitive(projectDir, config, planDir);
263
- const planTar = join2(work, "plan.tar.gz");
257
+ const planTar = join(work, "plan.tar.gz");
264
258
  await tarDirectory(planDir, planTar);
265
259
  const planTarUri = `${trimTrailingSlash(event.PlanOutputS3Prefix)}/plan.tar.gz`;
266
- const audioPath = join2(planDir, "audio.aac");
260
+ const audioPath = join(planDir, "audio.aac");
267
261
  const hasAudio = existsSync3(audioPath) && statSync2(audioPath).size > 0;
268
262
  const audioUri = hasAudio ? `${trimTrailingSlash(event.PlanOutputS3Prefix)}/audio.aac` : null;
269
263
  await Promise.all([
@@ -298,14 +292,14 @@ async function handleRenderChunk(event, deps) {
298
292
  const chromePath = await resolveChromeExecutablePath();
299
293
  process.env.PRODUCER_HEADLESS_SHELL_PATH = chromePath;
300
294
  }
301
- const work = mkdtempSync(join2(deps?.tmpRoot ?? tmpdir(), "hf-lambda-chunk-"));
302
- const planTar = join2(work, "plan.tar.gz");
303
- const planDir = join2(work, "plan");
295
+ const work = mkdtempSync(join(deps?.tmpRoot ?? tmpdir(), "hf-lambda-chunk-"));
296
+ const planTar = join(work, "plan.tar.gz");
297
+ const planDir = join(work, "plan");
304
298
  try {
305
299
  await downloadS3ObjectToFile(s3, event.PlanS3Uri, planTar);
306
300
  await untarDirectory(planTar, planDir);
307
301
  verifyPlanHash(planDir, event.PlanHash);
308
- const chunkOutputBase = join2(
302
+ const chunkOutputBase = join(
309
303
  work,
310
304
  event.Format === "png-sequence" ? `chunk-${pad(event.ChunkIndex)}` : `chunk-${pad(event.ChunkIndex)}${formatExtension(event.Format)}`
311
305
  );
@@ -346,19 +340,19 @@ async function handleAssemble(event, deps) {
346
340
  const started = Date.now();
347
341
  const s3 = deps?.s3 ?? getS3Client();
348
342
  const primitive = deps?.primitives?.assemble ?? assemble;
349
- const work = mkdtempSync(join2(deps?.tmpRoot ?? tmpdir(), "hf-lambda-assemble-"));
350
- const planTar = join2(work, "plan.tar.gz");
351
- const planDir = join2(work, "plan");
343
+ const work = mkdtempSync(join(deps?.tmpRoot ?? tmpdir(), "hf-lambda-assemble-"));
344
+ const planTar = join(work, "plan.tar.gz");
345
+ const planDir = join(work, "plan");
352
346
  try {
353
347
  await downloadS3ObjectToFile(s3, event.PlanS3Uri, planTar);
354
348
  await untarDirectory(planTar, planDir);
355
349
  const chunkPaths = await downloadChunkObjects(s3, event.ChunkS3Uris, work, event.Format);
356
350
  let audioPath = null;
357
351
  if (event.AudioS3Uri) {
358
- audioPath = join2(planDir, "audio.aac");
352
+ audioPath = join(planDir, "audio.aac");
359
353
  await downloadS3ObjectToFile(s3, event.AudioS3Uri, audioPath);
360
354
  }
361
- const finalOutput = event.Format === "png-sequence" ? join2(work, "output-frames") : join2(work, `output${formatExtension(event.Format)}`);
355
+ const finalOutput = event.Format === "png-sequence" ? join(work, "output-frames") : join(work, `output${formatExtension(event.Format)}`);
362
356
  const result = await primitive(planDir, chunkPaths, audioPath, finalOutput);
363
357
  if (event.Format === "png-sequence") {
364
358
  const tarball = `${finalOutput}.tar.gz`;
@@ -379,7 +373,7 @@ async function handleAssemble(event, deps) {
379
373
  }
380
374
  }
381
375
  async function downloadChunkObjects(s3, uris, workDir, format) {
382
- const chunksDir = join2(workDir, "chunks");
376
+ const chunksDir = join(workDir, "chunks");
383
377
  mkdirSync2(chunksDir, { recursive: true });
384
378
  const local = new Array(uris.length);
385
379
  await Promise.all(
@@ -388,10 +382,10 @@ async function downloadChunkObjects(s3, uris, workDir, format) {
388
382
  throw new Error(`[handler] chunk URI at index ${i} is empty`);
389
383
  }
390
384
  const { key } = parseS3Uri(uri);
391
- const localPath = join2(chunksDir, basename(key));
385
+ const localPath = join(chunksDir, basename(key));
392
386
  await downloadS3ObjectToFile(s3, uri, localPath);
393
387
  if (format === "png-sequence") {
394
- const dirPath = join2(chunksDir, `frames-${pad(i)}`);
388
+ const dirPath = join(chunksDir, `frames-${pad(i)}`);
395
389
  await untarDirectory(localPath, dirPath);
396
390
  local[i] = dirPath;
397
391
  } else {
@@ -414,7 +408,7 @@ function cleanupDir(dir) {
414
408
  }
415
409
  }
416
410
  function verifyPlanHash(planDir, expected) {
417
- const planJsonPath = join2(planDir, "plan.json");
411
+ const planJsonPath = join(planDir, "plan.json");
418
412
  let parsed;
419
413
  try {
420
414
  parsed = JSON.parse(readFileSync(planJsonPath, "utf-8"));
@@ -435,10 +429,10 @@ function verifyPlanHash(planDir, expected) {
435
429
  }
436
430
 
437
431
  // src/sdk/deploySite.ts
438
- import { mkdtempSync as mkdtempSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, rmSync as rmSync3, statSync as statSync3 } from "node:fs";
432
+ import { mkdtempSync as mkdtempSync2, readdirSync, readFileSync as readFileSync2, rmSync as rmSync3, statSync as statSync3 } from "node:fs";
439
433
  import { createHash } from "node:crypto";
440
434
  import { tmpdir as tmpdir2 } from "node:os";
441
- import { join as join3, relative } from "node:path";
435
+ import { join as join2, relative } from "node:path";
442
436
  import { HeadObjectCommand, S3Client as S3Client2 } from "@aws-sdk/client-s3";
443
437
  import { PLAN_PROJECT_DIR_SKIP_SEGMENTS } from "@hyperframes/producer/distributed";
444
438
  async function deploySite(opts) {
@@ -460,9 +454,9 @@ async function deploySite(opts) {
460
454
  uploaded: false
461
455
  };
462
456
  }
463
- const workdir = mkdtempSync2(join3(tmpdir2(), "hf-deploy-site-"));
457
+ const workdir = mkdtempSync2(join2(tmpdir2(), "hf-deploy-site-"));
464
458
  try {
465
- const tarball = join3(workdir, "project.tar.gz");
459
+ const tarball = join2(workdir, "project.tar.gz");
466
460
  await tarDirectory(opts.projectDir, tarball);
467
461
  const size = statSync3(tarball).size;
468
462
  await uploadFileToS3(s3, tarball, projectS3Uri, "application/gzip");
@@ -482,11 +476,11 @@ function hashProjectDir(projectDir) {
482
476
  const hash = createHash("sha256");
483
477
  const files = [];
484
478
  function walk(dir, isRoot) {
485
- for (const entry of readdirSync2(dir, { withFileTypes: true }).sort(
479
+ for (const entry of readdirSync(dir, { withFileTypes: true }).sort(
486
480
  (a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0
487
481
  )) {
488
482
  if (isRoot && PLAN_PROJECT_DIR_SKIP_SEGMENTS.has(entry.name)) continue;
489
- const full = join3(dir, entry.name);
483
+ const full = join2(dir, entry.name);
490
484
  if (entry.isDirectory()) walk(full, false);
491
485
  else if (entry.isFile()) files.push(full);
492
486
  }
@@ -531,7 +525,12 @@ var InvalidConfigError = class extends Error {
531
525
  }
532
526
  };
533
527
  var ALLOWED_FPS = [24, 30, 60];
534
- var ALLOWED_FORMATS = ["mp4", "mov", "png-sequence"];
528
+ var ALLOWED_FORMATS = [
529
+ "mp4",
530
+ "mov",
531
+ "png-sequence",
532
+ "webm"
533
+ ];
535
534
  var ALLOWED_CODECS = ["h264", "h265"];
536
535
  var ALLOWED_QUALITIES = ["draft", "standard", "high"];
537
536
  var ALLOWED_RUNTIME_CAPS = ["lambda", "temporal", "cloud-run-job", "k8s-job", "none"];