capnweb 0.0.0-8a47045 → 0.0.0-9e499e2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -3
- package/dist/index-bun.cjs +3551 -0
- package/dist/index-bun.cjs.map +1 -0
- package/dist/index-bun.d.cts +125 -0
- package/dist/index-bun.d.ts +125 -0
- package/dist/index-bun.js +3534 -0
- package/dist/index-bun.js.map +1 -0
- package/dist/index-workers-CiDKhXAE.d.cts +445 -0
- package/dist/index-workers-CiDKhXAE.d.ts +445 -0
- package/dist/index-workers.cjs +874 -49
- package/dist/index-workers.cjs.map +1 -1
- package/dist/index-workers.d.cts +1 -1
- package/dist/index-workers.d.ts +1 -1
- package/dist/index-workers.js +874 -49
- package/dist/index-workers.js.map +1 -1
- package/dist/index.cjs +874 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -364
- package/dist/index.d.ts +2 -364
- package/dist/index.js +874 -49
- package/dist/index.js.map +1 -1
- package/package.json +26 -18
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Cap'n Web is a spiritual sibling to [Cap'n Proto](https://capnproto.org) (and is
|
|
|
6
6
|
* That said, it integrates nicely with TypeScript.
|
|
7
7
|
* Also unlike Cap'n Proto, Cap'n Web's underlying serialization is human-readable. In fact, it's just JSON, with a little pre-/post-processing.
|
|
8
8
|
* It works over HTTP, WebSocket, and postMessage() out-of-the-box, with the ability to extend it to other transports easily.
|
|
9
|
-
* It works in all major browsers, Cloudflare Workers, Node.js, and other modern JavaScript runtimes.
|
|
9
|
+
* It works in all major browsers, Cloudflare Workers, Node.js, Bun, Deno, and other modern JavaScript runtimes.
|
|
10
10
|
The whole thing compresses (minify+gzip) to under 10kB with no dependencies.
|
|
11
11
|
|
|
12
12
|
Cap'n Web is more expressive than almost every other RPC system, because it implements an object-capability RPC model. That means it:
|
|
@@ -201,13 +201,14 @@ The following types can be passed over RPC (in arguments or return values), and
|
|
|
201
201
|
* `Date`
|
|
202
202
|
* `Uint8Array`
|
|
203
203
|
* `Error` and its well-known subclasses
|
|
204
|
+
* `Blob`
|
|
205
|
+
* `ReadableStream` and `WritableStream`, with automatic flow control.
|
|
206
|
+
* `Headers`, `Request`, and `Response` from the Fetch API.
|
|
204
207
|
|
|
205
208
|
The following types are not supported as of this writing, but may be added in the future:
|
|
206
209
|
* `Map` and `Set`
|
|
207
210
|
* `ArrayBuffer` and typed arrays other than `Uint8Array`
|
|
208
211
|
* `RegExp`
|
|
209
|
-
* `ReadableStream` and `WritableStream`, with automatic flow control.
|
|
210
|
-
* `Headers`, `Request`, and `Response`
|
|
211
212
|
|
|
212
213
|
The following are intentionally NOT supported:
|
|
213
214
|
* Application-defined classes that do not extend `RpcTarget`.
|
|
@@ -305,6 +306,10 @@ The trick here is record-replay: On the calling side, Cap'n Web will invoke your
|
|
|
305
306
|
|
|
306
307
|
Since all of the not-yet-determined values seen by the callback are represented as `RpcPromise`s, the callback's behavior is deterministic. Any actual computation (arithmetic, branching, etc.) can't possibly use these promises as (meaningful) inputs, so would logically produce the same results for every invocation of the callback. Any such computation will actually end up being performed on the sending side, just once, with the results being imbued into the recording.
|
|
307
308
|
|
|
309
|
+
### Streaming with flow control
|
|
310
|
+
|
|
311
|
+
You may pass a `ReadableStream` or `WritableStream` over RPC. When doing so, the RPC system automatically creates an equivalent stream at the other end and pumps bytes (or arbitrarily-typed chunks) across. This is done in such a way as to ensure the available bandwidth is fully utilized while minimizing buffer bloat, by observing the bandwidth-delay product and applying backpressure when too much is written. Multiple streams can be sent across the same connection -- they will be multiplexed appropriately, similar to HTTP/2 stream multiplexing.
|
|
312
|
+
|
|
308
313
|
### Cloudflare Workers RPC interoperability
|
|
309
314
|
|
|
310
315
|
Cap'n Web works on any JavaScript platform. But, on Cloudflare Workers specifically, it's designed to play nicely with the [the built-in RPC system](https://blog.cloudflare.com/javascript-native-rpc/). The two have basically the same semantics, the only difference being that Workers RPC is a built-in API provided by the Workers Runtime, whereas Cap'n Web is implemented in pure JavaScript.
|
|
@@ -528,6 +533,14 @@ export default {
|
|
|
528
533
|
}
|
|
529
534
|
```
|
|
530
535
|
|
|
536
|
+
#### Compatibility with Workers' built-in RPC
|
|
537
|
+
|
|
538
|
+
Cloudflare Workers has long featured [a built-in RPC system with semantics similar to Cap'n Web](https://developers.cloudflare.com/workers/runtime-apis/rpc/).
|
|
539
|
+
|
|
540
|
+
Cap'n Web is designed to be compatible with Workers RPC, meaning you can pass Cap'n Web RPC stubs over Workers RPC and vice versa. The system will automatically wrap one stub type in the other and arrange to proxy calls.
|
|
541
|
+
|
|
542
|
+
For best compatibility, make sure to set your [Workers compatibilty date](https://developers.cloudflare.com/workers/configuration/compatibility-dates/) to at least `2026-01-20`, or enable the [compatibility flag](https://developers.cloudflare.com/workers/configuration/compatibility-flags/) `rpc_params_dup_stubs`. (As of this writing, `2026-01-20` is in the future, so you will need to use the flag for now.)
|
|
543
|
+
|
|
531
544
|
### HTTP server on Node.js
|
|
532
545
|
|
|
533
546
|
A server on Node.js is a bit more involved, due to the awkward handling of WebSockets in Node's HTTP library.
|
|
@@ -618,6 +631,45 @@ Deno.serve(async (req) => {
|
|
|
618
631
|
});
|
|
619
632
|
```
|
|
620
633
|
|
|
634
|
+
### HTTP server on Bun
|
|
635
|
+
|
|
636
|
+
Bun's server-side WebSocket API uses [callback-based handlers](https://bun.sh/docs/runtime/http/websockets) instead of the standard `addEventListener` interface. Cap'n Web provides `newBunWebSocketRpcHandler()` which returns a handler object you can pass directly to `Bun.serve()`.
|
|
637
|
+
|
|
638
|
+
```ts
|
|
639
|
+
import { RpcTarget, newBunWebSocketRpcHandler, newHttpBatchRpcResponse } from "capnweb";
|
|
640
|
+
|
|
641
|
+
class MyApiImpl extends RpcTarget implements MyApi {
|
|
642
|
+
// ... define API, same as above ...
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Create a WebSocket handler that manages RPC sessions automatically.
|
|
646
|
+
// The callback is invoked once per connection to create a fresh API instance.
|
|
647
|
+
let rpcHandler = newBunWebSocketRpcHandler(() => new MyApiImpl());
|
|
648
|
+
|
|
649
|
+
Bun.serve({
|
|
650
|
+
async fetch(req, server) {
|
|
651
|
+
let url = new URL(req.url);
|
|
652
|
+
if (url.pathname === "/api") {
|
|
653
|
+
// Upgrade WebSocket requests.
|
|
654
|
+
if (req.headers.get("upgrade")?.toLowerCase() === "websocket") {
|
|
655
|
+
if (server.upgrade(req)) return;
|
|
656
|
+
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Handle HTTP batch requests.
|
|
660
|
+
let response = await newHttpBatchRpcResponse(req, new MyApiImpl());
|
|
661
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
662
|
+
return response;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
return new Response("Not Found", { status: 404 });
|
|
666
|
+
},
|
|
667
|
+
|
|
668
|
+
// Pass the handler directly — no manual wiring needed.
|
|
669
|
+
websocket: rpcHandler,
|
|
670
|
+
});
|
|
671
|
+
```
|
|
672
|
+
|
|
621
673
|
### HTTP server on other runtimes
|
|
622
674
|
|
|
623
675
|
Every runtime does HTTP handling and WebSockets a little differently, although most modern runtimes use the standard `Request` and `Response` types from the Fetch API, as well as the standard `WebSocket` API. You should be able to use these two functions (exported by `capnweb`) to implement both HTTP batch and WebSocket handling on all platforms:
|
|
@@ -642,6 +694,10 @@ function newWebSocketRpcSession(
|
|
|
642
694
|
: Disposable;
|
|
643
695
|
```
|
|
644
696
|
|
|
697
|
+
### HTTP server using Hono
|
|
698
|
+
|
|
699
|
+
If your app is built on [Hono](https://hono.dev/) (on any runtime it supports), check out [`@hono/capnweb`](https://github.com/honojs/middleware/tree/main/packages/capnweb).
|
|
700
|
+
|
|
645
701
|
### MessagePort
|
|
646
702
|
|
|
647
703
|
Cap'n Web can also talk over MessagePorts. This can be used in a browser to talk to Web Workers, iframes, etc.
|