JSPM

@serverless/components

2.8.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 164069
  • Score
    100M100P100Q148720F
  • License MIT

Serverless Components

Package Exports

  • @serverless/components

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@serverless/components) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

IMPORTANT – This branch features a large update to Serverless Components, which include cloud deployments, remote state storage, stages and the Serverless Registry. The README has been updated with instructions. Only a few Serverless Components have been updated to support these changes and they can be found in this repository's templates. You can read more about these changes here, or follow the README to get started!


Serverless Components

Serverless Components are simple abstractions that enable developers to deploy serverless applications and use-cases easily, via the Serverless Framework.

  • Simplicity - Easily deploy low-level infra, or higher-order serverless applications via Components.
  • Instant Deployments - Components deploy in 2-4 seconds.
  • Build Your Own - Components are easy to build.
  • Registry - Share your Components with you, your team, and the world, via the Serverless Registry.

Here's how easy it is to use Serverless Components with the Serverless Framework:

# serverless.yml

component: express@0.0.6 # The name of the Component in the Registry
org: acme # Your Serverless Framework Org
app: fullstack # Your Serverless Framework App
name: rest-api # The name of your instance of this Component

inputs: # The configuration the Component accepts according to its docs
  src: ./src

Read the Quick-Start to get started, or learn more via the documentation below!



Quick-Start

While we are testing the latest updates of Serverless Components, we've made them available within the Serverless Framework, via a special package on NPM:

$ npm i -g serverless@components

After installation, use the create --template-url command to install a Serverless Components Template, which contains Components as well as boilerplate code, to get you started quickly.

Currently, only the Components in the templates within this repository branch support the latest Serverless Component updates.

Deploy A Serverless Express.js Application

serverless create --template-url https://github.com/serverless/components/tree/cloud/templates/express

Deploy A Website

serverless create --template-url https://github.com/serverless/components/tree/cloud/templates/website

Next, both templates feaure package.json files. Be sure to run npm i to enable them to work.

After that, within your template, log in to enable deployment and saving state in the cloud:

$ serverless login

Be sure to copy your org and your app so that you can put these values into your serverless.yml. They are required to save your state.

# serverless.yml

org: my-org
app: my-app

Lastly, enter your cloud provider credentials into a .env file within the folder that contains your serverles.yml.

AWS_ACCESS_KEY_ID=12345
AWS_SECRET_ACCESS_KEY=5321

Deploy!

$ serverless deploy

Use --debug to see what your Components are doing upon deployment.

$ serverless deploy --dev

Run the remove command to remove your Component Instance and all of its cloud resources:

$ serverless remove

Features

Simplicity

Serverless Components are built around higher-order use-cases (e.g. a website, blog, payment system). Irrelevant low-level infrastructure details are abstracted away, and simpler configuration is offered instead.

For example, here's what it looks like to provision a serverless website hosted on AWS S3, delivered globally and quickly w/ AWS Cloudfront, via a custom domain on AWS Route 53, secured by a free AWS ACM SSL Certificate:

# serverless.yml

component: website # A Component in the Registry
org: acme # Your Org
app: ecommerce # Your App
name: website # The name of your Component Instance

inputs: # The configuration the Component accepts
  src:
    src: ./src
    hook: npm run build
    dist: ./dist
  domain: mystore.com

Check out these templates for more use-cases.

Instant Deployments

Most Serverless Components deploy within 2-4 seconds, 30x faster than traditional cloud provisioning tools.

Our goal is to design Serverless Components that deploy instantly, removing the need to emulate cloud services locally for fast feedback during the development process.

Serverless Components offer the fastest serverless development experience available today.

Build Your Own

Serverless Components are easily written in Javascript (serverless.js), with simple syntax inspired by component-based frameworks, like React.

// serverless.js

const { Component } = require('@serverless/core')

class MyBlog extends Component {
  async deploy(inputs) {
    await this.status('Deploying a serverless blog')
    const website = this.load('website', 'website-1') // Load a component
    const outputs = await website.deploy({ code: { src: inputs.src } }) // Deploy it
    this.state.url = outputs.url
    await this.save()
    return outputs
  }
}

module.exports = MyBlog

Registry

Anyone can build a Serverless Component and share it in our Registry.

