mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-05 00:56:23 +00:00
* feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe
Phase 6 of the distributed rendering plan: AWS Lambda turnkey adoption
(see DISTRIBUTED-RENDERING-PLAN.md §11 Phase 6 + §15).
This PR adds the new packages/aws-lambda/ workspace package that wraps
the OSS plan/renderChunk/assemble primitives in an AWS Lambda handler,
plus a build pipeline that bundles the handler + Chromium runtime +
ffmpeg into a deployable ZIP.
Architecture: ZIP deploy (not Docker image), Chrome via @sparticuz/chromium
with chrome-headless-shell fallback, dispatch on event.Action ∈ {plan,
renderChunk, assemble}.
The load-bearing concern — does @sparticuz/chromium's chrome-headless-shell
build honour CDP HeadlessExperimental.beginFrame? — is pinned by the new
scripts/probe-beginframe.ts regression guard. Probe boots the runtime
inside public.ecr.aws/lambda/nodejs:22, navigates to a static page, and
asserts beginFrame returns a PNG buffer. Verified locally + inside the
Docker container; both pass with hasDamage=true.
Sizes (sparticuz source): unzipped 157 MiB, zipped 99 MiB. Well under
the 240 MiB / 150 MiB in-house gates and the Lambda 250 MiB hard ceiling.
This is part of a stack of 8 PRs (3 in Phase 6a, 5 in Phase 6b); this is
PR 6.1.
* fix(lambda): address PR 878 review feedback
- Verify event.PlanHash against the untarred plan.json at the handler
boundary before invoking the producer primitive. Throws typed
PLAN_HASH_MISMATCH on divergence so Step Functions routes it as
non-retryable; previously the field was schema bloat the handler
ignored, leaving enforcement entirely inside the producer.
- Standardize on MiB throughout build-zip.ts, verify-zip-size.ts, and
the README. Lambda's hard ceiling is 250 MiB (AWS docs label "250 MB"
but use binary mebibytes); previously mixed units made the 248 MiB
budget look like a ~5 MB margin instead of the 2 MiB it actually is.
- stageChromeHeadlessShell now picks Chrome versions via numeric semver
comparison instead of lexicographic sort+reverse — the latter would
silently pick "99.x" over "131.x" once Chrome cached three-digit
majors that aren't width-aligned.
- Drop _setSparticuzChromiumForTests from the public index barrel.
Test-only DI seam imported directly from ./chromium.js in tests.
- Replace require("node:fs") inside walkSize() with the top-level fs
imports — file is ESM and the same module is already imported.
* docs(lambda): drop internal plan-doc refs from package README
* ci(windows): fix bun filter UNION bug excluding producer from Windows tests
`bun run --filter "!a" --filter "!b" test` composes as a UNION (any
package matching either negation runs), not an intersection. Effect:
@hyperframes/producer was still being tested on Windows even though
it's explicitly excluded — its regression harness (Docker + LFS golden
mp4 baselines) is Linux-only and was driving the 32min timeout.
Enumerate the packages we DO want to test instead.
56 lines
1.6 KiB
JSON
56 lines
1.6 KiB
JSON
{
|
|
"name": "@hyperframes/aws-lambda",
|
|
"version": "0.0.1",
|
|
"description": "AWS Lambda adapter for HyperFrames distributed rendering — Plan/RenderChunk/Assemble handler + ZIP bundling.",
|
|
"repository": {
|
|
"type": "git",
|
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
"directory": "packages/aws-lambda"
|
|
},
|
|
"files": [
|
|
"src/",
|
|
"scripts/",
|
|
"README.md"
|
|
],
|
|
"type": "module",
|
|
"main": "./src/index.ts",
|
|
"types": "./src/index.ts",
|
|
"exports": {
|
|
".": "./src/index.ts",
|
|
"./handler": "./src/handler.ts"
|
|
},
|
|
"publishConfig": {
|
|
"access": "public",
|
|
"registry": "https://registry.npmjs.org/"
|
|
},
|
|
"scripts": {
|
|
"build": "tsc --noEmit",
|
|
"build:zip": "tsx scripts/build-zip.ts",
|
|
"probe:beginframe": "tsx scripts/probe-beginframe.ts",
|
|
"probe:beginframe:docker": "docker build -f scripts/probe-beginframe.dockerfile -t hyperframes-lambda-probe:local ../.. && docker run --rm hyperframes-lambda-probe:local",
|
|
"test": "bun test",
|
|
"typecheck": "tsc --noEmit",
|
|
"verify:zip-size": "tsx scripts/verify-zip-size.ts"
|
|
},
|
|
"dependencies": {
|
|
"@aws-sdk/client-s3": "^3.700.0",
|
|
"@hyperframes/producer": "workspace:^",
|
|
"@sparticuz/chromium": "148.0.0",
|
|
"ffmpeg-static": "^5.2.0",
|
|
"ffprobe-static": "^3.1.0",
|
|
"puppeteer-core": "^24.39.1",
|
|
"tar": "^7.4.3"
|
|
},
|
|
"devDependencies": {
|
|
"@types/aws-lambda": "^8.10.146",
|
|
"@types/node": "^25.0.10",
|
|
"@types/tar": "^6.1.13",
|
|
"esbuild": "^0.25.12",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^5.7.2"
|
|
},
|
|
"engines": {
|
|
"node": ">=22"
|
|
}
|
|
}
|