in statefun-sdk-js/src/handler.ts [94:136]
export async function handle(
toFunctionBytes: Buffer | Uint8Array,
fns: Record<string, FunctionSpec>
): Promise<Buffer | Uint8Array> {
//
// setup
//
const toFn = proto.io.statefun.sdk.reqreply.ToFunction.deserializeBinary(toFunctionBytes);
const pbInvocationBatchRequest = toFn.getInvocation();
if (pbInvocationBatchRequest === null) {
throw new Error("An empty invocation request");
}
const targetAddress = pbAddressToSdkAddress(pbInvocationBatchRequest.getTarget());
if (targetAddress === null) {
throw new Error("Missing target address");
}
const fnSpec = findTargetFunctionSpec(fns, targetAddress);
const {missing, values, storage} = AddressScopedStorageFactory.tryCreateAddressScopedStorage(pbInvocationBatchRequest, fnSpec.valueSpecs);
if (missing !== null) {
return respondImmediatelyWithMissingContext(missing);
}
if (values === undefined || values === null) {
throw new Error("Unexpected internal error. Could not create an address scoped storage.");
}
//
// apply the batch
//
const internalContext = new InternalContext();
const context = new Context(targetAddress, storage, internalContext);
await applyBatch(pbInvocationBatchRequest, context, internalContext, fnSpec.fn);
//
// collect the side effects
//
const pbInvocationResponse = new proto.io.statefun.sdk.reqreply.FromFunction.InvocationResponse();
collectStateMutations(values, pbInvocationResponse);
collectOutgoingMessages(internalContext.sent, pbInvocationResponse);
collectEgress(internalContext.egress, pbInvocationResponse);
collectDelayedMessage(internalContext.delayed, pbInvocationResponse);
const fromFn = new proto.io.statefun.sdk.reqreply.FromFunction();
fromFn.setInvocationResult(pbInvocationResponse);
return fromFn.serializeBinary();
}