@eigr/spawn-sdk
TypeScript icon, indicating that this package has built-in type declarations

1.2.0 • Public • Published

Actor model framework for Node/Bun

Installation

yarn add @eigr/spawn-sdk

This package depends on @protobuf-ts/plugin to work with protobufs

Getting Started

We recommend you to use Typescript for better usage overall.

This lib supports both Bun and NodeJS runtimes, Bun performs invocations ~2x faster, we recommend using Bun.

Basic Usage

import spawn, { ActorContext, Value } from '@eigr/spawn-sdk'
import { UserState, ChangeUserNamePayload, ChangeUserNameStatus } from 'src/protos/examples/user_example'

const system = spawn.createSystem('spawn-system')

// You can register multiple actors with different options
const actor = system.buildActor({
  name: 'exampleActor',
  stateType: UserState,
  stateful: true,
  snapshotTimeout: 10_000n,
  deactivatedTimeout: 60_000n
})

// This can be defined in a separate file
const setNameHandler = async (context: ActorContext<UserState>, payload: ChangeUserNamePayload) => {
  return Value.of<UserState, ChangeUserNameResponse>()
    .state({ name: payload.newName })
    .response({ status: ChangeUserNameStatus.OK })
}

// This is similar to a Route definition in REST
actor.addAction({ name: 'SetName', payloadType: ChangeUserNamePayload, responseType: ChangeUserNameResponse }, setNameHandler)

system.register()
  .then(() => console.log('Spawn System registered'))

With this configured, you can invoke this actor anywhere you want with:

import spawn, { payloadFor } from '@eigr/spawn-sdk'
import { UserState, ChangeUserNamePayload, ChangeUserNameResponse } from 'src/protos/examples/user_example'

(async () => {
  const payload = { newName: 'changedName' } as ChangeUserNamePayload
  const response: ChangeUserNameResponse = await spawn.invoke('exampleActor', {
    action: 'setName',
    response: ChangeUserNameResponse,
    payload: payloadFor(ChangeUserNamePayload, payload),
    system: 'spawn-system'
  })

  const state: UserState = await spawn.invoke('exampleActor', {
    action: 'getState',
    response: UserState,
    system: 'spawn-system'
  })

  console.log(state) // { name: 'changedName' }
})()

Using protobufs

NOTE: Its recommended to use Protobufs to ensure your contracts will always be what you expect and also for performance improvements

Define a protobuf file (lets save this at protos/examples/user_example.proto), if you want to skip this part, you can use 'json' type actors.

syntax = "proto3";

message UserState {
  string name = 1;
}

message ChangeUserNamePayload {
  string new_name = 1;
}

enum ChangeUserNameStatus {
  NAME_ALREADY_TAKEN = 0;
  OK = 1;
}

message ChangeUserNameResponse {
  ChangeUserNameStatus status = 1;
}

Compile proto with protoc using ts-protoc-gen:

protoc --ts_out ./src/protos/ --proto_path protos protos/**/*.proto

With this, it should generate a file at src/protos/examples/user_example.ts, we will use this generated module for Actor definitions and invocations.

Running the Proxy

You'll need to make sure Spawn Proxy service is up and running. With docker-compose you can define:

NOTE: you can start the proxy using the spawn cli, see spawn deploy for production examples.

version: "3.8"

services:
  spawn-proxy:
    image: eigr/spawn-proxy:1.1.0
    restart: always
    environment:
      PROXY_ACTOR_SYSTEM_NAME: "spawn-system" # change this to the system you've registered
      PROXY_APP_NAME: spawn-typescript
      PROXY_HTTP_PORT: 9001
      PROXY_DATABASE_TYPE: postgres
      PROXY_DATABASE_NAME: eigr-functions-db
      PROXY_DATABASE_USERNAME: postgres
      PROXY_DATABASE_SECRET: password
      PROXY_DATABASE_HOST: localhost
      PROXY_DATABASE_PORT: 5432
      SPAWN_STATESTORE_KEY: 3Jnb0hZiHIzHTOih7t2cTEPEpY98Tu1wvQkPfq/XwqE=
      USER_FUNCTION_HOST: 0.0.0.0 # Your NodeJS runtime host
      USER_FUNCTION_PORT: 8090 # Your NodeJS runtime exposed port
    network_mode: host
    ports:
      - "9001:9001"

NOTE: Windows w/ WSL2 - If you want to use docker for spawn-proxy and local host for your NodeJS check this article https://www.beyondjava.net/docker-wsl-network

Set the following ENV variables for your NodeJS runtime (following .env.example)

PROXY_HTTP_PORT=9001
PROXY_HTTP_HOST=localhost
USER_FUNCTION_PORT=8090

Documentation

Examples

You can check test folder to see some examples

Environment variables: (you don't need to worry if you are using spawn proxy)

  • PROXY_HTTP_PORT This is the port of spawn proxy service
  • PROXY_HTTP_HOST This is the host of spawn proxy service
  • USER_FUNCTION_PORT This is the port that your service will expose to communicate with Spawn

Readme

Keywords

none

Package Sidebar

Install

npm i @eigr/spawn-sdk

Weekly Downloads

2

Version

1.2.0

License

ISC

Unpacked Size

370 kB

Total Files

45

Last publish

Collaborators

  • eliasdarruda
  • eigrio