kkrpc 0.0.4 → 0.0.6
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/.turbo/turbo-test.log +21 -21
- package/README.md +16 -7
- package/__deno_tests__/deno-web-worker.test.ts +1 -1
- package/__tests__/bun.worker.test.ts +1 -1
- package/__tests__/http.test.ts +2 -2
- package/__tests__/scripts/deno-api.ts +1 -1
- package/__tests__/scripts/node-api.ts +1 -1
- package/__tests__/scripts/worker.ts +1 -1
- package/__tests__/stdio-rpc.test.ts +1 -1
- package/__tests__/websocket.test.ts +6 -4
- package/deno.json +1 -1
- package/package.json +1 -1
- package/scripts/prepare.ts +10 -4
- package/src/adapters/iframe.ts +5 -3
- package/src/channel.ts +6 -1
- package/src/http.ts +2 -2
- package/typedoc.json +1 -1
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,51 +1,51 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> kkrpc@ test /Users/hacker/Dev/projects/kkrpc/packages/kkrpc
|
|
3
|
+
> kkrpc@0.0.5 test /Users/hacker/Dev/projects/kkrpc/packages/kkrpc
|
|
4
4
|
> bun run scripts/test.ts
|
|
5
5
|
|
|
6
6
|
[0m[32mCheck[0m file:///Users/hacker/Dev/projects/kkrpc/packages/kkrpc/__deno_tests__/deno-web-worker.test.ts
|
|
7
|
+
[0m[32mCheck[0m file:///Users/hacker/Dev/projects/kkrpc/packages/kkrpc/__tests__/scripts/worker.ts
|
|
7
8
|
[0m[38;5;245mrunning 1 test from ./__deno_tests__/deno-web-worker.test.ts[0m
|
|
8
|
-
Call Worker Exposed API
|
|
9
|
-
[0m[32mok[0m [0m[38;5;245m(538ms)[0m
|
|
9
|
+
Call Worker Exposed API ... [0m[32mok[0m [0m[38;5;245m(377ms)[0m
|
|
10
10
|
|
|
11
|
-
[0m[32mok[0m | 1 passed | 0 failed [0m[38;5;245m(
|
|
11
|
+
[0m[32mok[0m | 1 passed | 0 failed [0m[38;5;245m(379ms)[0m
|
|
12
12
|
|
|
13
13
|
bun test v1.1.34 (5e5e7c60)
|
|
14
14
|
|
|
15
15
|
__tests__/http.test.ts:
|
|
16
|
-
(pass) HTTP RPC > echo service [4.
|
|
17
|
-
(pass) HTTP RPC > math operations [
|
|
18
|
-
(pass) HTTP RPC > concurrent calls [0.
|
|
19
|
-
(pass) HTTP RPC > stress test with concurrent calls [
|
|
20
|
-
(pass) HTTP RPC > error handling - invalid endpoint [0.
|
|
21
|
-
(pass) HTTP RPC > error handling - wrong method [0.
|
|
16
|
+
(pass) HTTP RPC > echo service [4.33ms]
|
|
17
|
+
(pass) HTTP RPC > math operations [1.16ms]
|
|
18
|
+
(pass) HTTP RPC > concurrent calls [0.59ms]
|
|
19
|
+
(pass) HTTP RPC > stress test with concurrent calls [200.21ms]
|
|
20
|
+
(pass) HTTP RPC > error handling - invalid endpoint [0.38ms]
|
|
21
|
+
(pass) HTTP RPC > error handling - wrong method [0.48ms]
|
|
22
22
|
|
|
23
23
|
__tests__/websocket.test.ts:
|
|
24
|
-
(pass) WebSocket RPC [
|
|
25
|
-
(pass) WebSocket concurrent connections [2.
|
|
24
|
+
(pass) WebSocket RPC [26.99ms]
|
|
25
|
+
(pass) WebSocket concurrent connections [2.45ms]
|
|
26
26
|
|
|
27
27
|
__tests__/bun.worker.test.ts:
|
|
28
|
-
(pass) Bun Worker [
|
|
28
|
+
(pass) Bun Worker [35.24ms]
|
|
29
29
|
|
|
30
30
|
__tests__/stdio-rpc.test.ts:
|
|
31
|
-
(pass) RPCChannel Test > DenoStdio [
|
|
32
|
-
(pass) RPCChannel Test > NodeStdio [
|
|
31
|
+
(pass) RPCChannel Test > DenoStdio [463.95ms]
|
|
32
|
+
(pass) RPCChannel Test > NodeStdio [339.55ms]
|
|
33
33
|
|
|
34
34
|
__tests__/serialization.test.ts:
|
|
35
|
-
(pass) Serializer > should serialize and deserialize a message [0.
|
|
36
|
-
(pass) Serializer > should serialize and deserialize a response [
|
|
35
|
+
(pass) Serializer > should serialize and deserialize a message [0.38ms]
|
|
36
|
+
(pass) Serializer > should serialize and deserialize a response [0.17ms]
|
|
37
37
|
---------------------------|---------|---------|-------------------
|
|
38
38
|
File | % Funcs | % Lines | Uncovered Line #s
|
|
39
39
|
---------------------------|---------|---------|-------------------
|
|
40
|
-
All files |
|
|
41
|
-
__tests__/scripts/api.ts |
|
|
40
|
+
All files | 77.97 | 70.24 |
|
|
41
|
+
__tests__/scripts/api.ts | 72.73 | 87.50 | 24,41-42
|
|
42
42
|
mod.ts | 100.00 | 100.00 |
|
|
43
43
|
src/adapters/deno.ts | 0.00 | 20.00 | 13-28,32-35
|
|
44
44
|
src/adapters/http.ts | 100.00 | 100.00 |
|
|
45
45
|
src/adapters/node.ts | 84.62 | 91.43 | 25,42-43
|
|
46
46
|
src/adapters/websocket.ts | 77.27 | 1.61 | 3-124
|
|
47
47
|
src/adapters/worker.ts | 50.00 | 1.77 | 3-113
|
|
48
|
-
src/channel.ts | 73.08 | 88.
|
|
48
|
+
src/channel.ts | 73.08 | 88.54 | 46,164,183-189,218-224,256-257
|
|
49
49
|
src/interface.ts | 100.00 | 100.00 |
|
|
50
50
|
src/serialization.ts | 100.00 | 81.82 | 28-29,46-47
|
|
51
51
|
src/utils.ts | 100.00 | 100.00 |
|
|
@@ -54,4 +54,4 @@ All files | 78.63 | 70.89 |
|
|
|
54
54
|
13 pass
|
|
55
55
|
0 fail
|
|
56
56
|
14640 expect() calls
|
|
57
|
-
Ran 13 tests across 5 files. [
|
|
57
|
+
Ran 13 tests across 5 files. [1118.00ms]
|
package/README.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# kkrpc
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/kkrpc)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
3
7
|
> A TypeScript-first RPC library that enables seamless bi-directional communication between processes.
|
|
4
8
|
> Call remote functions as if they were local, with full TypeScript type safety and autocompletion support.
|
|
5
9
|
|
|
10
|
+
- [JSR Package](https://jsr.io/@kunkun/kkrpc)
|
|
11
|
+
- [NPM Package](https://www.npmjs.com/package/kkrpc)
|
|
12
|
+
- [Documentation by JSR](https://jsr.io/@kunkun/kkrpc/doc)
|
|
13
|
+
- [Typedoc Documentation](https://kunkunsh.github.io/kkrpc/)
|
|
14
|
+
|
|
6
15
|
## Supported Environments
|
|
7
16
|
|
|
8
17
|
- stdio: RPC over stdio between any combinations of Node.js, Deno, Bun processes
|
|
@@ -49,15 +58,15 @@ import { NodeIo, RPCChannel } from "kkrpc"
|
|
|
49
58
|
import { apiMethods } from "./api.ts"
|
|
50
59
|
|
|
51
60
|
const stdio = new NodeIo(process.stdin, process.stdout)
|
|
52
|
-
const child = new RPCChannel(stdio, apiMethods)
|
|
61
|
+
const child = new RPCChannel(stdio, { expose: apiMethods })
|
|
53
62
|
```
|
|
54
63
|
|
|
55
64
|
```ts
|
|
56
65
|
import { spawn } from "child_process"
|
|
57
66
|
|
|
58
|
-
const
|
|
67
|
+
const worker = spawn("bun", ["scripts/node-api.ts"])
|
|
59
68
|
const io = new NodeIo(worker.stdout, worker.stdin)
|
|
60
|
-
const parent = new RPCChannel<{}, API>(io
|
|
69
|
+
const parent = new RPCChannel<{}, API>(io)
|
|
61
70
|
const api = parent.getAPI()
|
|
62
71
|
|
|
63
72
|
expect(await api.add(1, 2)).toBe(3)
|
|
@@ -70,7 +79,7 @@ import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "kkrpc"
|
|
|
70
79
|
|
|
71
80
|
const worker = new Worker(new URL("./scripts/worker.ts", import.meta.url).href, { type: "module" })
|
|
72
81
|
const io = new WorkerChildIO(worker)
|
|
73
|
-
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, apiMethods)
|
|
82
|
+
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, { expose: apiMethods })
|
|
74
83
|
const api = rpc.getAPI()
|
|
75
84
|
|
|
76
85
|
expect(await api.add(1, 2)).toBe(3)
|
|
@@ -80,7 +89,7 @@ expect(await api.add(1, 2)).toBe(3)
|
|
|
80
89
|
import { RPCChannel, WorkerParentIO, type DestroyableIoInterface } from "kkrpc"
|
|
81
90
|
|
|
82
91
|
const io: DestroyableIoInterface = new WorkerChildIO()
|
|
83
|
-
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, apiMethods)
|
|
92
|
+
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, { expose: apiMethods })
|
|
84
93
|
const api = rpc.getAPI()
|
|
85
94
|
|
|
86
95
|
const sum = await api.add(1, 2)
|
|
@@ -121,7 +130,7 @@ import { HTTPServerIO, RPCChannel } from "kkrpc"
|
|
|
121
130
|
import { api, type API } from "./api"
|
|
122
131
|
|
|
123
132
|
const serverIO = new HTTPServerIO()
|
|
124
|
-
const serverRPC = new RPCChannel<API, API>(serverIO, api)
|
|
133
|
+
const serverRPC = new RPCChannel<API, API>(serverIO, { expose: api })
|
|
125
134
|
|
|
126
135
|
const server = Bun.serve({
|
|
127
136
|
port: 3000,
|
|
@@ -148,7 +157,7 @@ import { api, type API } from "./api"
|
|
|
148
157
|
const clientIO = new HTTPClientIO({
|
|
149
158
|
url: "http://localhost:3000/rpc"
|
|
150
159
|
})
|
|
151
|
-
const clientRPC = new RPCChannel<{}, API>(clientIO, api)
|
|
160
|
+
const clientRPC = new RPCChannel<{}, API>(clientIO, { expose: api })
|
|
152
161
|
const clientAPI = clientRPC.getAPI()
|
|
153
162
|
|
|
154
163
|
const echoResponse = await clientAPI.echo("hello")
|
|
@@ -11,7 +11,7 @@ const worker = new Worker(new URL("../__tests__/scripts/worker.ts", import.meta.
|
|
|
11
11
|
type: "module"
|
|
12
12
|
})
|
|
13
13
|
const io = new WorkerParentIO(worker)
|
|
14
|
-
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, apiMethods)
|
|
14
|
+
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, { expose: apiMethods })
|
|
15
15
|
const api = rpc.getAPI()
|
|
16
16
|
|
|
17
17
|
Deno.test("Call Worker Exposed API", async () => {
|
|
@@ -4,7 +4,7 @@ import { apiMethods, type API } from "./scripts/api.ts"
|
|
|
4
4
|
|
|
5
5
|
const worker = new Worker(new URL("./scripts/worker.ts", import.meta.url).href, { type: "module" })
|
|
6
6
|
const io = new WorkerParentIO(worker)
|
|
7
|
-
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, apiMethods)
|
|
7
|
+
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, { expose: apiMethods })
|
|
8
8
|
const api = rpc.getAPI()
|
|
9
9
|
|
|
10
10
|
test("Bun Worker", async () => {
|
package/__tests__/http.test.ts
CHANGED
|
@@ -15,7 +15,7 @@ describe("HTTP RPC", () => {
|
|
|
15
15
|
beforeAll(() => {
|
|
16
16
|
// Create server
|
|
17
17
|
serverIO = new HTTPServerIO()
|
|
18
|
-
serverRPC = new RPCChannel<API, API>(serverIO, apiMethods)
|
|
18
|
+
serverRPC = new RPCChannel<API, API>(serverIO, { expose: apiMethods })
|
|
19
19
|
|
|
20
20
|
server = Bun.serve({
|
|
21
21
|
port: 3000,
|
|
@@ -36,7 +36,7 @@ describe("HTTP RPC", () => {
|
|
|
36
36
|
clientIO = new HTTPClientIO({
|
|
37
37
|
url: "http://localhost:3000/rpc"
|
|
38
38
|
})
|
|
39
|
-
const clientRPC = new RPCChannel<API, API>(clientIO, apiMethods)
|
|
39
|
+
const clientRPC = new RPCChannel<API, API>(clientIO, { expose: apiMethods })
|
|
40
40
|
api = clientRPC.getAPI()
|
|
41
41
|
})
|
|
42
42
|
|
|
@@ -2,7 +2,7 @@ import { RPCChannel, WorkerChildIO, type DestroyableIoInterface } from "../../mo
|
|
|
2
2
|
import { apiMethods, type API } from "./api.ts"
|
|
3
3
|
|
|
4
4
|
const io: DestroyableIoInterface = new WorkerChildIO()
|
|
5
|
-
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, apiMethods)
|
|
5
|
+
const rpc = new RPCChannel<API, API, DestroyableIoInterface>(io, { expose: apiMethods })
|
|
6
6
|
const api = rpc.getAPI()
|
|
7
7
|
|
|
8
8
|
// const randInt1 = Math.floor(Math.random() * 100)
|
|
@@ -21,7 +21,7 @@ async function runWorker(worker: ChildProcessWithoutNullStreams) {
|
|
|
21
21
|
|
|
22
22
|
// const stdio = createStdio();
|
|
23
23
|
const io = new NodeIo(worker.stdout, worker.stdin)
|
|
24
|
-
const rpc = new RPCChannel<{}, API>(io
|
|
24
|
+
const rpc = new RPCChannel<{}, API>(io)
|
|
25
25
|
const api = rpc.getAPI()
|
|
26
26
|
|
|
27
27
|
expect(await api.add(1, 2)).toEqual(3)
|
|
@@ -16,7 +16,7 @@ beforeAll(() => {
|
|
|
16
16
|
// Handle WebSocket connections
|
|
17
17
|
wss.on("connection", (ws: WebSocket) => {
|
|
18
18
|
const serverIO = new WebSocketServerIO(ws)
|
|
19
|
-
serverRPC = new RPCChannel<API, API>(serverIO, apiMethods)
|
|
19
|
+
serverRPC = new RPCChannel<API, API>(serverIO, { expose: apiMethods })
|
|
20
20
|
})
|
|
21
21
|
})
|
|
22
22
|
|
|
@@ -29,7 +29,9 @@ test("WebSocket RPC", async () => {
|
|
|
29
29
|
url: `ws://localhost:${PORT}`
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
-
const clientRPC = new RPCChannel<API, API, DestroyableIoInterface>(clientIO,
|
|
32
|
+
const clientRPC = new RPCChannel<API, API, DestroyableIoInterface>(clientIO, {
|
|
33
|
+
expose: apiMethods
|
|
34
|
+
})
|
|
33
35
|
const api = clientRPC.getAPI()
|
|
34
36
|
|
|
35
37
|
// Test individual calls
|
|
@@ -70,7 +72,7 @@ test("WebSocket RPC", async () => {
|
|
|
70
72
|
// url: `ws://localhost:${invalidPort}`
|
|
71
73
|
// })
|
|
72
74
|
|
|
73
|
-
// const clientRPC = new RPCChannel<{}, API, DestroyableIoInterface>(clientIO
|
|
75
|
+
// const clientRPC = new RPCChannel<{}, API, DestroyableIoInterface>(clientIO)
|
|
74
76
|
// const api = clientRPC.getAPI()
|
|
75
77
|
// expect(() => api.add(1, 2)).toThrow()
|
|
76
78
|
// clientIO.destroy()
|
|
@@ -84,7 +86,7 @@ test("WebSocket concurrent connections", async () => {
|
|
|
84
86
|
})
|
|
85
87
|
return {
|
|
86
88
|
io: clientIO,
|
|
87
|
-
rpc: new RPCChannel<{}, API, DestroyableIoInterface>(clientIO
|
|
89
|
+
rpc: new RPCChannel<{}, API, DestroyableIoInterface>(clientIO)
|
|
88
90
|
}
|
|
89
91
|
})
|
|
90
92
|
|
package/deno.json
CHANGED
package/package.json
CHANGED
package/scripts/prepare.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { $ } from "bun"
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
// check if CF_PAGES is set to 1
|
|
4
|
+
const isCFPages = process.env.CF_PAGES === "1"
|
|
5
|
+
if (isCFPages) {
|
|
6
|
+
process.exit(0)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const denoTypes = await $`deno types`.text()
|
|
10
|
+
// filter out the line with no-default-lib
|
|
11
|
+
const denoTypesFiltered = denoTypes.split("\n").filter((line) => !line.includes("no-default-lib"))
|
|
12
|
+
await Bun.write("./deno.d.ts", denoTypesFiltered.join("\n"))
|
package/src/adapters/iframe.ts
CHANGED
|
@@ -28,10 +28,12 @@ export class IframeParentIO implements DestroyableIoInterface {
|
|
|
28
28
|
/**
|
|
29
29
|
* @example
|
|
30
30
|
* ```ts
|
|
31
|
-
* const io = new IframeParentIO(iframeRef.contentWindow)
|
|
31
|
+
* const io = new IframeParentIO(iframeRef.contentWindow);
|
|
32
32
|
* const rpc = new RPCChannel(io, {
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* expose: {
|
|
34
|
+
* add: (a: number, b: number) => Promise.resolve(a + b),
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
35
37
|
* ```
|
|
36
38
|
*/
|
|
37
39
|
constructor(private targetWindow: Window) {
|
package/src/channel.ts
CHANGED
|
@@ -31,11 +31,15 @@ export class RPCChannel<
|
|
|
31
31
|
private callbackCache: Map<CallbackFunction, string> = new Map()
|
|
32
32
|
private count: number = 0
|
|
33
33
|
private messageStr = ""
|
|
34
|
+
private apiImplementation?: LocalAPI
|
|
34
35
|
|
|
35
36
|
constructor(
|
|
36
37
|
private io: Io,
|
|
37
|
-
|
|
38
|
+
options?: {
|
|
39
|
+
expose?: LocalAPI
|
|
40
|
+
}
|
|
38
41
|
) {
|
|
42
|
+
this.apiImplementation = options?.expose
|
|
39
43
|
this.listen()
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -134,6 +138,7 @@ export class RPCChannel<
|
|
|
134
138
|
|
|
135
139
|
// Split the method path and traverse the API implementation
|
|
136
140
|
const methodPath = method.split(".")
|
|
141
|
+
if (!this.apiImplementation) return
|
|
137
142
|
let target: any = this.apiImplementation
|
|
138
143
|
|
|
139
144
|
// Traverse the object path
|
package/src/http.ts
CHANGED
|
@@ -8,7 +8,7 @@ export function createHttpClient<API extends Record<string, any>>(
|
|
|
8
8
|
channel: RPCChannel<{}, API, IoInterface>
|
|
9
9
|
api: API
|
|
10
10
|
} {
|
|
11
|
-
const channel = new RPCChannel<{}, API>(new HTTPClientIO({ url })
|
|
11
|
+
const channel = new RPCChannel<{}, API>(new HTTPClientIO({ url }))
|
|
12
12
|
const api = channel.getAPI()
|
|
13
13
|
return { channel, api }
|
|
14
14
|
}
|
|
@@ -17,7 +17,7 @@ export function createHttpHandler<API extends Record<string, any>>(
|
|
|
17
17
|
api: API
|
|
18
18
|
): { handleRequest: (data: string) => Promise<string> } {
|
|
19
19
|
const serverIO = new HTTPServerIO()
|
|
20
|
-
new RPCChannel<{}, API>(serverIO, api)
|
|
20
|
+
new RPCChannel<{}, API>(serverIO, { expose: api })
|
|
21
21
|
return serverIO
|
|
22
22
|
}
|
|
23
23
|
export { RPCChannel } from "./channel"
|