Files
heygen-com__hyperframes/packages/aws-lambda/package.json
T

108 lines
2.8 KiB
JSON
Raw Normal View History

feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
{
"name": "@hyperframes/aws-lambda",
2026-08-11 16:19:20 -04:00
"version": "0.7.107",
feat(lambda): add TypeScript SDK and CDK construct (#909) * feat(lambda): add TypeScript SDK and CDK construct Adds the client-side surface on top of the Phase 6a Lambda handler so adopters can drive a deployed stack from Node without writing AWS-SDK boilerplate: - renderToLambda(opts) starts a Step Functions execution and returns a handle. Does NOT poll. - getRenderProgress({ executionArn }) returns a snapshot of progress, frames rendered, cost (Lambda GB-seconds + SFN transitions), errors, and the final output object once Assemble completes. - deploySite({ projectDir, bucketName }) content-addresses the project tree, tar.gzs it, and uploads to S3 with a HeadObject short-circuit so re-renders of the same tree skip the tar+PUT. - validateDistributedRenderConfig throws a typed InvalidConfigError before StartExecution, so shape errors surface synchronously. - computeRenderCost is exposed for callers who want to format cost out of band. Also ships HyperframesRenderStack, an aws-cdk-lib L2 construct that emits the same topology as examples/aws-lambda/template.yaml. Lives on the ./cdk subpath export so SDK-only consumers don't pull aws-cdk-lib into their runtime graph (declared as an optional peer dependency). Tests: 24 new unit tests across the SDK plus 9 CDK synth / contract / snapshot tests. All 83 tests in packages/aws-lambda/src pass. * refactor(lambda): /simplify pass on the SDK + CDK PR Pulls shared logic out so the SDK doesn't re-invent things the handler and the producer already have: - `formatExtension` extracted to packages/aws-lambda/src/formatExtension.ts. handler.ts and renderToLambda.ts both used identical 12-line copies of this switch. - `PLAN_PROJECT_DIR_SKIP_SEGMENTS` is now exported from @hyperframes/producer/distributed. deploySite consumes it instead of its own duplicate SKIP_TOP_LEVEL set; the two lists were trivially identical and would have drifted silently. - `FakeS3` + `drainBody` factored out of the two SDK test files into src/sdk/__fixtures__/fakeS3.ts. Drops ~110 lines of test-file duplication and gives future SDK tests a one-line FakeS3 import. - S3 URI building in deploySite and renderToLambda routes through the existing `formatS3Uri` helper instead of inline `s3://...` concatenation; matches the convention already in handler.ts. Net -133 lines across the touched files. All 83 aws-lambda tests still pass; all 60 producer distributed tests still pass. * fix(lambda): bump CDK test timeouts for CI cold-start synth The bun:test default 5s timeout tripped the first CDK snapshot test in CI when the cold-start `Template.fromStack(stack)` synth took ~5-8s on the slowest GitHub Actions runner. Locally on a warm shell the synth measures <1s, so the failure didn't reproduce until PR #909 hit CI. Two changes: - Both CDK test files cache one synth in `beforeAll(..., 30000)` and reuse the result across every test that uses the default props. Each individual test now runs in microseconds (pure assertions against the already-synthed template), so the 5s timeout no longer applies on the hot path. - The two contract tests that exercise non-default props (reservedConcurrency, projectName) still synth fresh per-test; they get a per-test `it(..., 30000)` timeout. No behavior changes. * fix(lambda): address PR review on SDK + CDK construct Three correctness + ergonomics fixes raised in Vai's review: - getRenderProgress over-counted SFN transitions by 3-5×. Step Functions Standard Workflows bill per state-entry, not per history event. Each Task produces ~5-7 history events (Scheduled / Started / Succeeded / TaskStateExited / …); counting `events.length` reported the runaway. Switch to counting `*StateEntered` events explicitly. - assembleComplete + outputFile detection was coupled to the Lambda payload's `Action` field. Move both signals onto the enclosing state name (`StateExited.name === "Assemble"`), which is the state-machine identity rather than the Lambda event contract. framesRendered increment moves to the same boundary (RenderChunk state). - SiteHandle now carries `bucketName` directly so README + CLI callers don't have to re-parse `projectS3Uri.split("/")[2]`. Test updates: getRenderProgress tests wrap renderChunk/assemble events in matching StateEntered + StateExited pairs so the new state-name-driven dispatch is exercised end-to-end. SiteHandle fixture in renderToLambda.test.ts gets the new bucketName field. All 83 aws-lambda tests still pass.
2026-05-17 03:03:51 -04:00
"description": "AWS Lambda adapter for HyperFrames distributed rendering — handler, client-side SDK, and CDK construct.",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"repository": {
"type": "git",
"url": "https://github.com/heygen-com/hyperframes",
"directory": "packages/aws-lambda"
},
"files": [
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
"dist/",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"scripts/",
"README.md"
],
"type": "module",
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"exports": {
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
".": {
"bun": "./src/index.ts",
"import": "./src/index.ts",
"types": "./src/index.ts"
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
},
"./handler": {
"bun": "./src/handler.ts",
"import": "./src/handler.ts",
"types": "./src/handler.ts"
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
},
"./sdk": {
"bun": "./src/sdk/index.ts",
"import": "./src/sdk/index.ts",
"types": "./src/sdk/index.ts"
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
},
"./cdk": {
"bun": "./src/cdk/index.ts",
"import": "./src/cdk/index.ts",
"types": "./src/cdk/index.ts"
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
}
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
},
"publishConfig": {
"access": "public",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./handler": {
"import": "./dist/handler.js",
"types": "./dist/handler.d.ts"
},
"./sdk": {
"import": "./dist/sdk/index.js",
"types": "./dist/sdk/index.d.ts"
},
"./cdk": {
"import": "./dist/cdk/index.js",
"types": "./dist/cdk/index.d.ts"
}
},
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"registry": "https://registry.npmjs.org/"
},
"scripts": {
chore(lambda): publish-readiness for @hyperframes/aws-lambda The Lambda adapter has been on `main` since PR #909 but its package manifest still shipped TypeScript source (`main: ./src/index.ts`, `build: tsc --noEmit`, `version: 0.0.1`) and the publish workflow didn't list it. This wires it up to publish alongside the other `@hyperframes/*` packages on the next `v*` tag. Changes: - **packages/aws-lambda/build.mjs (new)** — mirrors `packages/producer/build.mjs`: esbuild bundles four entry points (`src/index.ts`, `src/handler.ts`, `src/sdk/index.ts`, `src/cdk/index.ts`) → `dist/`, then `tsc --emitDeclarationOnly` emits .d.ts via `tsconfig.build.json`. All runtime/peer deps (@aws-sdk/*, @hyperframes/producer*, @sparticuz/chromium, aws-cdk-lib, constructs, ffmpeg-static, ffprobe-static, puppeteer-core, tar) are external so consumers resolve them through their own node_modules. - **packages/aws-lambda/tsconfig.build.json (new)** — drops the workspace `paths` overrides so `@hyperframes/producer*` resolves through node_modules to producer's already-built `dist/` types instead of pulling its full source tree into emit (which would violate `rootDir`). - **packages/aws-lambda/tsconfig.json** — keeps `noEmit: true` + workspace `paths` for fast in-place typechecks; also excludes `src/**/__fixtures__/**` so test-only helpers (fakeS3) don't leak into emitted declarations. - **packages/aws-lambda/package.json**: * version bumped 0.0.1 → 0.6.18 (matches the repo's lockstep release cadence) * main / types / exports map points at `dist/...` * files: ["dist/", "scripts/", "README.md"] (scripts/ kept whole because build-zip.ts and verify-zip-size.ts both import scripts/_formatBytes.ts) * scripts.build = `node build.mjs` - **package.json** — root `build` filter includes `aws-lambda` so `bun run build` builds it in topological order after producer. - **.github/workflows/publish.yml** — one new `publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"` line. First publish is automatic via the `--access public` flag in `publish_pkg`; the @hyperframes scope already owns the name. Verification: bun run build # full root build green bun run verify:packed-manifests # aws-lambda passes pnpm pack packages/cli # @hyperframes/aws-lambda # rewrites workspace:* → 0.6.18 npm install -g <cli-tgz> # smoke-install still works hyperframes lambda deploy # friendly missing-package # error still fires when # aws-lambda isn't installed
2026-05-17 19:16:56 +00:00
"build": "node build.mjs",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"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",
feat(lambda): add TypeScript SDK and CDK construct (#909) * feat(lambda): add TypeScript SDK and CDK construct Adds the client-side surface on top of the Phase 6a Lambda handler so adopters can drive a deployed stack from Node without writing AWS-SDK boilerplate: - renderToLambda(opts) starts a Step Functions execution and returns a handle. Does NOT poll. - getRenderProgress({ executionArn }) returns a snapshot of progress, frames rendered, cost (Lambda GB-seconds + SFN transitions), errors, and the final output object once Assemble completes. - deploySite({ projectDir, bucketName }) content-addresses the project tree, tar.gzs it, and uploads to S3 with a HeadObject short-circuit so re-renders of the same tree skip the tar+PUT. - validateDistributedRenderConfig throws a typed InvalidConfigError before StartExecution, so shape errors surface synchronously. - computeRenderCost is exposed for callers who want to format cost out of band. Also ships HyperframesRenderStack, an aws-cdk-lib L2 construct that emits the same topology as examples/aws-lambda/template.yaml. Lives on the ./cdk subpath export so SDK-only consumers don't pull aws-cdk-lib into their runtime graph (declared as an optional peer dependency). Tests: 24 new unit tests across the SDK plus 9 CDK synth / contract / snapshot tests. All 83 tests in packages/aws-lambda/src pass. * refactor(lambda): /simplify pass on the SDK + CDK PR Pulls shared logic out so the SDK doesn't re-invent things the handler and the producer already have: - `formatExtension` extracted to packages/aws-lambda/src/formatExtension.ts. handler.ts and renderToLambda.ts both used identical 12-line copies of this switch. - `PLAN_PROJECT_DIR_SKIP_SEGMENTS` is now exported from @hyperframes/producer/distributed. deploySite consumes it instead of its own duplicate SKIP_TOP_LEVEL set; the two lists were trivially identical and would have drifted silently. - `FakeS3` + `drainBody` factored out of the two SDK test files into src/sdk/__fixtures__/fakeS3.ts. Drops ~110 lines of test-file duplication and gives future SDK tests a one-line FakeS3 import. - S3 URI building in deploySite and renderToLambda routes through the existing `formatS3Uri` helper instead of inline `s3://...` concatenation; matches the convention already in handler.ts. Net -133 lines across the touched files. All 83 aws-lambda tests still pass; all 60 producer distributed tests still pass. * fix(lambda): bump CDK test timeouts for CI cold-start synth The bun:test default 5s timeout tripped the first CDK snapshot test in CI when the cold-start `Template.fromStack(stack)` synth took ~5-8s on the slowest GitHub Actions runner. Locally on a warm shell the synth measures <1s, so the failure didn't reproduce until PR #909 hit CI. Two changes: - Both CDK test files cache one synth in `beforeAll(..., 30000)` and reuse the result across every test that uses the default props. Each individual test now runs in microseconds (pure assertions against the already-synthed template), so the 5s timeout no longer applies on the hot path. - The two contract tests that exercise non-default props (reservedConcurrency, projectName) still synth fresh per-test; they get a per-test `it(..., 30000)` timeout. No behavior changes. * fix(lambda): address PR review on SDK + CDK construct Three correctness + ergonomics fixes raised in Vai's review: - getRenderProgress over-counted SFN transitions by 3-5×. Step Functions Standard Workflows bill per state-entry, not per history event. Each Task produces ~5-7 history events (Scheduled / Started / Succeeded / TaskStateExited / …); counting `events.length` reported the runaway. Switch to counting `*StateEntered` events explicitly. - assembleComplete + outputFile detection was coupled to the Lambda payload's `Action` field. Move both signals onto the enclosing state name (`StateExited.name === "Assemble"`), which is the state-machine identity rather than the Lambda event contract. framesRendered increment moves to the same boundary (RenderChunk state). - SiteHandle now carries `bucketName` directly so README + CLI callers don't have to re-parse `projectS3Uri.split("/")[2]`. Test updates: getRenderProgress tests wrap renderChunk/assemble events in matching StateEntered + StateExited pairs so the new state-name-driven dispatch is exercised end-to-end. SiteHandle fixture in renderToLambda.test.ts gets the new bucketName field. All 83 aws-lambda tests still pass.
2026-05-17 03:03:51 -04:00
"@aws-sdk/client-sfn": "^3.700.0",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"@hyperframes/producer": "workspace:^",
"@sparticuz/chromium": "148.0.0",
"ffmpeg-static": "^5.2.0",
"ffprobe-static": "^3.1.0",
fix(engine,cli): resolve drawElement to a Chrome build that actually has it canvas.drawElementImage is an unlaunched Dev/Canary-only Blink feature (~151+). The CLI's pinned CHROME_VERSION fallback was still 131.0.6778.85 — a puppeteer 24→25.2.1 bump that pinned it to Chrome Dev 151.0.7912.0 was written on 2026-06-29 but never merged (orphaned local commit, no PR). Any render on that pin, or on the shared puppeteer-cache binary, or on system Chrome (Stable, no drawElementImage at all) got a canvas.getContext("2d") missing the method and crashed mid-capture with "ctx.drawElementImage is not a function" instead of falling back (HF#2060). Three changes: - Bump puppeteer/puppeteer-core to ^25.2.1 across every package that depends on it, and CHROME_VERSION to 152.0.7928.2 (today's Dev channel; confirmed via direct probe to implement drawElementImage, unlike 131). - `ensureBrowser({ preferManagedChrome: true })`, always used by `render`: resolve straight to our pinned/cached build, skipping both the shared puppeteer-cache preference and system Chrome. Rendering shouldn't depend on whatever arbitrary Chrome a machine happens to have — that's exactly how this regressed (any Mac with Chrome.app installed bypassed the CLI's pin entirely). - A runtime capability probe in the engine, right before any other drawElement work: if `drawElementImage` isn't a function on the injected canvas, route to the existing screenshot-fallback gate instead of crashing. This is the real backstop — it protects every resolution path (env override, stale cache entry, a future Chrome regression), not just the ones `preferManagedChrome` reaches. Verified end-to-end: rendering against chrome-headless-shell 131 (confirmed to lack drawElementImage) now falls back cleanly and produces a valid MP4 instead of crashing; rendering against a capable build still engages drawElement normally. 922 engine tests + 1373 CLI tests pass. Fixes #2060.
2026-07-08 14:14:28 -07:00
"puppeteer-core": "^25.2.1",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"tar": "^7.4.3"
},
"devDependencies": {
"@types/aws-lambda": "^8.10.146",
"@types/node": "^25.0.10",
"@types/tar": "^6.1.13",
feat(lambda): add TypeScript SDK and CDK construct (#909) * feat(lambda): add TypeScript SDK and CDK construct Adds the client-side surface on top of the Phase 6a Lambda handler so adopters can drive a deployed stack from Node without writing AWS-SDK boilerplate: - renderToLambda(opts) starts a Step Functions execution and returns a handle. Does NOT poll. - getRenderProgress({ executionArn }) returns a snapshot of progress, frames rendered, cost (Lambda GB-seconds + SFN transitions), errors, and the final output object once Assemble completes. - deploySite({ projectDir, bucketName }) content-addresses the project tree, tar.gzs it, and uploads to S3 with a HeadObject short-circuit so re-renders of the same tree skip the tar+PUT. - validateDistributedRenderConfig throws a typed InvalidConfigError before StartExecution, so shape errors surface synchronously. - computeRenderCost is exposed for callers who want to format cost out of band. Also ships HyperframesRenderStack, an aws-cdk-lib L2 construct that emits the same topology as examples/aws-lambda/template.yaml. Lives on the ./cdk subpath export so SDK-only consumers don't pull aws-cdk-lib into their runtime graph (declared as an optional peer dependency). Tests: 24 new unit tests across the SDK plus 9 CDK synth / contract / snapshot tests. All 83 tests in packages/aws-lambda/src pass. * refactor(lambda): /simplify pass on the SDK + CDK PR Pulls shared logic out so the SDK doesn't re-invent things the handler and the producer already have: - `formatExtension` extracted to packages/aws-lambda/src/formatExtension.ts. handler.ts and renderToLambda.ts both used identical 12-line copies of this switch. - `PLAN_PROJECT_DIR_SKIP_SEGMENTS` is now exported from @hyperframes/producer/distributed. deploySite consumes it instead of its own duplicate SKIP_TOP_LEVEL set; the two lists were trivially identical and would have drifted silently. - `FakeS3` + `drainBody` factored out of the two SDK test files into src/sdk/__fixtures__/fakeS3.ts. Drops ~110 lines of test-file duplication and gives future SDK tests a one-line FakeS3 import. - S3 URI building in deploySite and renderToLambda routes through the existing `formatS3Uri` helper instead of inline `s3://...` concatenation; matches the convention already in handler.ts. Net -133 lines across the touched files. All 83 aws-lambda tests still pass; all 60 producer distributed tests still pass. * fix(lambda): bump CDK test timeouts for CI cold-start synth The bun:test default 5s timeout tripped the first CDK snapshot test in CI when the cold-start `Template.fromStack(stack)` synth took ~5-8s on the slowest GitHub Actions runner. Locally on a warm shell the synth measures <1s, so the failure didn't reproduce until PR #909 hit CI. Two changes: - Both CDK test files cache one synth in `beforeAll(..., 30000)` and reuse the result across every test that uses the default props. Each individual test now runs in microseconds (pure assertions against the already-synthed template), so the 5s timeout no longer applies on the hot path. - The two contract tests that exercise non-default props (reservedConcurrency, projectName) still synth fresh per-test; they get a per-test `it(..., 30000)` timeout. No behavior changes. * fix(lambda): address PR review on SDK + CDK construct Three correctness + ergonomics fixes raised in Vai's review: - getRenderProgress over-counted SFN transitions by 3-5×. Step Functions Standard Workflows bill per state-entry, not per history event. Each Task produces ~5-7 history events (Scheduled / Started / Succeeded / TaskStateExited / …); counting `events.length` reported the runaway. Switch to counting `*StateEntered` events explicitly. - assembleComplete + outputFile detection was coupled to the Lambda payload's `Action` field. Move both signals onto the enclosing state name (`StateExited.name === "Assemble"`), which is the state-machine identity rather than the Lambda event contract. framesRendered increment moves to the same boundary (RenderChunk state). - SiteHandle now carries `bucketName` directly so README + CLI callers don't have to re-parse `projectS3Uri.split("/")[2]`. Test updates: getRenderProgress tests wrap renderChunk/assemble events in matching StateEntered + StateExited pairs so the new state-name-driven dispatch is exercised end-to-end. SiteHandle fixture in renderToLambda.test.ts gets the new bucketName field. All 83 aws-lambda tests still pass.
2026-05-17 03:03:51 -04:00
"aws-cdk-lib": "^2.130.0",
"constructs": "^10.3.0",
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"esbuild": "^0.25.12",
"tsx": "^4.21.0",
"typescript": "^5.7.2",
"yaml": "^2.9.0"
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
},
feat(lambda): add TypeScript SDK and CDK construct (#909) * feat(lambda): add TypeScript SDK and CDK construct Adds the client-side surface on top of the Phase 6a Lambda handler so adopters can drive a deployed stack from Node without writing AWS-SDK boilerplate: - renderToLambda(opts) starts a Step Functions execution and returns a handle. Does NOT poll. - getRenderProgress({ executionArn }) returns a snapshot of progress, frames rendered, cost (Lambda GB-seconds + SFN transitions), errors, and the final output object once Assemble completes. - deploySite({ projectDir, bucketName }) content-addresses the project tree, tar.gzs it, and uploads to S3 with a HeadObject short-circuit so re-renders of the same tree skip the tar+PUT. - validateDistributedRenderConfig throws a typed InvalidConfigError before StartExecution, so shape errors surface synchronously. - computeRenderCost is exposed for callers who want to format cost out of band. Also ships HyperframesRenderStack, an aws-cdk-lib L2 construct that emits the same topology as examples/aws-lambda/template.yaml. Lives on the ./cdk subpath export so SDK-only consumers don't pull aws-cdk-lib into their runtime graph (declared as an optional peer dependency). Tests: 24 new unit tests across the SDK plus 9 CDK synth / contract / snapshot tests. All 83 tests in packages/aws-lambda/src pass. * refactor(lambda): /simplify pass on the SDK + CDK PR Pulls shared logic out so the SDK doesn't re-invent things the handler and the producer already have: - `formatExtension` extracted to packages/aws-lambda/src/formatExtension.ts. handler.ts and renderToLambda.ts both used identical 12-line copies of this switch. - `PLAN_PROJECT_DIR_SKIP_SEGMENTS` is now exported from @hyperframes/producer/distributed. deploySite consumes it instead of its own duplicate SKIP_TOP_LEVEL set; the two lists were trivially identical and would have drifted silently. - `FakeS3` + `drainBody` factored out of the two SDK test files into src/sdk/__fixtures__/fakeS3.ts. Drops ~110 lines of test-file duplication and gives future SDK tests a one-line FakeS3 import. - S3 URI building in deploySite and renderToLambda routes through the existing `formatS3Uri` helper instead of inline `s3://...` concatenation; matches the convention already in handler.ts. Net -133 lines across the touched files. All 83 aws-lambda tests still pass; all 60 producer distributed tests still pass. * fix(lambda): bump CDK test timeouts for CI cold-start synth The bun:test default 5s timeout tripped the first CDK snapshot test in CI when the cold-start `Template.fromStack(stack)` synth took ~5-8s on the slowest GitHub Actions runner. Locally on a warm shell the synth measures <1s, so the failure didn't reproduce until PR #909 hit CI. Two changes: - Both CDK test files cache one synth in `beforeAll(..., 30000)` and reuse the result across every test that uses the default props. Each individual test now runs in microseconds (pure assertions against the already-synthed template), so the 5s timeout no longer applies on the hot path. - The two contract tests that exercise non-default props (reservedConcurrency, projectName) still synth fresh per-test; they get a per-test `it(..., 30000)` timeout. No behavior changes. * fix(lambda): address PR review on SDK + CDK construct Three correctness + ergonomics fixes raised in Vai's review: - getRenderProgress over-counted SFN transitions by 3-5×. Step Functions Standard Workflows bill per state-entry, not per history event. Each Task produces ~5-7 history events (Scheduled / Started / Succeeded / TaskStateExited / …); counting `events.length` reported the runaway. Switch to counting `*StateEntered` events explicitly. - assembleComplete + outputFile detection was coupled to the Lambda payload's `Action` field. Move both signals onto the enclosing state name (`StateExited.name === "Assemble"`), which is the state-machine identity rather than the Lambda event contract. framesRendered increment moves to the same boundary (RenderChunk state). - SiteHandle now carries `bucketName` directly so README + CLI callers don't have to re-parse `projectS3Uri.split("/")[2]`. Test updates: getRenderProgress tests wrap renderChunk/assemble events in matching StateEntered + StateExited pairs so the new state-name-driven dispatch is exercised end-to-end. SiteHandle fixture in renderToLambda.test.ts gets the new bucketName field. All 83 aws-lambda tests still pass.
2026-05-17 03:03:51 -04:00
"peerDependencies": {
"aws-cdk-lib": "^2.130.0",
"constructs": "^10.3.0"
},
"peerDependenciesMeta": {
"aws-cdk-lib": {
"optional": true
},
"constructs": {
"optional": true
}
},
feat(lambda): add Lambda handler, ZIP bundling, and BeginFrame probe (#878) * 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.
2026-05-16 18:08:47 -04:00
"engines": {
"node": ">=22"
}
}