@yingyeothon/actor-system-lambda
v2.0.1
Published
AWS Lambda handler and shift-invoker glue for @yingyeothon/actor-system.
Readme
@yingyeothon/actor-system-lambda
AWS Lambda glue for @yingyeothon/actor-system: an API Gateway proxy handler that turns HTTP requests into actor messages, a Lambda handler that processes an actor's queue within the invocation's lifetime, and a shift function that hands remaining work to a fresh asynchronous Lambda invocation when the current one runs out of time.
Install
npm install @yingyeothon/actor-system-lambda @aws-sdk/client-lambda@aws-sdk/client-lambda is a peer dependency, used by createLambdaShift.
Usage
ESM:
import {
createActorAPIEventHandler,
createActorLambdaEventHandler,
createLambdaShift,
createTimeline,
} from "@yingyeothon/actor-system-lambda";
import { singleConsumer } from "@yingyeothon/actor-system";
// Shared actor options: queue/lock/awaiter come from your own
// subsystem (for example @yingyeothon/actor-system-redis).
const newActorEnv = (actorId: string) => ({
...singleConsumer,
...actorSubsys,
id: actorId,
onMessage: (message: { delta: number }) => applyDelta(message.delta),
shift: createLambdaShift({ functionName: "my-actor-worker" }),
});
// API Gateway entrypoint: enqueue the request body as an actor message
// and process the queue inline ("send") or leave it to a worker ("post").
export const api = createActorAPIEventHandler({
newActorEnv: (apiPath) => newActorEnv(apiPath.slice(1)),
policy: { type: "send" },
});
// Worker Lambda entrypoint: drain the actor's queue while this
// invocation is alive, then shift the rest to the next invocation.
// Pass a timeline to observe the remaining invocation lifetime.
const timeline = createTimeline();
export const worker = createActorLambdaEventHandler({
newActorEnv: ({ actorId }) => newActorEnv(actorId),
timeline,
});
// User code can check the remaining invocation lifetime at any point.
if (timeline.over) {
// wrap up quickly
}CJS:
const {
createActorLambdaEventHandler,
} = require("@yingyeothon/actor-system-lambda");
exports.handler = createActorLambdaEventHandler({ newActorEnv });Public API
createActorAPIEventHandler({ newActorEnv, parseMessage?, logger?, policy })— builds anAPIGatewayProxyHandlerthat parses the request body (defaultJSON.parse) into a message for the actor returned bynewActorEnv(apiPath, event).policy.type: "send"processes the queue inline (default options: 5saliveMillis, one-shot, shiftable);policy.type: "post"only enqueues. Returns200 OK; throws on missing actor options, an empty body, or a falsy parsed message.createActorLambdaEventHandler({ newActorEnv, logger?, processOptions?, timeline? })— builds aHandler<LambdaPayload, void>that resets itstimeline(default lifetime 870s, orprocessOptions.aliveMillis) and runstryToProcesson the options fromnewActorEnv(event); by default a shiftable one-shot bounded by the remaining lifetime.timelinedefaults to a fresh timeline private to the handler; pass your own to observe the remaining lifetime.createLambdaShift({ functionName, functionVersion?, buildPayload?, client? })— returns anActorShiftthat invokesfunctionNamewithInvocationType: "Event"and payloadbuildPayload(actorId)(default{ actorId }, qualifier default$LATEST).createTimeline(timeoutMillis?)— creates aTimelinethat starts now (default timeout 5s).Timeline— tracks elapsed/remaining lifetime:reset(timeoutMillis?),epochMillis,timeoutMillis,passedMillis,remainMillis,over(type)ActorLambdaEvent—{ actorId: string }, the default worker invocation payload (type)ActorAPIEventHandlerOptions,ActorLambdaEventHandlerOptions,LambdaShiftOptions— options shapes of the factories above (types)
Every factory accepts an optional logger?: Logger (see @yingyeothon/logger) and defaults to nullLogger; the API and Lambda handlers fall back to the actor options' own logger when none is given.
Migrating from the legacy package
- The npm package was renamed:
@yingyeothon/actor-system-aws-lambda-support→@yingyeothon/actor-system-lambda. - Factory renames (they return handlers/functions rather than performing the work themselves):
handleActorAPIEvent→createActorAPIEventHandlerhandleActorLambdaEvent→createActorLambdaEventHandlershiftToNextLambda→createLambdaShift
- Options type renames:
ActorAPIEventHandlerArguments→ActorAPIEventHandlerOptions,ActorLambdaHandlerArguments→ActorLambdaEventHandlerOptions,ShiftToNextLambdaArguments→LambdaShiftOptions. Timelineis now an interface created withcreateTimeline(); the mutableglobalTimelinesingleton was removed. To watch the remaining lifetime, create a timeline and pass it asActorLambdaEventHandlerOptions.timeline(the handler still resets it at the start of every invocation).- The
loggeroption is now aLoggerfrom@yingyeothon/logger(withwarnandseverity), defaulting tonullLogger. - The package ships dual ESM/CJS with types; deep imports (
.../lib/handle/...) are no longer supported — import everything from the package root. createLambdaShiftaccepts an optionalclient: LambdaClient; by default one client is created percreateLambdaShiftcall and reused across shifts (the legacy version created a new client on every shift).createActorLambdaEventHandlervalidates the actor options before touching them and stringifies the event in itsNo actor enverror message.