$ serverless publish

express: components publish

express@0.0.4 › Published

Serverless

Serverless Components favor cloud infrastructure with serverless qualities (shocker!). We also believe in order to deliver the best product, you must be free to use the best services.

Serverless Components are being designed entirely vendor agnostic, enabling you to easily use services from different vendors, together. Like, AWS Lambda, AWS S3, Azure Functions, Google Big Query, Twilio, Stripe, Algolia, Cloudflare Workers and more.


Overview

Serverless Components are merely Javascript libraries that provision something.

They are focused primarily on use-cases built upon cloud infrastructure with serverless qualities, enabling you to deliver software with radically less overhead and cost. Serverless Components are to serverless back-end use-cases, what React Components are to front-end use-cases.

A Component can be designed to provision low-level infrastructure (e.g. an AWS S3 bucket). However, they can also provision higher-order outcomes — which is when they are at their best. Examples of a higher-order outcome are:

  1. A group of infrastructure with a purpose, like a type of data processing pipeline.
  2. A software feature, like user registration, comments, or a payment system.
  3. An entire application, like a blog, video streaming service, or landing page.

Serverless Components are used declaratively (via the Serverless Framework's serverless.yml file).

If you want to create a Serverless Component, it's easy! It's also trivial to load child Components and deploy them, enabling you to lean on low-level Components to handle difficult infrastructure provisioning tasks, while you rapidly create a higher-order abstraction.


Using Components

serverless.yml

Serverless Components live exclusively in the cloud, where they await to deploy your serverless use-cases.

They are discoverable and usable via the Serverless Registry. Please note, the Registry API exists today, but currently does not have a front-end with search functionality until January 4th, 2020. Instead, reference the templates directory for available Components.

To use a Serverless Component, declare the name of one that exists in the Serverless Registry in your serverless.yml. The syntax looks like this:

# serverless.yml

component: express # The name of the Component in the Registry
org: acme # Your Serverless Framework Org
app: fullstack # Your Serverless Framework App
name: rest-api # The name of your instance of this Component

inputs: # The configuration the Component accepts according to its docs
  src: ./src

There is nothing to install when using Serverless Components. Instead, when you run deploy, the configuration you specify in serverless.yml will be sent to the Serverless Components Deployment Engine, along with any files or folders you specifiy in inputs that may be part of the outcome you are seeking to deploy.

Please note that you can only have 1 Serverless Component in serverless.yml. We encourage this because we believe you should separate the resources in your Serverless Applications as much as possible, rather than put all of them in 1 infrastructure stack.

Note: You cannot use Serverless Components within an existing Serverless Framework project file (i.e. a project file that contains functions, events, resources and plugins).

Inputs

Every Serverless Component accepts parameters via an inputs property. You can see which inputs a Component accepts in its documentation.

Some inputs have special types, starting with src. This input specifies a folder containing code or general files you wish to upload upon deployment, which the Component may need to provision a specific outcome. Before running the Component in the cloud, the Serverless Framework will first upload any files specified in src. Generally, you want to keep the package size of your serverless applications small (<5MB) in order to have the best performance in serverless compute services. Larger package sizes will also make deployments slower since the upload process is dependent on your internet connection bandwidth. Consider a tool to build and minify your code first. You can specify a build hook to run and a dist folder to upload, via the src property, like this:

inputs:
  src:
    src: ./src # Source files
    hook: npm run build # Build hook to run on every "serverless deploy"
    dist: ./dist # Location of the distribution folder to upload

Deploying

You can deploy Components easily via the Serverless Framework with the $ serverless deploy command.

$ serverless deploy

While Serverless Components deploy incredibly fast, please note that first deployments can often be 10x slower because creating cloud resources takes a lot longer than updating them.

State

Serverless Components automatically save their state remotely. This means you can easily push your Components to Github, Gitlab, Bitbucket, etc., and collaborate on them with others as long as the serverless.yml contains an org which your collaboraters are added to:

component: my-component
org: acme-team # Your collaboraters must be added at dashboard.serverless.com
app: ecommerce
name: rest-api

Further, your Component Instances can easily be deployed with CI/CD, as long as you make sure to include a SERVERLESS_ACCESS_TOKEN environment variable.

You can add collaboraters and create access tokens in the Serverless Framework Dashboard.

Versioning

Serverless Components use semantic versioning.

component: express@0.0.4

When you add a version, only that Component version is used. When you don't add a version, upon every deployment, the Serverless Framework will use a "dev" stage of that Component, if it exists. We recommend to always pin your Component to a version.

Outputs

When a Component is finished running, it returns an outputs object.

Outputs contain the most important information you need to know from a deployed Component Instance, like the URL of the API or website, or all of the API endpoints.

Credentials

Upon deployment, the Serverless Framework looks for a .env file in the current working directory. If a .env file exists, the Serverless Framework will send those credentials to the Component and the Component can access them within the this.credentials object. However, you must use the following Environment Variable keys:

AWS Credentials

AWS_ACCESS_KEY_ID=123456789
AWS_SECRET_ACCESS_KEY=123456789
AWS_REGION=us-east-1

Components could access these AWS credentials using this.credentials.aws. This object would look like this:

{
  accessKeyId: '123456789',
  secretAccessKey: '123456789',
  region: 'us-east-1'
}

Google Credentials

# You can specify the path to the JSON credentials file that you downloaded from Google
GOOGLE_APPLICATION_CREDENTIALS=path/to/credentials/json/file

# Or you could just provide your project id, client email & private key
GOOGLE_PROJECT_ID=project-id-xxx
GOOGLE_CLIENT_EMAIL=project-id-xxx@appspot.gserviceaccount.com
GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgk..."

Components could access these google credentials using this.credentials.google. This object would look like this:

{
  applicationCredentials: 'path/to/credentials/json/file',
  projectId: 'project-id-xxx',
  clientEmail: 'project-id-xxx@appspot.gserviceaccount.com',
  privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgk...'
}

Stages

Serverless Components have a Stages concept, which enables you to deploy entirely separate Component Instances and their cloud resources per stage.

The dev Stage is always used as the default stage. If you wish to change your stage, set it in serverless.yml, like this:

component: express@0.0.4
org: my-org
app: my-app
name: my-component-instance
stage: prod # Enter the stage here

You can also specify a Stage within the SERVERLESS_STAGE Environment Variable, which overrides the stage set in serverless.yml:

SERVERLESS_STAGE=prod

Lastly, you can specify a Stage upon deployment via a CLI flag, which overrides anything set in serverless.yml AND an Environment Variable, like this:

$ serverless deploy --stage prod

Again, the CLI flag overrides both a stage in serverless.yml and an Environment Variable. Whereas an Environment Variable can only override the stage in serverless.yml.


Variables

You can use Variables within your Component Instances serverless.yml to reference Environment Variables, values from within serverless.yml and Outputs from other Serverless Component Instances that you've already deployed.

Here is a quick preview of possibilities:

org: acme
app: ecommerce
component: express
name: rest-api
stage: prod

inputs:
  name: ${org}-${stage}-${app}-${name} # Results in "acme-prod-ecommerce-rest-api"
  region: ${env.REGION} # Results in whatever your environment variable REGION= is set to.
  roleArn: ${output:shared:prod:role.arn} # Fetches an output from another component instance that is already deployed

Variables: Org

You can reference your org value in the inputs of your YAML in serverless.yml by using the ${org} Variable, like this:

org: acme
app: ecommerce
component: express
name: rest-api
stage: prod

inputs:
  name: ${org}-api # Results in "acme-api"

Variables: Stage

You can reference your stage value in the inputs of your YAML in serverless.yml by using the ${stage} Variable, like this:

org: acme
app: ecommerce
component: express
name: rest-api
stage: prod

inputs:
  name: ${stage}-api # Results in "prod-api"

Variables: App

You can reference your app value in the inputs of your YAML in serverless.yml by using the ${app} Variable, like this:

org: acme
app: ecommerce
component: express
name: rest-api
stage: prod

inputs:
  name: ${app}-api # Results in "ecommerce-api"

Variables: Name

You can reference your name value in the inputs of your YAML in serverless.yml by using the ${name} Variable, like this:

org: acme
app: ecommerce
component: express
name: rest-api
stage: prod

inputs:
  name: ${name} # Results in "rest-api"

Variables: Environment Variables

You can reference Environment Variables (e.g. those that you defined in the .env file or that you've set in your environment manually) directly in serverless.yml by using the ${env} Variable.

For example, if you want to reference the REGION environment variable, you could do that with ${env.REGION}.

component: express
org: acme
app: ecommerce
name: rest-api
stage: prod

inputs:
  region: ${env.REGION}

Variables: Outputs

Perhaps one of the most useful Variables is the ability to reference Outputs from other Component Instances that you have already deployed. This allows you to share configuration/data easily across as many Component Instances as you'd like.

If you want to reference an Output of another Component Instance, use the ${output:[app]:[stage]:[instance name].[output]} syntax, like this:

component: express
org: acme
app: ecommerce
name: rest-api
stage: prod

inputs:
  roleArn: ${output:shared:prod:role.arn} # Fetches an output from another component instance that is already deployed

You can access Outputs across any App, Instance, in an any Stage, within the same Org.

A killer feature of this is the ability to share resources easily, and even do so across environments. This is useful when developers want to deploy a Component Instance in their own personal Stage, but access shared resources within a common "development" Stage, like a database. This way, the developers on your team do not have to recreate the entire development stage to perform their feature work or bug fix, only the Component Instance that needs changes.


Building Components

If you want to build reusable Serverless Components, there are 2 essential files you need to be aware of:

  • serverless.component.yml - This contains the definition of your Serverless Component.
  • serverelss.js - This contains your Serverless Component's code.

One of the most important things to note is that Serverless Components only run in the cloud and do not run locally. You must publish your Component first, to run it (it takes only few seconds to publish). Fortunately, we've made this process easy, as described below.

serverless.component.yml

To declare a Serverless Component and make it available within the Serverless Registry, you must create a serverless.component.yml file with the following properties:

# serverless.component.yml

name: express # Required. The name of the Component
version: 0.0.4 # Required. The version of the Component
author: eahefnawy # Required. The author of the Component
org: serverlessinc # Required. The Serverless Framework org which owns this Component
description: Deploys Serverless Express.js Apps # Optional. The description of the Component
keywords: aws, serverless, express # Optional. The keywords of the Component to make it easier to find at registry.serverless.com
repo: https://github.com/owner/project # Optional. The code repository of the Component
license: MIT # Optional. The license of the Component code
main: ./src # Optional. The directory which contains the Component code

serverless.js

A serverless.js file contains the Serverless Component's code.

To make a bare minimum Serverless Component, create a serverless.js file, extend the Component class and add a deploy method like this:

// serverless.js

const { Component } = require('@serverless/core')

class MyComponent extends Component {
  async deploy(inputs = {}) {
    return {}
  } // The default functionality to run/provision/update your Component
}

module.exports = MyComponent

deploy() is always required. It is where the logic resides in order for your Component to make something. Whenever you run the $ serverless deploy command, it's always calling the deploy() method.

You can also add other methods to this class. A remove() method is often the next logical choice, if you want your Serverless Component to remove the things it creates, via $ serverless remove.

You can add as many methods as you want. This is interesting because it enables you to ship more automation with your Component, than logic that merely deploys and removes something.

It's still early days for Serverless Components, but we are starting to work on Components that ship with their own test() function, or their own logs() and metrics() functions, or seed() for establishing initial values in a database Component. Overall, there is a lot of opportunity here to deliver Components that are loaded with useful automation.

All methods other than the deploy() method are optional. All methods take a single inputs object, not individual arguments, and return a single outputs object.

Here is what it looks like to add a remove method, as well as a custom method.

// serverless.js

const { Component } = require('@serverless/core')

class MyComponent extends Component {
  /*
   * Deploy (Required)
   * - The default functionality to run/provision/update your Component
   * - You can run this function by running the "$ serverless deploy" command
   */

  async deploy(inputs = {}) {
    return {}
  }

  /*
   * Remove (Optional)
   * - If your Component removes infrastructure, this is recommended.
   * - You can run this function by running "$ serverless remove"
   */

  async remove(inputs = {}) {
    return {}
  }

  /*
   * Anything (Optional)
   * - If you want to ship your Component w/ extra functionality, put it in a method.
   * - You can run this function by running "$ serverless anything"
   */

  async anything(inputs = {}) {
    return {}
  }
}

module.exports = MyComponent

When inside a Component method, this comes with utilities which you can use. Here is a guide to what's available to you within the context of a Component.

// serverless.js

const { Component } = require('@serverless/core')

class MyComponent extends Component {
  async deploy(inputs = {}) {
    // this features useful information
    console.log(this)

    // Common provider credentials are identified in the environment or .env file and added to this.context.credentials
    // when you run "serverless deploy", then the credentials in .env will be used
    // when you run "serverless deploy --stage prod", then the credentials in .env.prod will be used...etc
    // if you don't have any .env files, then global aws credentials will be used
    const dynamodb = new AWS.DynamoDB({ credentials: this.credentials.aws })

    // You can easily create a random ID to name cloud infrastructure resources with using this utility.
    const s3BucketName = `my-bucket-${this.resourceId()}`
    // This prevents name collisions.

    // Components have built-in state storage.
    // Here is how to save state to your Component:
    this.state.name = 'myComponent'
    await this.save()

    // Here is how to load a child Component via its name in the Registry
    // You can run a method on the child Component, like this:
    let websiteOutputs = await website.deploy({ code: { src: './src' } })

    // If you are deploying multiple instances of the same Component, include an instance id.
    let website1 = this.load('website', 'website1')
    let website2 = this.load('website', 'website2')
    // Child Components save their state automatically.

    // Here is how you can easily remove a Component.
    let websiteRemoveOutputs = await website.remove({})

    // Here is how you can call any custom method on a Component.
    let websiteRemoveOutputs = await website.test({})

    // If you want to show a status update to the CLI, use this.
    await this.status('Uploading')

    // If you want to show a debug statement in the CLI, use this.
    await this.debug('this is a debug statement')

    // Return your results
    return { url: websiteOutputs.url }
  }
}

module.exports = MyComponent

Development Workflow

Serverless Components only run in the cloud and cannot be run locally. This presents some tremendous advantages to Component consumers, but the workflow can be a bit tedious for Component authors building and testing Serverless Components. Fortunately, we've added some workflow tricks to make the authoring workflow easier. Here they are...

When you have added or updated the code of your Serverless Component and you want to test the change, you will need to publish it first. Since you don't want to publish your changes to a proper version of your Component just for testing (because people may be using it), we allow for you to publish a "dev" version of your Component.

Simply run the following command to publish your Serverless Component to the "dev" version:

$ serverless publish --dev

You can test the "dev" version of your Component in serverless.yml, by not including a @version in your Component name, like this:

# serverless.yml

component: express # DO NOT ADD A @version HERE.  By keeping blank, it will use the "dev" version.
org: acme
app: fullstack
name: rest-api

inputs:
  src: ./src

Run your Component command to test your changes:

$ serverless deploy --debug

When writing a Component, we recomend to always use the --debug flag, so that the Component's this.debug() statements are sent to the CLI. These are handy to use in Serverless Components, since they describe what the Component is doing. We recommend you add this.debug() statements to your Component wherever you think they are necessary. Don't forget to add await as well!

class MyComponent extends Component {
  async deploy(inputs) {
    await this.debug(`Starting MyComponent.`)
    await this.debug(`Creating resources.`)
    await this.debug(`Waiting for resources to be provisioned.`)
    await this.debug(`Finished MyComponent.`)
    return {}
  }
}

When you're ready to publish a new version for others to use, update the version in serverless.component.yml, then run publish without the --dev flag.

# serverless.component.yml

name: express@0.0.5
$ serverless publish

Serverless: Successfully publish express@0.0.5

Development Tips

Here are some development tips when it comes to writing Serverless Components:

Start With The Outcome

When making a Serverless Component, it can be tempting to break it down into several levels of child Components, to maintain separation of concerns and increase the ways your work could be re-used.

However, we've learned over-optimizing for granular separation of concerns is a fast way to burn yourself out, and you'll often realize your Component will deploy faster and more reliably without relying on several child Components.

We recommend starting with a focus on your desired outcome. Create one Serverless Component that solves that problem first. After you've achieved your initial goal, then start breaking it down into child Components, if you think there is value in that still.

The Outcome Is Your Advantage

Provisioning infrastructure can be quite complicated. However, Serverless Components have one powerful advantage over general infrastructure provision tools that seek to enable every possible option and combination (e.g. AWS Cloudformation) — Serverless Components know the specific use-case they are trying to deliver.

One of the most important lessons we've learned about software development tools is that once you know the use-case, you can create a much better tool.

Components know their use-case. You can use that knowledge to: 1) provision infrastructure more reliably, because you have a clear provisioning path and you can program around the pitfalls. 2) provision infrastructure more quickly 3) add use-case specific automation to your Component in the form of custom methods.

