Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ jobs:
publish_pkg "@hyperframes/producer" "@hyperframes/producer"
publish_pkg "@hyperframes/shader-transitions" "@hyperframes/shader-transitions"
publish_pkg "@hyperframes/studio" "@hyperframes/studio"
publish_pkg "@hyperframes/aws-lambda" "@hyperframes/aws-lambda"

# CLI is @hyperframes/cli in the monorepo but published as unscoped "hyperframes" on npm.
# Rewrite the name in package.json before publishing, then use npm publish directly
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"type": "module",
"scripts": {
"dev": "bun run studio",
"build": "bun run --filter @hyperframes/core build && bun run --filter '@hyperframes/{core,engine,producer,player,studio,shader-transitions}' build && bun run --filter @hyperframes/cli build",
"build": "bun run --filter @hyperframes/core build && bun run --filter '@hyperframes/{core,engine,producer,player,studio,shader-transitions,aws-lambda}' build && bun run --filter @hyperframes/cli build",
"build:producer": "bun run --filter @hyperframes/producer build",
"studio": "bun run --filter @hyperframes/studio dev",
"build:hyperframes-runtime": "bun run --filter @hyperframes/core build:hyperframes-runtime",
Expand Down
62 changes: 62 additions & 0 deletions packages/aws-lambda/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env node
/**
* Build script for @hyperframes/aws-lambda (public OSS package).
*
* Bundles each subpath barrel via esbuild → dist/, then emits .d.ts via tsc.
*
* Subpaths (each gets its own dist entry so adopters that import one path
* don't load the others' transitive graphs at module-load time):
*
* . (the umbrella barrel: handler + sdk + cdk types re-exported)
* ./handler (the Lambda runtime entry — what `scripts/build-zip.ts` ZIPs)
* ./sdk (client-side helpers — AWS-SDK only, no chromium/puppeteer)
* ./cdk (CDK L2 construct — aws-cdk-lib is a peer dep)
*
* All production deps and peer deps are kept external so consumers resolve
* them via their own node_modules.
*/

import { build } from "esbuild";
import { execSync } from "node:child_process";
import { mkdirSync, rmSync } from "node:fs";

rmSync("dist", { recursive: true, force: true });
mkdirSync("dist", { recursive: true });

const sharedOpts = {
bundle: true,
platform: "node",
target: "node22",
format: "esm",
minify: false,
sourcemap: true,
external: [
"@aws-sdk/client-s3",
"@aws-sdk/client-sfn",
"@hyperframes/producer",
"@hyperframes/producer/distributed",
"@sparticuz/chromium",
"aws-cdk-lib",
"constructs",
"ffmpeg-static",
"ffprobe-static",
"puppeteer-core",
"tar",
],
};

await Promise.all([
build({ ...sharedOpts, entryPoints: ["src/index.ts"], outfile: "dist/index.js" }),
build({ ...sharedOpts, entryPoints: ["src/handler.ts"], outfile: "dist/handler.js" }),
build({ ...sharedOpts, entryPoints: ["src/sdk/index.ts"], outfile: "dist/sdk/index.js" }),
build({ ...sharedOpts, entryPoints: ["src/cdk/index.ts"], outfile: "dist/cdk/index.js" }),
]);

// esbuild doesn't emit .d.ts. tsc does, with a build-only tsconfig that
// drops the workspace `paths` overrides so `@hyperframes/producer` resolves
// through node_modules to the sibling package's already-built `dist/`
// types instead of pulling its full source tree into emit (which would
// violate rootDir).
execSync("tsc -p tsconfig.build.json --emitDeclarationOnly", { stdio: "inherit" });

console.log("[Build] Complete: dist/{index,handler,sdk/index,cdk/index}.js + .d.ts");
30 changes: 21 additions & 9 deletions packages/aws-lambda/package.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
{
"name": "@hyperframes/aws-lambda",
"version": "0.0.1",
"version": "0.6.20",
"description": "AWS Lambda adapter for HyperFrames distributed rendering — handler, client-side SDK, and CDK construct.",
"repository": {
"type": "git",
"url": "https://github.com/heygen-com/hyperframes",
"directory": "packages/aws-lambda"
},
"files": [
"src/",
"dist/",
"scripts/",
"README.md"
],
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": "./src/index.ts",
"./handler": "./src/handler.ts",
"./sdk": "./src/sdk/index.ts",
"./cdk": "./src/cdk/index.ts"
".": {
"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"
}
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"build": "tsc --noEmit",
"build": "node build.mjs",
"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",
Expand Down
12 changes: 12 additions & 0 deletions packages/aws-lambda/tsconfig.build.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"paths": {},
"noEmit": false,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}
2 changes: 1 addition & 1 deletion packages/aws-lambda/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "src/**/*.test.ts", "scripts"]
"exclude": ["node_modules", "dist", "src/**/*.test.ts", "src/**/__fixtures__/**", "scripts"]
}
37 changes: 37 additions & 0 deletions packages/producer/src/regression-harness-lambda-local-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Public-facing types for `./regression-harness-lambda-local.ts`.
*
* Kept in its own file because the implementation imports
* `@hyperframes/aws-lambda`, which can't be resolved by producer's
* tsc emit pass until aws-lambda's own dist/ is built. Splitting the
* types out lets producer's regression harness reference the lambda
* adapter's shape without pulling the aws-lambda graph into producer's
* type-check pass.
*/

