@hyperframes/aws-lambda 0.6.80 → 0.6.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/events.d.ts CHANGED
@@ -15,7 +15,8 @@
15
15
  * inside Step Functions' history budget (under 200 bytes for chunk
16
16
  * results per §2.4).
17
17
  */
18
- import type { DistributedFormat, DistributedRenderConfig } from "@hyperframes/producer/distributed";
18
+ import type { DistributedFormat, SerializableDistributedRenderConfig } from "@hyperframes/producer/distributed";
19
+ export type { SerializableDistributedRenderConfig } from "@hyperframes/producer/distributed";
19
20
  /** Discriminator for the three roles the one Lambda image fulfills. */
20
21
  export type LambdaAction = "plan" | "renderChunk" | "assemble";
21
22
  /**
@@ -85,13 +86,6 @@ export interface AssembleEvent {
85
86
  */
86
87
  Cfr?: boolean;
87
88
  }
88
- /**
89
- * `DistributedRenderConfig` minus the runtime-only fields (`logger`,
90
- * `abortSignal`, `producerConfig`). The Step Functions event JSON cannot
91
- * carry function references; the handler reconstitutes the runtime fields
92
- * from Lambda environment + the AbortController it owns.
93
- */
94
- export type SerializableDistributedRenderConfig = Omit<DistributedRenderConfig, "logger" | "abortSignal" | "producerConfig">;
95
89
  /** Result of a `plan` invocation. Carries enough to size the Map(N) state. */