Keep Most State On The Cloud Provider

Serverless Components save remarkably little state. In fact, many powerful Components have less than 10 properties in their state objects.

Components rely on the state saved within the cloud services they use as the source of truth. This prevents drift issues that break infrastructure provisioning tools. It also opens up the possibility of working with existing resources, that were not originally managed by Serverless Components.

Store State Immediately After A Successful Operation

If you do need to store state, try to store it immediately after a successful operation. This way, if anything after that operation fails, your Serverless Component can pick up where it left off, when the end user tries to deploy it again.

Optimize For Accessibility

We believe serverless infrastructure and architectures will empower more people to develop software than ever before.

Because of this, we're designing all of our projects to be as approachable as possible. Please try to use simple, vanilla Javascript. Additionally, to reduce security risks and general bloat, please try to use the least amount of NPM dependencies as possible.

Core API

You could use components programatically and integrate them into your own application or CLI using a simple object-oriented abstraction. All you need is an accessKey from the Serverless Dashboard that you simply pass to one of the core classes.

We export 3 main classes for working with components:

  1. The Component Class: This class represnets and manages components in the registry. You could use this class if you'd like to publish or unpublish components to the registry.

  2. The Instance Class: This class represents component instances of existing components that were previously published to the registry. You could use this class if you'd like to build, deploy, remove or run a particular component from the registry.

  3. The Context Class: This class represents the context components and instances are running within. You could use this class to control how you set the accessKey and credentials, how you consume logs and how you render your UI.