/** Inputs for {@link runLambdaLocalRender}. Same contract as `runDistributedSimulatedRender`. */
export interface RunLambdaLocalInput {
projectDir: string;
tempRoot: string;
renderedOutputPath: string;
fps: 24 | 30 | 60;
/**
* Width/height from the fixture's renderConfig. Forwarded directly to
* the Lambda event so this mode catches drift if the handler ever
* starts honouring `Config.width/height` for canvas sizing rather
* than reading the composition's `data-width`/`data-height`. The
* `distributed-simulated` mode hardcodes 1920×1080 because it
* bypasses the event-serialization boundary; lambda-local goes
* through it, which is the whole point.
*/
width: number;
height: number;
format: "mp4" | "mov" | "png-sequence";
codec?: "h264" | "h265";
chunkSize?: number;
maxParallelChunks?: number;
variables?: Record<string, unknown>;
}

/** Public signature of the dynamically-loaded `runLambdaLocalRender`. */
export type RunLambdaLocalRender = (input: RunLambdaLocalInput) => Promise<void>;
25 changes: 2 additions & 23 deletions packages/producer/src/regression-harness-lambda-local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,29 +46,8 @@ import type {
SerializableDistributedRenderConfig,
} from "@hyperframes/aws-lambda";

/** Inputs for {@link runLambdaLocalRender}. Same contract as `runDistributedSimulatedRender`. */
export interface RunLambdaLocalInput {
projectDir: string;
tempRoot: string;
renderedOutputPath: string;
fps: 24 | 30 | 60;
/**
* Width/height from the fixture's renderConfig. Forwarded directly to
* the Lambda event so this mode catches drift if the handler ever
* starts honouring `Config.width/height` for canvas sizing rather
* than reading the composition's `data-width`/`data-height`. The
* `distributed-simulated` mode hardcodes 1920×1080 because it
* bypasses the event-serialization boundary; lambda-local goes
* through it, which is the whole point.
*/
width: number;
height: number;
format: "mp4" | "mov" | "png-sequence";
codec?: "h264" | "h265";
chunkSize?: number;
maxParallelChunks?: number;
variables?: Record<string, unknown>;
}
export type { RunLambdaLocalInput } from "./regression-harness-lambda-local-types.js";
import type { RunLambdaLocalInput } from "./regression-harness-lambda-local-types.js";

const FAKE_BUCKET = "harness-lambda-local";

Expand Down
25 changes: 21 additions & 4 deletions packages/producer/src/regression-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,27 @@ import {
// In Dockerfile.test the workspace copy of aws-lambda's src isn't present,
// so a static import here would fail at module-load time even when
// running `--mode=in-process`. Load it on demand instead.
async function loadLambdaLocalRender(): Promise<
typeof import("./regression-harness-lambda-local.js").runLambdaLocalRender
> {
const mod = await import("./regression-harness-lambda-local.js");
//
// The signature is typed via `RunLambdaLocalRender` (in its own types-only
// file) instead of `typeof import(...)` so producer's tsc doesn't have to
// type-check the implementation. The implementation imports
// `@hyperframes/aws-lambda`, whose types come from `dist/index.d.ts` after
// aws-lambda's build runs — a chicken-and-egg with producer's tsc that
// would otherwise fail the whole-repo build.
//
// The dynamic import path is indirected through a variable so tsc can't
// statically resolve the target file. Without this indirection tsc still
// pulls `regression-harness-lambda-local.ts` (and its `@hyperframes/aws-lambda`
// imports) into the program even though the tsconfig `exclude` list
// nominally hides it. `tsx` resolves the path normally at runtime.
import type { RunLambdaLocalRender } from "./regression-harness-lambda-local-types.js";

const LAMBDA_LOCAL_MODULE = "./regression-harness-lambda-local.js";

async function loadLambdaLocalRender(): Promise<RunLambdaLocalRender> {
const mod = (await import(LAMBDA_LOCAL_MODULE)) as {
runLambdaLocalRender: RunLambdaLocalRender;
};
return mod.runLambdaLocalRender;
}

Expand Down
8 changes: 7 additions & 1 deletion packages/producer/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,11 @@
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "src/**/*.test.ts", "src/**/__test_utils__/**"]
"exclude": [
"node_modules",
"dist",
"src/**/*.test.ts",
"src/**/__test_utils__/**",
"src/regression-harness-lambda-local.ts"
]
}
1 change: 1 addition & 0 deletions scripts/set-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const PACKAGES = [
"packages/shader-transitions",
"packages/studio",
"packages/cli",
"packages/aws-lambda",
];

const ROOT = join(import.meta.dirname, "..");
Expand Down
Loading