|
1 | 1 | --- |
2 | 2 | id: index |
3 | | -title: JavaScript |
4 | | -slug: /bindings/javascript |
| 3 | +title: TypeScript |
| 4 | +slug: /bindings/typescript |
5 | 5 | --- |
6 | 6 |
|
7 | 7 | import BindingBadge from '@site/src/components/BindingBadge'; |
8 | 8 |
|
9 | | -<BindingBadge label="JavaScript binding" tone="planned" /> |
| 9 | +<BindingBadge label="TypeScript binding" tone="alpha" /> |
10 | 10 |
|
11 | 11 | ## Status |
12 | 12 |
|
13 | | -Planned. Development will begin after the Python binding stabilizes. |
| 13 | +Alpha. The TypeScript binding mirrors the Python binding's feature set using NAPI-RS for the transport layer and pure TypeScript for the RPC framework. |
14 | 14 |
|
15 | | -## Timeline |
| 15 | +**Packages:** |
| 16 | +- `@aster-rpc/transport` — NAPI-RS native addon (Iroh P2P transport) |
| 17 | +- `@aster-rpc/aster` — Pure TypeScript RPC framework |
16 | 18 |
|
17 | | -The JavaScript binding is expected to follow the core systems-language bindings (Rust, JVM, .NET, Go) in priority. |
| 19 | +**Runtime support:** Node.js 20+, Bun 1.0+, Deno (via Node compat) |
18 | 20 |
|
19 | | -## Architecture |
20 | | - |
21 | | -Two approaches are under consideration: |
| 21 | +## Install |
22 | 22 |
|
23 | | -### Option A: WASM |
| 23 | +```bash |
| 24 | +# bun (recommended) |
| 25 | +bun add @aster-rpc/aster |
24 | 26 |
|
25 | | -Compile the `core` crate to WebAssembly for use in browsers and edge runtimes (Deno, Cloudflare Workers). |
| 27 | +# npm |
| 28 | +npm install @aster-rpc/aster |
26 | 29 |
|
27 | | -``` |
28 | | -JavaScript / TypeScript application code |
29 | | - | |
30 | | - v |
31 | | -@aster/client npm package Idiomatic JS API: decorators (TC39), |
32 | | - AsyncIterator for streaming, AbortSignal for cancellation |
33 | | - | |
34 | | - | wasm-bindgen |
35 | | - v |
36 | | -core.wasm Core crate compiled to WASM |
37 | | - | |
38 | | - v |
39 | | -iroh crates (WASM-compatible subset) |
| 30 | +# pnpm |
| 31 | +pnpm add @aster-rpc/aster |
40 | 32 | ``` |
41 | 33 |
|
42 | | -WASM provides the broadest reach (browsers, edge, Node.js) but may have limitations around direct UDP access. Browser-based consumers would connect via WebSocket-to-QUIC relay bridges. |
43 | | - |
44 | | -### Option B: N-API (Node.js native addon) |
| 34 | +The `@aster-rpc/transport` native addon is included as a dependency and auto-selects the correct binary for your platform. |
| 35 | + |
| 36 | +## Quick example |
| 37 | + |
| 38 | +```typescript |
| 39 | +import { Service, Rpc, WireType, AsterServer, createClient, LocalTransport, ServiceRegistry } from '@aster-rpc/aster'; |
| 40 | + |
| 41 | +// Define wire types |
| 42 | +@WireType("hello/HelloRequest") |
| 43 | +class HelloRequest { |
| 44 | + name = ""; |
| 45 | + constructor(init?: Partial<HelloRequest>) { if (init) Object.assign(this, init); } |
| 46 | +} |
| 47 | + |
| 48 | +@WireType("hello/HelloResponse") |
| 49 | +class HelloResponse { |
| 50 | + message = ""; |
| 51 | + constructor(init?: Partial<HelloResponse>) { if (init) Object.assign(this, init); } |
| 52 | +} |
| 53 | + |
| 54 | +// Define service |
| 55 | +@Service({ name: "Hello", version: 1 }) |
| 56 | +class HelloService { |
| 57 | + @Rpc() |
| 58 | + async sayHello(req: HelloRequest): Promise<HelloResponse> { |
| 59 | + return new HelloResponse({ message: `Hello, ${req.name}!` }); |
| 60 | + } |
| 61 | +} |
| 62 | + |
| 63 | +// Create and call |
| 64 | +const registry = new ServiceRegistry(); |
| 65 | +registry.register(new HelloService()); |
| 66 | +const transport = new LocalTransport(registry); |
| 67 | + |
| 68 | +const client = createClient(HelloService, transport); |
| 69 | +const result = await client.sayHello(new HelloRequest({ name: "TypeScript" })); |
| 70 | +console.log(result.message); // "Hello, TypeScript!" |
| 71 | +``` |
45 | 72 |
|
46 | | -Use N-API to expose the `core` crate as a native Node.js addon, similar to the Python PyO3 approach. |
| 73 | +## Architecture |
47 | 74 |
|
48 | 75 | ``` |
49 | | -JavaScript / TypeScript application code (Node.js) |
| 76 | +@aster-rpc/aster Pure TypeScript — decorators, client, server, |
| 77 | + interceptors, framing, protocol types |
50 | 78 | | |
51 | | - v |
52 | | -@aster/client npm package Idiomatic JS API |
| 79 | +@aster-rpc/transport NAPI-RS native addon — IrohNode, QUIC streams, |
| 80 | + | blobs, docs, gossip |
53 | 81 | | |
54 | | - | N-API |
55 | | - v |
56 | | -aster.node Native addon built from core crate |
| 82 | +aster_transport_core Shared Rust crate (same as Python binding) |
57 | 83 | | |
58 | | - v |
59 | | -iroh crates (full functionality) |
| 84 | +iroh crates QUIC, blobs, docs, gossip |
60 | 85 | ``` |
61 | 86 |
|
62 | | -N-API provides full access to the networking stack (including direct UDP) but is limited to Node.js and compatible runtimes. |
| 87 | +The TypeScript binding uses the same Rust core as the Python binding. Wire-level compatibility is guaranteed — a Python server can serve TypeScript clients and vice versa. |
| 88 | + |
| 89 | +## Key design decisions |
| 90 | + |
| 91 | +- **TC39 Stage 3 decorators** (`@Service`, `@Rpc`, `@ServerStream`, etc.) — compiles to standard JS, no runtime decorator support needed. |
| 92 | +- **Proxy-based client stubs** — `createClient(ServiceClass, transport)` returns a typed client with full IDE autocompletion. |
| 93 | +- **AsyncIterator/AsyncGenerator** for all streaming patterns. |
| 94 | +- **Fory XLANG** (`@apache-fory/core`) for cross-language wire compatibility with Python. |
| 95 | +- **NAPI-RS** for the native transport layer — same pattern as SWC, Prisma, Turbo. |
| 96 | + |
| 97 | +## Features |
63 | 98 |
|
64 | | -### Key design decisions |
| 99 | +All features from the Python binding are available: |
65 | 100 |
|
66 | | -- **TypeScript-first** with full type definitions. |
67 | | -- **TC39 decorators** (Stage 3) for service definitions where available; plain class registration as a fallback. |
68 | | -- **AsyncIterator** for streaming patterns. |
69 | | -- **AbortSignal** for cancellation and deadline propagation. |
70 | | -- **Apache Fory JavaScript** will handle XLANG serialization for wire compatibility. |
| 101 | +| Feature | Status | |
| 102 | +|---------|--------| |
| 103 | +| All 4 streaming patterns (unary, server, client, bidi) | Done | |
| 104 | +| TC39 decorators (@Service, @Rpc, @ServerStream, etc.) | Done | |
| 105 | +| Proxy-based typed client stubs | Done | |
| 106 | +| 9 interceptors (deadline, retry, metrics, rate-limit, etc.) | Done | |
| 107 | +| Contract identity (BLAKE3 hashing) | Done | |
| 108 | +| Session-scoped services (CALL/CANCEL multiplexing) | Done | |
| 109 | +| Structured logging (JSON/text, correlation, masking) | Done | |
| 110 | +| Health endpoints (/healthz, /readyz, /metrics) | Done | |
| 111 | +| Configuration (env vars, TOML) | Done | |
| 112 | +| IrohTransport (QUIC) | Done | |
| 113 | +| LocalTransport (in-process testing) | Done | |
71 | 114 |
|
72 | | -### Requirements |
| 115 | +## WASM (future) |
73 | 116 |
|
74 | | -- Node.js 18+ (for N-API) or any modern browser/edge runtime (for WASM). |
75 | | -- The native addon or WASM module for the target platform. |
| 117 | +Iroh supports WASM compilation (since v0.33) with all connections routed through relay servers. The `AsterTransport` interface is designed to support a future `IrohWasmTransport` for browser and edge runtimes. Connections remain end-to-end encrypted even via relay. |
76 | 118 |
|
77 | 119 | ## Further reading |
78 | 120 |
|
79 | | -- [Cross-Language Interop](/docs/examples/cross-language) for how wire types enable multi-language deployments |
| 121 | +- [TypeScript Quickstart](/docs/quickstart/typescript) — step-by-step guide |
| 122 | +- [TypeScript Server Reference](/docs/bindings/typescript/server) — AsterServer API |
| 123 | +- [TypeScript Client Reference](/docs/bindings/typescript/client) — createClient API |
| 124 | +- [Cross-Language Interop](/docs/examples/cross-language) — Python ↔ TypeScript |
0 commit comments