https://github.com/speedapi/driver-ts
API building toolkit - TypeScript support library
https://github.com/speedapi/driver-ts
api protocol serialization typescript
Last synced: about 2 months ago
JSON representation
API building toolkit - TypeScript support library
- Host: GitHub
- URL: https://github.com/speedapi/driver-ts
- Owner: speedapi
- License: bsd-3-clause
- Created: 2022-01-04T15:43:33.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2023-10-17T22:40:01.000Z (over 1 year ago)
- Last Synced: 2025-03-30T22:32:10.787Z (2 months ago)
- Topics: api, protocol, serialization, typescript
- Language: TypeScript
- Homepage: https://github.com/speedapi/info
- Size: 500 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
- Security: SECURITY.md
Awesome Lists containing this project
README





# SpeedAPI wire protocol implementation
This library provides a SpeedAPI implementation for JS and TS in all major environments (browser, node, etc.). Install it with:
```console
npm i @speedapi/driver
```Also install a transport level library according to your environment:
- `npm i @speedapi/node` for Node.JS
- don't see an appropriate transport here? [implement your own](#implementing-a-transport-layer)You don't need additional libraries if you just use the `Serializer` class.
**If you're using a BigInt polyfill**, add this as close to entry as possible:
```typescript
import * as speedapi from "@speedapi/driver";// if using a polyfill that provides a BigInt(string, radix) constructor
// (e.g. 'big-integer', 'bigint-polyfill'):
speedapi.repr.BigInteger.polyfillMode = "radix";// if using a polyfill that supports BigInt("0x"):
speedapi.repr.BigInteger.polyfillMode = "0x";// if not using a polyfill or using a polyfill that implements
// operators like native BigInts do (haven't seen one of those
// in the wild):
speedapi.repr.BigInteger.polyfillMode = "none";
// OR don't do anything, this is the default value
```# What is SpeedAPI?
It's a platform-agnostic API and serialization tool specifically geared towards high-throughput realtime applications. You can read more about its features [here](https://github.com/speedapi/info)# How do I use it?
There's a complete tutorial over [here](https://github.com/speedapi/info/tree/master/speedapi-tutorial).## Implementing a transport layer
You just have to write glue code between an implementation of your desired transport protocol and SpeedAPI. The requirements for the underlying protocol are as follows:
- for datagram/packet/frame-based protocols like UDP: reliable and unordered - packets _must not_ get lost, but their order _may_ be mixed up (note that UDP doesn't fit this description as it's unreliable)
- for stream-based protocols like TCP: reliable and ordered - bytes _must not_ get lost and their order _must not_ get mixed upYou will need to write 3 or 4 classes depending on the protocol nature:
- A `Link`, `Client` and `Server` if the protocol is two-partied in nature, meaning there are only two active devices on the bus/network (e.g. UART)
- A `Link`, `Client`, `Server` and `Listener` if one server can serve multiple clients (the overwhelming majority of Internet protocols)Note that for every client-to-server link there's a `Client` object on the client and a `Server` object on the server. There's only one `Listener` on the server.
### `Link`
This class acts as the reader/writer for SpeedAPI and should extend `Duplex`. Its only job is to read and write `Uint8Array`s. This class will be instantiated by you, therefore you can make the constructor of an arbitrary signature. Here's the skeleton for such a class:
```ts
import { Duplex } from "@speedapi/driver";
class MyLink extends Duplex {
constructor(/* pass what you need (e.g. a socket) */) { }
async write(data: Uint8Array): Promise { }
async read(cnt: number): Promise { }
async close(): Promise { }
}
```Alternatively, you can extend from `BufferedLink` if the underlying protocol implementation is event-driven, meaning it provides a "data has arrived" callback, but not a "read me N bytes" function.
```ts
import { BufferedLink } from "@speedapi/driver/transport/universal";
class MyLink extends BufferedLink {
constructor(/* again, pass what you need */) {
someProtocol.on("bytesArrived", (data: Uint8Array) => {
// feed BufferedLink data as it arrives
this.dataArrived(data);
});
}protected async dataWrite(data: Uint8Array): Promise { }
override async close(): Promise { }
}
```### `Server` and `Client`
Very thin wrappers that tell SpeedAPI about your `Link` while preserving type information.**Important**: if you omit type information (e.g. if you're using plain JS to implement these two classes), your IDE will not be able to provide suggestions.
```ts
import { SpecSpaceGen, Session } from "@speedapi/driver";
class MyClient extends Session {
constructor(specSpace: Gen /* any other arguments */) {
super(specSpace, new MyLink(/* your arguments */), "client");
}
}
class MyServer extends Session {
constructor(specSpace: Gen /* any other arguments */) {
super(specSpace, new MyLink(/* your arguments */), "server");
}
}
```### `Listener` (optional)
The notice from before applies here as well.
```ts
class MyListener {
constructor(specSpace: Gen, /* any other arguments */, callback: (server: MyServer) => void /* optional too */) {
someProtocol.on("clientConnected", (socket) => {
const session = new MyServer(specSpace, socket /* or any other arguments per your definition */);
callback(session);
});
}async close() { }
}
```# Testing
**Warning**: this repository uses a `pnpm` lock file, hence you can't substitute it for `npm` below.
```
git clone https://github.com/speedapi/driver-ts
cd driver-ts
pnpm i
pip3 install susc
pnpm test
```# TypeScript notice
This project relies _heavily_ on typing. As such, the language server gets misled into thinking that an expression type is `any` even though it's not just because the type is deeply nested. If you see a type error in your IDE that you think shouldn't be there or you're missing some autocomplete entries, try restarting your IDE and/or language server.