@hyperframes/aws-lambda 0.6.25 → 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/events.d.ts +4 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/formatExtension.d.ts +2 -1
- package/dist/formatExtension.d.ts.map +1 -1
- package/dist/handler.js +29 -35
- package/dist/handler.js.map +3 -3
- package/dist/index.js +41 -42
- package/dist/index.js.map +3 -3
- package/dist/s3Transport.d.ts +0 -2
- package/dist/s3Transport.d.ts.map +1 -1
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.d.ts.map +1 -1
- package/dist/sdk/index.js +20 -21
- package/dist/sdk/index.js.map +3 -3
- package/dist/sdk/validateConfig.d.ts +3 -2
- package/dist/sdk/validateConfig.d.ts.map +1 -1
- package/package.json +2 -2
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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(
|
|
253
|
-
const projectArchive =
|
|
254
|
-
const projectDir =
|
|
255
|
-
const planDir =
|
|
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 =
|
|
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 =
|
|
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(
|
|
302
|
-
const planTar =
|
|
303
|
-
const planDir =
|
|
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 =
|
|
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(
|
|
350
|
-
const planTar =
|
|
351
|
-
const planDir =
|
|
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 =
|
|
352
|
+
audioPath = join(planDir, "audio.aac");
|
|
359
353
|
await downloadS3ObjectToFile(s3, event.AudioS3Uri, audioPath);
|
|
360
354
|
}
|
|
361
|
-
const finalOutput = event.Format === "png-sequence" ?
|
|
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 =
|
|
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 =
|
|
385
|
+
const localPath = join(chunksDir, basename(key));
|
|
392
386
|
await downloadS3ObjectToFile(s3, uri, localPath);
|
|
393
387
|
if (format === "png-sequence") {
|
|
394
|
-
const dirPath =
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
457
|
+
const workdir = mkdtempSync2(join2(tmpdir2(), "hf-deploy-site-"));
|
|
464
458
|
try {
|
|
465
|
-
const tarball =
|
|
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
|
|
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 =
|
|
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 = [
|
|
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"];
|