Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

async-call-rpc

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

async-call-rpc

A lightweight JSON RPC server & client

  • 3.0.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
5.2K
decreased by-8.19%
Maintainers
1
Weekly downloads
 
Created
Source

Async Call

async-call-rpc is a JSON RPC server and client written in TypeScript for any ES6+ environment.

Code coverage GitHub Workflow Status npm ES2015+

CHANGELOG.md | Document of AsyncCall | Document of AsyncGeneratorCall | Playground

Chapters:

Features

  • Zero dependencies!
  • Running in any ES6+ environment (+globalThis), no requirement on any Web or Node API
  • Simple to define a server and simple to use as a client
  • Full TypeScript support
  • Support custom serializer to pass complex data types
  • Support async generator (Require both server and client supports 4 JSON RPC internal methods, and Symbol.asyncIterator, (async function* () {}).constructor.prototype available)

Cautions

  • NOT support ECMAScript 5 (ES6 Proxy is the core of this library)
  • This package is shipping ECMAScript 2018 syntax (including async function).
  • The async generator mode might leak memory on the server. Use it by your caution.
  • NOT support JSON RPC 1.0

The first concept: messageChannel

The messageChannel is the only thing you need to learn to use this library.

This library is designed to not rely on any specific platform. Only require things defined in the ECMAScript specification. In the ES spec, there is no I/O related API so it's impossible to communicate with the outer world.

Therefore, this library require you to provide an object in the following shape:

interface MessageChannel {
    on(event: string, callback: (data: unknown) => void): void
    emit(event: string, data: unknown): void
}

In general, the MessageChannel should have the following semantics:

  • When the data from the remote arrives (by addEventListener('message', ...), etc), the callback should be called.
  • When the emit method is called, the data should be sent to the remote properly (by postMessage or fetch, etc).

There is a plan to add built-in messageChannel for Web, Node.JS, and Deno to simplify the setup.

The following document will assume you have defined your messageChannel.

Example

Server example

// server.ts
export function add(x: number, y: number) {
    return x + y
}
export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))

// init.ts
import { AsyncCall } from 'async-call-rpc'
import * as server from './server'
// create a server
AsyncCall(server, { messageChannel })

Client example

import { AsyncCall } from 'async-call-rpc'
const server = AsyncCall<typeof server>({}, { messageChannel })
server.add(2, 40).then(console.log) // 42

Isomorphic API

You can notice from the above example, define a server is using AsyncCall(serverImplementation, opt), define a client is using AsyncCall<typeof serverImplementation>({}, opt). So it is possible to define a server and a client at the same time.

Installation

Install through npm

npm i async-call-rpc

yarn add async-call-rpc

Import from browser or Deno

You can access https://www.jsdelivr.com/package/npm/async-call-rpc?path=out to get the latest URL and SRI.

(Supports type definition for deno out-of-box!)

import { AsyncCall } from 'https://cdn.jsdelivr.net/npm/async-call-rpc@latest/out/base.mjs'

UMD

<script src="https://cdn.jsdelivr.net/npm/async-call-rpc@2.0.1/out/base.js"></script>
<script>
    const { AsyncCall } = globalThis.AsyncCall
</script>

In other JS environment

Load the out/base.mjs (ES Module) or out/base.js (UMD, CommonJS or AMD) to your project.

Entries

This library has 2 entry. base and full. base is the default entry point. The full version includes the AsyncGeneratorCall but the base version doesn't.

Browser / Deno

Please check out https://www.jsdelivr.com/package/npm/async-call-rpc?path=out

Node:

// Full version
require('async-rpc-call/full') // or
import * as RPC from 'async-rpc-call/full'

// Base version
require('async-rpc-call/base') // or
import * as RPC from 'async-rpc-call/base'

Look this if both server and client are created by this library

AsyncCall has some non-standard extensions to the JSON RPC specification that can help the library easier to use. Those features aren't enabled by default.

Implemented JSON RPC internal methods

These four methods are used to implement AsyncGeneratorCall support.

interface JSONRPC_Internal_Methods {
    // These 4 methods represent the Async Iterator protocol in ECMAScript
    // this method starts an async iterator, return the id
    'rpc.async-iterator.start'(method: string, params: unknown[]): Promise<string>
    // this method executes `next` method on the previous iterator started by `rpc.async-iterator.start`
    'rpc.async-iterator.next'(id: string, value: unknown): Promise<IteratorResult<unknown>>
    // this method executes `return` method on the previous iterator started by `rpc.async-iterator.start`
    'rpc.async-iterator.return'(id: string, value: unknown): Promise<IteratorResult<unknown>>
    // this method executes `throw` method on the previous iterator started by `rpc.async-iterator.start`
    'rpc.async-iterator.throw'(id: string, value: unknown): Promise<IteratorResult<unknown>>
}

Non-standard extension to JSON RPC specification

remoteStack on Request object

This library can send the client the call stack to the server to make the logger better.

Controlled by option.log.sendLocalStack. Default to false.

interface JSONRPC_Request_object {
    // This property include the caller's stack.
    remoteStack?: string
}

"undef" on Response object

This is a non-standard property appears when using JSONSerialization due to JSON doesn't support undefined. It's a hint to the client, that the result is undefined.

This behavior is controlled by the 3rd parameter of JSONSerialization(replacerAndReceiver?, space?, undefinedKeepingBehavior?: false | "keep" | "null" = "null"). Default to "null". To turn on this feature to "keep" undefined values, change the 3rd option to "keep".

interface JSONRPC_Response_object {
    // This property is a hint.
    // If the client is run in JavaScript, it should treat "result: null" as "result: undefined"
    undef?: boolean
}

The implementation-defined Error data

In the JSON RPC specification, this is implementation-defined. (Plan to add API for custom Error data).

This library will try to "Recover" the Error object if there is enough information from another side.

interface JSONRPC_Error_object {
    // This property will help client to build a better Error object.
    data?: {
        stack?: string
        // Supported value for "type" field (Defined in ECMAScript specification):
        type?:
            | string
            | 'Error'
            | 'EvalError'
            | 'RangeError'
            | 'ReferenceError'
            | 'SyntaxError'
            | 'TypeError'
            | 'URIError'
            // Defined in HTML specification, only supported in Web
            | 'DOMException'
    }
}

Keywords

FAQs

Package last updated on 27 Jun 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc