README
👫
alice-bob
transport agnostic strongly typed duplex rpc interfaces
🔧 Install · 🧩 Example · 📜 API docs · 🔥 Releases · 💪🏼 Contribute · 🖐️ Help
Install
$ npm i alice-bob
Example
// alice
import { fork } from 'child_process'
import { join } from 'path'
import { Alice } from 'alice-bob'
// we import Bob's interface and call it Remote
// bob will show as Agent<Remote> in intellisense
import type { Interface as Remote } from './bob'
export interface Interface {
hiya: (message: { from: string }) => Promise<void>
}
// for intellisense reasons we alias our interface to `Local`
// so that alice shows as Agent<Local> and bob as Agent<Remote>
type Local = Interface
// start bob
const child = fork(join(__dirname, 'bob'))
// create an Alice instance with given `send` function as the
// constructor parameter. Note that Alice, Bob both inherit from
// the AliceBob class, the only thing they change is they have
// the names "alice" and "bob" preconfigured in their agents
const [alice, bob] = new Alice<Local, Remote>(
data => void child.send(data)
).agents()
// all messages from bob passed to alice.receive
child.on('message', alice.receive)
// we can set debug=true|false at any time
alice.debug = true
// methods can be added also lazily at any time at any scope..
alice.hiya = async ({ from }) => {
alice.log(from, 'says: hiya!')
// => alice: bob says: hiya!
// `agent.log()` prepends the agent's name to the output
}
const sayHello = async () => {
const result = await bob.hello('there', { iam: alice.name })
alice.log('bob responded with:', result)
// => alice: bob responded with: hi alice
process.exit(0)
}
sayHello()
// bob
import { Bob } from 'alice-bob'
import type { Interface as Remote } from './alice'
export interface Interface {
hello: (message: string, data: { iam: string }) => Promise<string>
}
type Local = Interface
const [bob, alice] = new Bob<Local, Remote>().agents({ debug: true })
// we connect our transport in just these two lines
process.on('message', bob.receive)
// send method can be provided at any time
bob.send = data => void process.send!(data)
bob.hello = async (message, { iam }) => {
bob.log(iam + ' says: hello ' + message)
// we can call alice methods as well
await alice.hiya({ from: 'bob' })
// if we throw here the remote's `await`
// will throw as well with this message
// throw new Error('failed :(')
return 'hi ' + iam
}
API
Table of Contents
Payload
Payload.
id
Payload id.
Type: number
method
Method to call.
Type: any
args
The arguments passed to the method.
Type: Array<any>
Agent
Agent.
Type: any
debug
Whether or not to log debugging information.
Type: boolean
name
The name of the agent. Defaults to either 'alice' or 'bob' depending on the constructor used, Alice or Bob.
Type: string
send
The send method overriden by the user to any transport.
Type: PayloadMethod<Agent<B, A>>
deferredSend
Returns the send method. Used in contexts where it might change between sessions, like browser refresh/hot/livereload.
Type: function (): PayloadMethod<Agent<B, A>>
log
Overridable logging function. Defaults to console.log()
and prepends agent.name
.
Type: function (...args: Array<any>): void
AliceBob
AliceBob class.
Parameters
send
PayloadMethod<Agent<A, B>>? Thesend
payload method provided by the user. Will be called with a payload to be sent.
local
The local Agent.
Type: Agent<A, B>
remote
The remote Agent.
Type: Agent<B, A>
agents
Returns the agents tuple [alice, bob]
.
Example:
const [alice, bob] = new Alice<Local, Remote>().agents()
// to enable debugging on local (alice)
const [alice, bob] = new Alice<Local, Remote>().agents({ debug: true })
// use different names:
const [alice, bob] = new Alice<Local, Remote>().agents(
{ name: 'server', debug: true },
{ name: 'client' }
)
Parameters
local
(Partial<Agent<A, B>> | null)? Local agent overrides.remote
(Partial<Agent<B, A>> | null)? Remote agent overrides.
Alice
Extends AliceBob
Alice class.
Parameters
send
PayloadMethod<Agent<A, B>>? Thesend
payload method provided by the user. Will be called with a payload to be sent.
Bob
Extends AliceBob
Bob class.
Parameters
send
PayloadMethod<Agent<A, B>>? Thesend
payload method provided by the user. Will be called with a payload to be sent.
Contribute
All contributions are welcome!
License
MIT © 2021 stagas