Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
async-call-rpc
Advanced tools
async-call-rpc
is a JSON RPC server and client written in TypeScript for any ECMAScript environment.
CHANGELOG.md | Document of AsyncCall | Document of AsyncGeneratorCall | Playground
Chapters:
channel
, how to communicateencoder
, how to use complex data typeschannels
(including WebSocket)async function
).npm i async-call-rpc
yarn add async-call-rpc
pnpm i async-call-rpc
You can access https://www.jsdelivr.com/package/npm/async-call-rpc?path=out to get the latest URL and SRI.
import { AsyncCall } from 'https://cdn.jsdelivr.net/npm/async-call-rpc@latest/out/base.mjs'
<script src="https://cdn.jsdelivr.net/npm/async-call-rpc@2.0.1/out/base.js"></script>
<script>
const { AsyncCall } = globalThis.AsyncCall
</script>
Load the out/base.mjs
(ES Module) or out/base.js
(UMD, CommonJS, or AMD) to your project.
channel
To communicate with the server/client, you need to implement one of the following interfaces:
There are some built-in channels you can simplify the usage.
The following document will assume you have defined your channel
.
encoder
This library does not have any opinionated data transmitting format. You need to implement one of the following interfaces:
// 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.ts'
// create a server
AsyncCall(server, { channel })
import { AsyncCall } from 'async-call-rpc'
import type * as server from './server.ts'
const server = AsyncCall<typeof server>({}, { channel })
server.add(2, 40).then(console.log) // 42
AsyncCall can send notifications.
Using notifications means results or remote errors are never sent back. Local errors will not be omitted, e.g. encoder errors or network errors.
import { AsyncCall, notify } from 'async-call-rpc'
const server = notify(AsyncCall<typeof server>({}, { channel }))
server.add(1, 2).then(console.log) // undefined
AsyncCall can send batch request too.
import { AsyncCall, batch } from 'async-call-rpc'
const [server, emit, drop] = batch(AsyncCall<typeof server>({}, { channel }))
const a = server.req1() // pending
const b = server.req2() // pending
const c = server.req3() // pending
emit() // to send all pending requests
// request a, b, c sent
const d = server.req1() // pending
drop() // to drop all pending requests (and reject corresponding Promises)
// d rejected
This library has 2 entries. base
and full
. base
is the default entry point. The full
version includes the AsyncGeneratorCall
but the base
version doesn't.
Please check out https://www.jsdelivr.com/package/npm/async-call-rpc?path=out
// Full version
require('async-rpc-call/full') // or
import { } from 'async-rpc-call/full'
// Base version
require('async-rpc-call') // or
import { } from 'async-rpc-call'
They're not part of the core library but are provided as utils to increase usability.
Server | Client | |
---|---|---|
Entry point | async-call-rpc/utils/node/websocket.server.js (Source code) | TBD |
Entry point type | CommonJS | CommonJS |
Dependencies | ws | ws |
Example | ./examples/node.websocket.server.js | TBD |
Server | Client | |
---|---|---|
Entry point | https://cdn.jsdelivr.net/npm/async-call-rpc@latest/utils/deno/websocket.server.ts (Source code) | TBD |
Entry point type | ES Module | ES Module |
Dependencies | Deno std | Deno std |
Example | ./examples/deno.websocket.server.ts | TBD |
Client | |
---|---|
Entry point | https://cdn.jsdelivr.net/npm/async-call-rpc@latest/utils/web/websocket.client.js (Source code) |
Entry point type | ES Module |
Dependencies | Nothing |
Example | ./examples/browser.websocket.client.js |
Server & Client | |
---|---|
Entry point | https://cdn.jsdelivr.net/npm/async-call-rpc@latest/utils/web/broadcast.channel.js (Source code) |
Entry point type | ES Module |
Dependencies | Nothing |
Example | TBD |
Host & Worker | |
---|---|
Entry point | https://cdn.jsdelivr.net/npm/async-call-rpc@latest/utils/web/worker.js (Source code) |
Entry point type | ES Module |
Dependencies | Nothing |
Example | Main frame: ./examples/browser.worker-main.js Worker: ./examples/browser.worker-worker.js |
Main thread: new WorkerChannel(new Worker(...))
Worker: new WorkerChannel()
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, returns the id
'rpc.async-iterator.start'(method: string, params: unknown[]): Promise<string>
//This method executes the `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 the `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 the `throw` method on the previous iterator started by `rpc.async-iterator.start`
'rpc.async-iterator.throw'(id: string, value: unknown): Promise<IteratorResult<unknown>>
}
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 includes the caller's stack.
remoteStack?: string
}
This is a non-standard property that appears when using the deprecated 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
}
In the JSON RPC specification, this is implementation-defined. This is controlled by the option options.mapError
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 the 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'
}
}
6.4.0
fd34f22: add a new encoder
option and deprecate the old serializer
option
how to migrate:
// before
const options = {
channel,
serializer: {
serialization(data) { return ... },
deserialization(data) { return ... },
},
}
// after
const options = {
channel,
encoder: {
encode(data) { return ... },
decode(data) { return ... },
},
}
// before
const options = {
channel,
serializer: NoSerialization,
};
// after
const options = {
channel,
};
// before
const options = {
channel,
serializer: JSONSerialization(),
};
// after
const options = {
channel,
encoder: JSONEncoder(),
};
fd34f22: hint
added to the CallbackBasedChannel.setup(jsonRPCHandlerCallback)
and EventBasedChannel.on(listener)
.
For an isomorphic instance of AsyncCall
(used as both a server and a client),
when a new message comes, it does not clear if to call decodeRequest
or decodeRespones
.
This version introduces a new option encoder
to replace serialization
. serialization
is always working in isomorphic way.
hint
is "request"
, (encoder as ServerEncoding).decodeRequest
will be called first, if this method does not exist, (encoder as IsomorphicEncoder).decode
will be called.hint
is "response"
, (encoder as ClientEncoding).decodeResponse
will be called first, if this method does not exist, (encoder as IsomorphicEncoder).decode
will be called.hint
is not present, only encoder.decode
will be called.0d0900b: rename "key" to "name"
fd34f22: BSON_Serialization
and Msgpack_Serialization
is now deprecated
0431c15: rename AsyncCallStrictJSONRPC
to AsyncCallStrictOptions
8a38d8b: add signal
and forceSignal
to stop the instance
c9bbbd2: rename parameterStructures
to parameterStructure
fd34f22: expose JSON-RPC interfaces
fd34f22: new built-in JSONEncoder
for the new encode option.
Promise<void>
into return signature of EventBasedChannel.send
FAQs
A lightweight JSON RPC server & client
The npm package async-call-rpc receives a total of 4,421 weekly downloads. As such, async-call-rpc popularity was classified as popular.
We found that async-call-rpc demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
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.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.