@why-ts/irpc
v0.3.3
Published
Real-time, type-safe data flow without the hassle.
Downloads
10
Readme
Bi-directional reactive protocol
Real-time, type-safe data flow without the hassle.
Operations
- Method
Call a remote function (RPC) - Event
Listen to remote events - Observable
Subscribe to remote observable values
In the following documentation, the code that provide implementations is called server
and the code that consumes the implementation remotely is called client
Method
Allows client to invoke a function implemented in the server side, and optionally gets a value back.
To define and implement remotely-callable methods:
- invoke the irpc constructor with a generic type parameter
{local: {methods: MyMethods}}
- provide implementations in the
methods
field in the constructor
type MyMethods = { add(a:number, b:number) => number }
const server = init<{ local: { methods: MyMethods } }>(
transport,
{ methods: {add: (a, b) => a + b} }
);
To consume the remote methods:
- invoke the irpc constructor with a generic type parameter
{remote: {methods: MyMethods}}
- invoke the methods via
instance.remote.methods
const client = init<{ remote: { methods: MyMethods } }>(
transport,
{}
);
const sum = await client.remote.methods.add(2, 3); // sum = 5
Event
Allow clients to subscribe to events emitted from the server side.
To define and implement remotely-listenable events:
- invoke the irpc constructor with a generic type parameter
{local: {events: MyEvents}}
- emit the event via
instance.local.events
type MyEvents = { tick: number };
const server = init<{ local: { events: MyEvents } }>(
transport,
{}
);
// emit the event every second
setInterval(() => server.local.events.tick(Date.now()), 1000);
To listen to the remote events:
- invoke the irpc constructor with a generic type parameter
{remote: {events: MyEvents}}
- invoke the Events via
instance.remote.events
const client = init<{ remote: { events: MyEvents } }>(
transport,
{}
);
const unsubscribe = client.remote.events.tick((time) => console.log(time));
// unsubscribe later
unsubscribe();
Observable
Observable is very similar to Event, but it is lazy. The observable logic is only initiated on the first subscription and will not re-initiate for subsequent subscriptions. Also the teardown logic will only be run when the last subscriber unsubscribes.
To define and implement remotely-observable values:
- invoke the irpc constructor with a generic type parameter
{local: {observables: MyObservables}}
- provide implementations in the
observables
field in the constructor
type MyObservables = { foo: number };
const server = init<{ local: { observables: MyObservables } }>(
transport, {
observables: (callback) => {
const timer = setInterval(() => callback(new Date()), 50);
return () => clearInterval(timer);
},
});
To subscribe to the remote observables:
- invoke the irpc constructor with a generic type parameter
{remote: {observables: MyObservables}}
- invoke the Observables via
instance.remote.observables
const client = init<{ remote: { observables: MyObservables } }>(
transport,
{}
);
const unsubscribe = client.remote.observables.foo((val) => console.log(val));
// unsubscribe later
unsubscribe();
Untyped Access
Access the API in a untyped-manner via the DYNAMIC
symbol.
const sum = await client.remote.methods[DYNAMIC]('add', 2, 3); // sum = 5
Transport
Transport is the implementation that actually delivers the data. The implementation dictates what and how data types are "transmitted" to the remote side.
LocalBridgeTransport
In-memory tranport, mainly for testing. Since all data lives in the same program memory, all data types are supported.PostMessageTransport
Built on top of browser'spostMessage
API, mainly for communication between iframes or workers. Check the docs ofpostMessage
to find out what data types are supported. Thetransfer
option is also exposed so one can decide to transfer the data instead of cloning it.WebSocketTransport
: (coming soon)
TODO
- Validation of payload data type (command args and return values, etc)
- Allow parameters when subscribing to an observable
- Properly teardown/reset stuff when disconnect