96
90
  export interface PlanLambdaResult {
97
91
  Action: "plan";
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAEpG,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,UAAU,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAE3B,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,MAAM,EAAE,mCAAmC,CAAC;CAC7C;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+FAA+F;IAC/F,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0FAA0F;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,MAAM,mCAAmC,GAAG,IAAI,CACpD,uBAAuB,EACvB,QAAQ,GAAG,aAAa,GAAG,gBAAgB,CAC5C,CAAC;AAIF,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,mCAAmC,EACpC,MAAM,mCAAmC,CAAC;AAE3C,YAAY,EAAE,mCAAmC,EAAE,MAAM,mCAAmC,CAAC;AAE7F,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,GAAG,UAAU,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,gBAAgB,GAChB,aAAa,GACb;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GACxB;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAE3B,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,YAAY,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,MAAM,EAAE,mCAAmC,CAAC;CAC7C;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,+FAA+F;IAC/F,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0FAA0F;IAC1F,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAID,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,uBAAuB,GAAG,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -488,12 +488,11 @@ function verifyPlanHash(planDir, expected) {
488
488
  }
489
489
 
490
490
  // src/sdk/deploySite.ts
491
- import { mkdtempSync as mkdtempSync2, readdirSync, readFileSync as readFileSync2, rmSync as rmSync3, statSync as statSync3 } from "node:fs";
492
- import { createHash } from "node:crypto";
491
+ import { mkdtempSync as mkdtempSync2, rmSync as rmSync3, statSync as statSync3 } from "node:fs";
493
492
  import { tmpdir as tmpdir2 } from "node:os";
494
- import { join as join2, relative } from "node:path";
493
+ import { join as join2 } from "node:path";
495
494
  import { HeadObjectCommand, S3Client as S3Client2 } from "@aws-sdk/client-s3";
496
- import { PLAN_PROJECT_DIR_SKIP_SEGMENTS } from "@hyperframes/producer/distributed";
495
+ import { hashProjectDir } from "@hyperframes/producer/distributed";
497
496
  async function deploySite(opts) {
498
497
  if (!statSync3(opts.projectDir).isDirectory()) {
499
498
  throw new Error(`[deploySite] projectDir is not a directory: ${opts.projectDir}`);
@@ -531,28 +530,6 @@ async function deploySite(opts) {
531
530
  rmSync3(workdir, { recursive: true, force: true });
532
531
  }
533
532
  }
534
- function hashProjectDir(projectDir) {
535
- const hash = createHash("sha256");
536
- const files = [];
537
- function walk(dir, isRoot) {
538
- for (const entry of readdirSync(dir, { withFileTypes: true }).sort(
539
- (a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0
540
- )) {
541
- if (isRoot && PLAN_PROJECT_DIR_SKIP_SEGMENTS.has(entry.name)) continue;
542
- const full = join2(dir, entry.name);
543
- if (entry.isDirectory()) walk(full, false);
544
- else if (entry.isFile()) files.push(full);
545
- }
546
- }
547
- walk(projectDir, true);
548
- for (const file of files) {
549
- const rel = relative(projectDir, file).replaceAll("\\", "/");
550
- hash.update(rel);
551
- hash.update("\0");
552
- hash.update(readFileSync2(file));
553
- }
554
- return hash.digest("hex").slice(0, 16);
555
- }
556
533
  async function headObject(s3, bucket, key) {
557
534
  try {
558
535
  const res = await s3.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
@@ -574,130 +551,12 @@ import { randomUUID } from "node:crypto";
574
551
  import { SFNClient, StartExecutionCommand } from "@aws-sdk/client-sfn";
575
552
 
576
553
  // src/sdk/validateConfig.ts
577
- var InvalidConfigError = class extends Error {
578
- // Read via Error.prototype.toString; fallow can't see it.
579
- // fallow-ignore-next-line unused-class-member
580
- name = "InvalidConfigError";
581
- /** Dotted JSON-pointer-ish path to the offending field, e.g. `config.fps`. */
582
- field;
583
- constructor(field, message) {
584
- super(`[validateConfig] ${field}: ${message}`);
585
- this.field = field;
586
- }
587
- };
588
- var ALLOWED_FPS = [24, 30, 60];
589
- var ALLOWED_FORMATS = [
590
- "mp4",
591
- "mov",
592
- "png-sequence",
593
- "webm"
594
- ];
595
- var ALLOWED_CODECS = ["h264", "h265"];
596
- var ALLOWED_QUALITIES = ["draft", "standard", "high"];
597
- var ALLOWED_RUNTIME_CAPS = ["lambda", "temporal", "cloud-run-job", "k8s-job", "none"];
598
- var ALLOWED_HDR_MODES = ["auto", "force-sdr"];
599
- var MAX_DIMENSION = 7680;
600
- var MIN_DIMENSION = 16;
601
- var MAX_CHUNK_SIZE = 3600;
602
- var MAX_PARALLEL_CHUNKS_CEILING = 256;
603
- function validateDistributedRenderConfig(config) {
604
- if (config === null || typeof config !== "object") {
605
- throw new InvalidConfigError("config", "must be an object");
606
- }
607
- if (!ALLOWED_FPS.includes(config.fps)) {
608
- throw new InvalidConfigError(
609
- "config.fps",
610
- `must be one of ${ALLOWED_FPS.join(", ")}; got ${String(config.fps)}`
611
- );
612
- }
613
- validateIntDimension("config.width", config.width);
614
- validateIntDimension("config.height", config.height);
615
- if (!ALLOWED_FORMATS.includes(config.format)) {
616
- throw new InvalidConfigError(
617
- "config.format",
618
- `must be one of ${ALLOWED_FORMATS.join(", ")}; got ${String(config.format)}`
619
- );
620
- }
621
- if (config.codec !== void 0) {
622
- if (config.format !== "mp4") {
623
- throw new InvalidConfigError(
624
- "config.codec",
625
- `is only valid with format="mp4"; got format=${String(config.format)}`
626
- );
627
- }
628
- if (!ALLOWED_CODECS.includes(config.codec)) {
629
- throw new InvalidConfigError(
630
- "config.codec",
631
- `must be one of ${ALLOWED_CODECS.join(", ")}; got ${String(config.codec)}`
632
- );
633
- }
634
- }
635
- if (config.quality !== void 0 && !ALLOWED_QUALITIES.includes(config.quality)) {
636
- throw new InvalidConfigError(
637
- "config.quality",
638
- `must be one of ${ALLOWED_QUALITIES.join(", ")}; got ${String(config.quality)}`
639
- );
640
- }
641
- if (config.crf !== void 0 && config.bitrate !== void 0) {
642
- throw new InvalidConfigError("config.crf", "is mutually exclusive with config.bitrate");
643
- }
644
- if (config.crf !== void 0 && (!Number.isInteger(config.crf) || config.crf < 0 || config.crf > 51)) {
645
- throw new InvalidConfigError("config.crf", `must be an integer in [0, 51]; got ${config.crf}`);
646
- }
647
- if (config.bitrate !== void 0 && !/^\d+(\.\d+)?[kKmM]?$/.test(config.bitrate)) {
648
- throw new InvalidConfigError(
649
- "config.bitrate",
650
- `must look like "10M" or "5000k"; got ${JSON.stringify(config.bitrate)}`
651
- );
652
- }
653
- if (config.chunkSize !== void 0) {
654
- if (!Number.isInteger(config.chunkSize) || config.chunkSize < 1) {
655
- throw new InvalidConfigError(
656
- "config.chunkSize",
657
- `must be a positive integer; got ${config.chunkSize}`
658
- );
659
- }
660
- if (config.chunkSize > MAX_CHUNK_SIZE) {
661
- throw new InvalidConfigError(
662
- "config.chunkSize",
663
- // Lambda 15-min cap leaves no useful headroom past ~3600 frames
664
- // at 4 fps capture-equivalent throughput; rejecting up front
665
- // avoids a 14-minute Plan-state retry storm.
666
- `must be \u2264 ${MAX_CHUNK_SIZE} (Lambda 15-min cap); got ${config.chunkSize}`
667
- );
668
- }
669
- }
670
- if (config.maxParallelChunks !== void 0) {
671
- if (!Number.isInteger(config.maxParallelChunks) || config.maxParallelChunks < 1) {
672
- throw new InvalidConfigError(
673
- "config.maxParallelChunks",
674
- `must be a positive integer; got ${config.maxParallelChunks}`
675
- );
676
- }
677
- if (config.maxParallelChunks > MAX_PARALLEL_CHUNKS_CEILING) {
678
- throw new InvalidConfigError(
679
- "config.maxParallelChunks",
680
- `must be \u2264 ${MAX_PARALLEL_CHUNKS_CEILING}; got ${config.maxParallelChunks}`
681
- );
682
- }
683
- }
684
- if (config.runtimeCap !== void 0 && !ALLOWED_RUNTIME_CAPS.includes(config.runtimeCap)) {
685
- throw new InvalidConfigError(
686
- "config.runtimeCap",
687
- `must be one of ${ALLOWED_RUNTIME_CAPS.join(", ")}; got ${String(config.runtimeCap)}`
688
- );
689
- }
690
- if (config.hdrMode !== void 0 && !ALLOWED_HDR_MODES.includes(config.hdrMode)) {
691
- throw new InvalidConfigError(
692
- "config.hdrMode",
693
- `distributed mode supports only ${ALLOWED_HDR_MODES.join(", ")}; got ${String(config.hdrMode)}`
694
- );
695
- }
696
- if (config.variables !== void 0) {
697
- validateVariablesPayload(config.variables);
698
- }
699
- return config;
700
- }
554
+ import { InvalidConfigError } from "@hyperframes/producer/distributed";
555
+ import {
556
+ InvalidConfigError as InvalidConfigError2,
557
+ validateDistributedRenderConfig,
558
+ validateVariablesPayload
559
+ } from "@hyperframes/producer/distributed";
701
560
  var MAX_STEP_FUNCTIONS_INPUT_BYTES = 256 * 1024;
702
561
  var LARGE_VARIABLES_DOCS_URL = "https://hyperframes.heygen.com/deploy/templates-on-lambda#working-with-large-variables";
703
562
  function validateStepFunctionsInputSize(input) {
@@ -724,84 +583,6 @@ function validateStepFunctionsInputSize(input) {
724
583
  );
725
584
  }
726
585
  }
727
- function validateVariablesPayload(value) {
728
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
729
- throw new InvalidConfigError(
730
- "config.variables",
731
- `must be a plain JSON object (got ${describeValue(value)})`
732
- );
733
- }
734
- walkVariables(value, "config.variables", /* @__PURE__ */ new WeakSet());
735
- }
736
- var LEAF_REJECTIONS = {
737
- // `JSON.stringify` silently drops `undefined` leaves — caller would never
738
- // notice their value isn't actually being sent.
739
- undefined: "undefined leaves are silently dropped by JSON.stringify \u2014 use null if you mean an absent value",
740
- function: "functions are not JSON-serializable",
741
- symbol: "Symbols are not JSON-serializable",
742
- bigint: "BigInt values throw at JSON.stringify \u2014 encode as a string if you need 64-bit integers"
743
- };
744
- function walkVariables(value, path, seen) {
745
- const t = typeof value;
746
- if (value === null || t === "string" || t === "boolean") return;
747
- if (t === "number") {
748
- if (!Number.isFinite(value)) {
749
- throw new InvalidConfigError(
750
- path,
751
- `non-finite numbers (NaN / Infinity) are not JSON-serializable; got ${String(value)}`
752
- );
753
- }
754
- return;
755
- }
756
- const leafReject = LEAF_REJECTIONS[t];
757
- if (leafReject !== void 0) {
758
- throw new InvalidConfigError(path, leafReject);
759
- }
760
- if (seen.has(value)) {
761
- throw new InvalidConfigError(
762
- path,
763
- "circular reference detected \u2014 JSON.stringify cannot serialize cycles"
764
- );
765
- }
766
- seen.add(value);
767
- if (Array.isArray(value)) {
768
- for (let i = 0; i < value.length; i++) {
769
- walkVariables(value[i], `${path}[${i}]`, seen);
770
- }
771
- return;
772
- }
773
- const proto = Object.getPrototypeOf(value);
774
- if (proto !== Object.prototype && proto !== null) {
775
- throw new InvalidConfigError(
776
- path,
777
- `non-plain objects are not supported (got ${describeValue(value)}); use a plain {\u2026} object`
778
- );
779
- }
780
- for (const key of Object.keys(value)) {
781
- walkVariables(value[key], `${path}.${key}`, seen);
782
- }
783
- }
784
- function describeValue(value) {
785
- if (value === null) return "null";
786
- if (Array.isArray(value)) return "array";
787
- if (typeof value !== "object") return typeof value;
788
- const ctorName = value.constructor?.name ?? "Object";
789
- return ctorName === "Object" ? "object" : ctorName;
790
- }
791
- function validateIntDimension(field, value) {
792
- if (typeof value !== "number" || !Number.isInteger(value)) {
793
- throw new InvalidConfigError(field, `must be an integer; got ${String(value)}`);
794
- }
795
- if (value < MIN_DIMENSION || value > MAX_DIMENSION) {
796
- throw new InvalidConfigError(
797
- field,
798
- `must be in [${MIN_DIMENSION}, ${MAX_DIMENSION}]; got ${value}`
799
- );
800
- }
801
- if (value % 2 !== 0) {
802
- throw new InvalidConfigError(field, `must be even (yuv420p constraint); got ${value}`);
803
- }
804
- }
805
586
 
806
587
  // src/sdk/renderToLambda.ts
807
588
  async function renderToLambda(opts) {
@@ -1130,7 +911,7 @@ function isTerminalFailure(status) {
1130
911
  }
1131
912
  export {
1132
913
  ChromeBinaryUnavailableError,
1133
- InvalidConfigError,
914
+ InvalidConfigError2 as InvalidConfigError,
1134
915
  computeRenderCost,
1135
916
  deploySite,
1136
917
  downloadS3ObjectToFile,