Component Class

const { Component } = require('@serverless/components')

// set the context properties
const context = {
  accessKey: 'xxx'
}

// your component properties
const props = {
  name: 'myComponent', // required
  version: '0.1.0', // optional. default is dev
  org: 'serverlessInc', // required
  author: 'Austen Collins', // required
  description: 'My Component', // optional
  keywords: 'aws, serverless', // optional
  repo: 'https://github.com/owner/repo', // optional
  readme: 'README.md', // optional
  license: 'MIT', // optional. default is MIT
  main: './src' // optional. default is ./src
}

// intitialize a new instance of the Component class
const myComponent = new Component(props, context)

// publish a new component to the registry
await myComponent.publish()

Instance Class

const { Instance } = require('@serverless/components')

// set the context properties
const context = {
  accessKey: 'xxx',
  credentials: { aws: {} }
}

// your component instance properties
const props = {
  name: 'myComponent', // required
  component: 'express@1.0.0', // required. Version optional.
  org: 'serverlessInc', // required
  app: 'myApp', // required.
  stage: 'dev', // optional. default is dev
  inputs: {
    foo: 'bar',
    src: './src'
  }
}

// intitialize a new instance of the Component Instance class
const myInstance = new Instance(props, context)

// optionally connect to the instance via WebSockets
// this allows your context to process streaming logs
await myInstance.connect()

// build the src input if provided
await myInstance.build()

// upload the src input if provided
await myInstance.upload()

// run a method on the initialized instance. default is 'deploy'
const outputs = await myInstance.run()

// pass any other method you'd like to run...
await myInstance.run('remove')

Context Class

const { Context, Instance } = require('@serverless/components')

// you can overwite the core Context class methods
// if you'd like to control the context & stream logs
class myContext extends Context {
  log() {
    // do something...
  }

  debug() {
    // do something...
  }

  status() {
    // do something...
  }
}

const props = {
  // instance props here...
}

// initialize your new context here...
const context = new myContext({ accessKey: 'xxx' })

const myInstance = new Instance(props, context)

await myInstance.connect()

const outputs = await myInstance.run()