kkrpc 0.2.0-beta.2 → 0.2.1
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 +79 -4
- package/dist/browser-mod.cjs +22 -0
- package/dist/browser-mod.d.cts +2 -1
- package/dist/browser-mod.d.ts +2 -1
- package/dist/browser-mod.js +3 -1
- package/dist/chunk-GRCUBSPR.js +27 -0
- package/dist/{chunk-XU7DWWSJ.js → chunk-KZFPA2BM.js} +22 -1
- package/dist/deno-mod.cjs +355 -0
- package/dist/deno-mod.d.cts +19 -0
- package/dist/deno-mod.d.ts +19 -0
- package/dist/deno-mod.js +10 -0
- package/dist/mod.cjs +51 -6
- package/dist/mod.d.cts +22 -18
- package/dist/mod.d.ts +22 -18
- package/dist/mod.js +29 -26
- package/dist/{worker-DiYJxxHW.d.ts → tauri-CRNRbu3f.d.cts} +13 -2
- package/dist/{worker-72MNjMgj.d.cts → tauri-PdcZTVUI.d.ts} +13 -2
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# kkrpc
|
|
2
2
|
|
|
3
|
+
> This project is created for building extension system for a Tauri app (https://github.com/kunkunsh/kunkun).
|
|
4
|
+
>
|
|
5
|
+
> It's potential can be used in other types of apps, so I open sourced it as a standalone package.
|
|
6
|
+
|
|
3
7
|
[](https://www.npmjs.com/package/kkrpc)
|
|
4
8
|
[](https://jsr.io/@kunkun/kkrpc)
|
|
5
9
|

|
|
@@ -12,11 +16,12 @@
|
|
|
12
16
|
- [Documentation by JSR](https://jsr.io/@kunkun/kkrpc/doc)
|
|
13
17
|
- [Typedoc Documentation](https://kunkunsh.github.io/kkrpc/)
|
|
14
18
|
|
|
15
|
-
[Excalidraw Diagrams](https://excalidraw.com/#json=
|
|
19
|
+
[Excalidraw Diagrams](https://excalidraw.com/#json=xp6GbAJVAx3nU-h3PhaxW,oYBNvYmCRsQ2XR3MQo73Ug)
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
<img src="https://imgur.com/vR3Lmv0.png" style="max-height: 200px;"/>
|
|
22
|
+
<img src="https://i.imgur.com/zmOHNfu.png" style="max-height: 250px;"/>
|
|
23
|
+
<img src="https://imgur.com/u728aVv.png" style="max-height: 400px;"/>
|
|
24
|
+
<img src="https://i.imgur.com/Gu7jH1v.png" style="max-height: 300px;"/>
|
|
20
25
|
|
|
21
26
|
## Supported Environments
|
|
22
27
|
|
|
@@ -220,3 +225,73 @@ const api = rpc.getAPI()
|
|
|
220
225
|
const data = await api.getData()
|
|
221
226
|
console.log(data) // { message: "Hello from background!" }
|
|
222
227
|
```
|
|
228
|
+
|
|
229
|
+
### Tauri Example
|
|
230
|
+
|
|
231
|
+
Call functions in bun/node/deno processes from Tauri app with JS/TS.
|
|
232
|
+
|
|
233
|
+
It allows you to call any JS/TS code in Deno/Bun/Node processes from Tauri app, just like using Electron.
|
|
234
|
+
|
|
235
|
+
Seamless integration with Tauri's official shell plugin and [unlocked shellx plugin](https://github.com/HuakunShen/tauri-plugin-shellx).
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
import { RPCChannel, TauriShellStdio } from "kkrpc/browser"
|
|
239
|
+
import { Child, Command } from "@tauri-apps/plugin-shell"
|
|
240
|
+
|
|
241
|
+
const localAPIImplementation = {
|
|
242
|
+
add: (a: number, b: number) => Promise.resolve(a + b)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async function spawnCmd(runtime: "deno" | "bun" | "node") {
|
|
246
|
+
let cmd: Command<string>
|
|
247
|
+
let process = Child | null = null
|
|
248
|
+
|
|
249
|
+
if (runtime === "deno") {
|
|
250
|
+
cmd = Command.create("deno", ["run", "-A", scriptPath])
|
|
251
|
+
process = await cmd.spawn()
|
|
252
|
+
} else if (runtime === "bun") {
|
|
253
|
+
cmd = Command.create("bun", [scriptPath])
|
|
254
|
+
process = await cmd.spawn()
|
|
255
|
+
} else if (runtime === "node") {
|
|
256
|
+
cmd = Command.create("node", [scriptPath])
|
|
257
|
+
process = await cmd.spawn()
|
|
258
|
+
} else {
|
|
259
|
+
throw new Error(`Invalid runtime: ${runtime}, pick either deno or bun`)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// monitor stdout/stderr/close/error for debugging and error handling
|
|
263
|
+
cmd.stdout.on("data", (data) => {
|
|
264
|
+
console.log("stdout", data)
|
|
265
|
+
})
|
|
266
|
+
cmd.stderr.on("data", (data) => {
|
|
267
|
+
console.warn("stderr", data)
|
|
268
|
+
})
|
|
269
|
+
cmd.on("close", (code) => {
|
|
270
|
+
console.log("close", code)
|
|
271
|
+
})
|
|
272
|
+
cmd.on("error", (err) => {
|
|
273
|
+
console.error("error", err)
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
const stdio = new TauriShellStdio(cmd.stdout, process)
|
|
277
|
+
const stdioRPC = new RPCChannel<typeof localAPIImplementation, RemoteAPI>(stdio, {
|
|
278
|
+
expose: localAPIImplementation
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
const api = stdioRPC.getAPI();
|
|
282
|
+
await api
|
|
283
|
+
.add(1, 2)
|
|
284
|
+
.then((result) => {
|
|
285
|
+
console.log("result", result)
|
|
286
|
+
})
|
|
287
|
+
.catch((err) => {
|
|
288
|
+
console.error(err)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
process?.kill()
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
I provided a sample tauri app in `examples/tauri-demo`.
|
|
296
|
+
|
|
297
|
+

|
package/dist/browser-mod.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(browser_mod_exports, {
|
|
|
35
35
|
IframeChildIO: () => IframeChildIO,
|
|
36
36
|
IframeParentIO: () => IframeParentIO,
|
|
37
37
|
RPCChannel: () => RPCChannel,
|
|
38
|
+
TauriShellStdio: () => TauriShellStdio,
|
|
38
39
|
WorkerChildIO: () => WorkerChildIO,
|
|
39
40
|
WorkerParentIO: () => WorkerParentIO,
|
|
40
41
|
deserializeMessage: () => deserializeMessage,
|
|
@@ -343,6 +344,26 @@ var IframeChildIO = class {
|
|
|
343
344
|
}
|
|
344
345
|
};
|
|
345
346
|
|
|
347
|
+
// src/adapters/tauri.ts
|
|
348
|
+
var import_plugin_shell = require("@tauri-apps/plugin-shell");
|
|
349
|
+
var TauriShellStdio = class {
|
|
350
|
+
constructor(readStream, childProcess) {
|
|
351
|
+
this.readStream = readStream;
|
|
352
|
+
this.childProcess = childProcess;
|
|
353
|
+
}
|
|
354
|
+
name = "tauri-shell-stdio";
|
|
355
|
+
read() {
|
|
356
|
+
return new Promise((resolve, reject) => {
|
|
357
|
+
this.readStream.on("data", (chunk) => {
|
|
358
|
+
resolve(chunk);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async write(data) {
|
|
363
|
+
return this.childProcess.write(data + "\n");
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
|
|
346
367
|
// src/interface.ts
|
|
347
368
|
var import_node_buffer = require("buffer");
|
|
348
369
|
|
|
@@ -656,6 +677,7 @@ var RPCChannel = class {
|
|
|
656
677
|
IframeChildIO,
|
|
657
678
|
IframeParentIO,
|
|
658
679
|
RPCChannel,
|
|
680
|
+
TauriShellStdio,
|
|
659
681
|
WorkerChildIO,
|
|
660
682
|
WorkerParentIO,
|
|
661
683
|
deserializeMessage,
|
package/dist/browser-mod.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { a as WorkerChildIO, W as WorkerParentIO } from './
|
|
1
|
+
export { T as TauriShellStdio, a as WorkerChildIO, W as WorkerParentIO } from './tauri-CRNRbu3f.cjs';
|
|
2
2
|
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.cjs';
|
|
3
3
|
import { D as DestroyableIoInterface } from './channel-D6ZClufP.cjs';
|
|
4
4
|
export { I as IoInterface, R as RPCChannel } from './channel-D6ZClufP.cjs';
|
|
5
|
+
import '@tauri-apps/plugin-shell';
|
|
5
6
|
import 'node:buffer';
|
|
6
7
|
|
|
7
8
|
/**
|
package/dist/browser-mod.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { a as WorkerChildIO, W as WorkerParentIO } from './
|
|
1
|
+
export { T as TauriShellStdio, a as WorkerChildIO, W as WorkerParentIO } from './tauri-PdcZTVUI.js';
|
|
2
2
|
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.js';
|
|
3
3
|
import { D as DestroyableIoInterface } from './channel-D6ZClufP.js';
|
|
4
4
|
export { I as IoInterface, R as RPCChannel } from './channel-D6ZClufP.js';
|
|
5
|
+
import '@tauri-apps/plugin-shell';
|
|
5
6
|
import 'node:buffer';
|
|
6
7
|
|
|
7
8
|
/**
|
package/dist/browser-mod.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
TauriShellStdio,
|
|
2
3
|
WorkerChildIO,
|
|
3
4
|
WorkerParentIO
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KZFPA2BM.js";
|
|
5
6
|
import {
|
|
6
7
|
ChromeBackgroundIO,
|
|
7
8
|
ChromeContentIO
|
|
@@ -154,6 +155,7 @@ export {
|
|
|
154
155
|
IframeChildIO,
|
|
155
156
|
IframeParentIO,
|
|
156
157
|
RPCChannel,
|
|
158
|
+
TauriShellStdio,
|
|
157
159
|
WorkerChildIO,
|
|
158
160
|
WorkerParentIO,
|
|
159
161
|
deserializeMessage,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/adapters/deno.ts
|
|
2
|
+
import { Buffer } from "node:buffer";
|
|
3
|
+
var DenoIo = class {
|
|
4
|
+
constructor(readStream) {
|
|
5
|
+
this.readStream = readStream;
|
|
6
|
+
this.reader = this.readStream.getReader();
|
|
7
|
+
}
|
|
8
|
+
reader;
|
|
9
|
+
name = "deno-io";
|
|
10
|
+
async read() {
|
|
11
|
+
const { value, done } = await this.reader.read();
|
|
12
|
+
if (done) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return Buffer.from(value);
|
|
16
|
+
}
|
|
17
|
+
write(data) {
|
|
18
|
+
const encoder = new TextEncoder();
|
|
19
|
+
const encodedData = encoder.encode(data + "\n");
|
|
20
|
+
Deno.stdout.writeSync(encodedData);
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
DenoIo
|
|
27
|
+
};
|
|
@@ -82,7 +82,28 @@ var WorkerChildIO = class {
|
|
|
82
82
|
}
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
+
// src/adapters/tauri.ts
|
|
86
|
+
import "@tauri-apps/plugin-shell";
|
|
87
|
+
var TauriShellStdio = class {
|
|
88
|
+
constructor(readStream, childProcess) {
|
|
89
|
+
this.readStream = readStream;
|
|
90
|
+
this.childProcess = childProcess;
|
|
91
|
+
}
|
|
92
|
+
name = "tauri-shell-stdio";
|
|
93
|
+
read() {
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
this.readStream.on("data", (chunk) => {
|
|
96
|
+
resolve(chunk);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async write(data) {
|
|
101
|
+
return this.childProcess.write(data + "\n");
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
85
105
|
export {
|
|
86
106
|
WorkerParentIO,
|
|
87
|
-
WorkerChildIO
|
|
107
|
+
WorkerChildIO,
|
|
108
|
+
TauriShellStdio
|
|
88
109
|
};
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// deno-mod.ts
|
|
31
|
+
var deno_mod_exports = {};
|
|
32
|
+
__export(deno_mod_exports, {
|
|
33
|
+
DenoIo: () => DenoIo,
|
|
34
|
+
RPCChannel: () => RPCChannel
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(deno_mod_exports);
|
|
37
|
+
|
|
38
|
+
// src/adapters/deno.ts
|
|
39
|
+
var import_node_buffer = require("buffer");
|
|
40
|
+
var DenoIo = class {
|
|
41
|
+
constructor(readStream) {
|
|
42
|
+
this.readStream = readStream;
|
|
43
|
+
this.reader = this.readStream.getReader();
|
|
44
|
+
}
|
|
45
|
+
reader;
|
|
46
|
+
name = "deno-io";
|
|
47
|
+
async read() {
|
|
48
|
+
const { value, done } = await this.reader.read();
|
|
49
|
+
if (done) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return import_node_buffer.Buffer.from(value);
|
|
53
|
+
}
|
|
54
|
+
write(data) {
|
|
55
|
+
const encoder = new TextEncoder();
|
|
56
|
+
const encodedData = encoder.encode(data + "\n");
|
|
57
|
+
Deno.stdout.writeSync(encodedData);
|
|
58
|
+
return Promise.resolve();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/serialization.ts
|
|
63
|
+
var import_superjson = __toESM(require("superjson"), 1);
|
|
64
|
+
function serializeMessage(message) {
|
|
65
|
+
return import_superjson.default.stringify(message) + "\n";
|
|
66
|
+
}
|
|
67
|
+
function deserializeMessage(message) {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
try {
|
|
70
|
+
const parsed = import_superjson.default.parse(message);
|
|
71
|
+
resolve(parsed);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error("failed to parse message", typeof message, message, error);
|
|
74
|
+
reject(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/utils.ts
|
|
80
|
+
function generateUUID() {
|
|
81
|
+
return new Array(4).fill(0).map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)).join("-");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/channel.ts
|
|
85
|
+
var RPCChannel = class {
|
|
86
|
+
constructor(io, options) {
|
|
87
|
+
this.io = io;
|
|
88
|
+
this.apiImplementation = options?.expose;
|
|
89
|
+
this.listen();
|
|
90
|
+
}
|
|
91
|
+
pendingRequests = {};
|
|
92
|
+
callbacks = {};
|
|
93
|
+
callbackCache = /* @__PURE__ */ new Map();
|
|
94
|
+
count = 0;
|
|
95
|
+
messageStr = "";
|
|
96
|
+
apiImplementation;
|
|
97
|
+
/**
|
|
98
|
+
* Exposes a local API implementation that can be called remotely
|
|
99
|
+
* @param api The local API implementation to expose
|
|
100
|
+
*/
|
|
101
|
+
expose(api) {
|
|
102
|
+
this.apiImplementation = api;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Returns the IO interface used by this channel
|
|
106
|
+
* @returns The IO interface instance
|
|
107
|
+
*/
|
|
108
|
+
getIO() {
|
|
109
|
+
return this.io;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Listens for incoming messages on the IO interface
|
|
113
|
+
* Handles message buffering and parsing
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
async listen() {
|
|
117
|
+
while (true) {
|
|
118
|
+
const buffer = await this.io.read();
|
|
119
|
+
if (!buffer) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const bufferStr = buffer.toString("utf-8");
|
|
123
|
+
if (bufferStr.trim().length === 0) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
this.messageStr += bufferStr;
|
|
127
|
+
const lastChar = this.messageStr[this.messageStr.length - 1];
|
|
128
|
+
const msgsSplit = this.messageStr.split("\n");
|
|
129
|
+
const msgs = lastChar === "\n" ? msgsSplit : msgsSplit.slice(0, -1);
|
|
130
|
+
this.messageStr = lastChar === "\n" ? "" : msgsSplit.at(-1) ?? "";
|
|
131
|
+
for (const msgStr of msgs.map((msg) => msg.trim()).filter(Boolean)) {
|
|
132
|
+
if (msgStr.startsWith("{")) {
|
|
133
|
+
this.handleMessageStr(msgStr);
|
|
134
|
+
} else {
|
|
135
|
+
console.log(`(kkrpc stdout passthrough):`, msgStr);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Handles a single message string by parsing and routing it
|
|
142
|
+
* @param messageStr The message string to handle
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
async handleMessageStr(messageStr) {
|
|
146
|
+
this.count++;
|
|
147
|
+
return deserializeMessage(messageStr).then((parsedMessage) => {
|
|
148
|
+
if (parsedMessage.type === "response") {
|
|
149
|
+
this.handleResponse(parsedMessage);
|
|
150
|
+
} else if (parsedMessage.type === "request") {
|
|
151
|
+
this.handleRequest(parsedMessage);
|
|
152
|
+
} else if (parsedMessage.type === "callback") {
|
|
153
|
+
this.handleCallback(parsedMessage);
|
|
154
|
+
} else {
|
|
155
|
+
console.error("received unknown message type", parsedMessage, typeof parsedMessage);
|
|
156
|
+
}
|
|
157
|
+
}).catch((err) => {
|
|
158
|
+
console.log(`(kkrpc stdout passthrough):`, messageStr);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Calls a method on the remote API
|
|
163
|
+
* @param method The name of the method to call
|
|
164
|
+
* @param args Arguments to pass to the remote method
|
|
165
|
+
* @returns Promise that resolves with the result of the remote call
|
|
166
|
+
*/
|
|
167
|
+
callMethod(method, args) {
|
|
168
|
+
return new Promise((resolve, reject) => {
|
|
169
|
+
const messageId = generateUUID();
|
|
170
|
+
this.pendingRequests[messageId] = { resolve, reject };
|
|
171
|
+
const callbackIds = [];
|
|
172
|
+
const processedArgs = args.map((arg) => {
|
|
173
|
+
if (typeof arg === "function") {
|
|
174
|
+
let callbackId = this.callbackCache.get(arg);
|
|
175
|
+
if (!callbackId) {
|
|
176
|
+
callbackId = generateUUID();
|
|
177
|
+
this.callbacks[callbackId] = arg;
|
|
178
|
+
this.callbackCache.set(arg, callbackId);
|
|
179
|
+
} else {
|
|
180
|
+
}
|
|
181
|
+
callbackIds.push(callbackId);
|
|
182
|
+
return `__callback__${callbackId}`;
|
|
183
|
+
}
|
|
184
|
+
return arg;
|
|
185
|
+
});
|
|
186
|
+
const message = {
|
|
187
|
+
id: messageId,
|
|
188
|
+
method,
|
|
189
|
+
args: processedArgs,
|
|
190
|
+
type: "request",
|
|
191
|
+
callbackIds: callbackIds.length > 0 ? callbackIds : void 0
|
|
192
|
+
};
|
|
193
|
+
this.io.write(serializeMessage(message));
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Handles responses received from remote method calls
|
|
198
|
+
* @param response The response message to handle
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
handleResponse(response) {
|
|
202
|
+
const { id } = response;
|
|
203
|
+
const { result, error } = response.args;
|
|
204
|
+
if (this.pendingRequests[id]) {
|
|
205
|
+
if (error) {
|
|
206
|
+
this.pendingRequests[id].reject(new Error(error));
|
|
207
|
+
} else {
|
|
208
|
+
this.pendingRequests[id].resolve(result);
|
|
209
|
+
}
|
|
210
|
+
delete this.pendingRequests[id];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Handles incoming method call requests from the remote endpoint
|
|
215
|
+
* @param request The request message to handle
|
|
216
|
+
* @private
|
|
217
|
+
*/
|
|
218
|
+
handleRequest(request) {
|
|
219
|
+
const { id, method, args } = request;
|
|
220
|
+
const methodPath = method.split(".");
|
|
221
|
+
if (!this.apiImplementation) return;
|
|
222
|
+
let target = this.apiImplementation;
|
|
223
|
+
for (let i = 0; i < methodPath.length - 1; i++) {
|
|
224
|
+
target = target[methodPath[i]];
|
|
225
|
+
if (!target) {
|
|
226
|
+
this.sendError(id, `Method path ${method} not found at ${methodPath[i]}`);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const finalMethod = methodPath[methodPath.length - 1];
|
|
231
|
+
const targetMethod = target[finalMethod];
|
|
232
|
+
if (typeof targetMethod !== "function") {
|
|
233
|
+
this.sendError(id, `Method ${method} is not a function`);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const processedArgs = args.map((arg) => {
|
|
237
|
+
if (typeof arg === "string" && arg.startsWith("__callback__")) {
|
|
238
|
+
const callbackId = arg.slice(12);
|
|
239
|
+
return (...callbackArgs) => {
|
|
240
|
+
this.invokeCallback(callbackId, callbackArgs);
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
return arg;
|
|
244
|
+
});
|
|
245
|
+
try {
|
|
246
|
+
const result = targetMethod.apply(target, processedArgs);
|
|
247
|
+
Promise.resolve(result).then((res) => {
|
|
248
|
+
return this.sendResponse(id, res);
|
|
249
|
+
}).catch((err) => this.sendError(id, err.message));
|
|
250
|
+
} catch (error) {
|
|
251
|
+
this.sendError(id, error.message ?? error.toString());
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Invokes a callback on the remote endpoint
|
|
256
|
+
* @param callbackId The ID of the callback to invoke
|
|
257
|
+
* @param args Arguments to pass to the callback
|
|
258
|
+
* @private
|
|
259
|
+
*/
|
|
260
|
+
invokeCallback(callbackId, args) {
|
|
261
|
+
const message = {
|
|
262
|
+
id: generateUUID(),
|
|
263
|
+
method: callbackId,
|
|
264
|
+
args,
|
|
265
|
+
type: "callback"
|
|
266
|
+
};
|
|
267
|
+
this.io.write(serializeMessage(message));
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Handles callback invocations received from the remote endpoint
|
|
271
|
+
* @param message The callback message to handle
|
|
272
|
+
* @private
|
|
273
|
+
*/
|
|
274
|
+
handleCallback(message) {
|
|
275
|
+
const { method: callbackId, args } = message;
|
|
276
|
+
const callback = this.callbacks[callbackId];
|
|
277
|
+
if (callback) {
|
|
278
|
+
callback(...args);
|
|
279
|
+
} else {
|
|
280
|
+
console.error(`Callback with id ${callbackId} not found`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Sends a successful response back to the remote endpoint
|
|
285
|
+
* @param id The ID of the request being responded to
|
|
286
|
+
* @param result The result to send back
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
sendResponse(id, result) {
|
|
290
|
+
const response = {
|
|
291
|
+
id,
|
|
292
|
+
method: "",
|
|
293
|
+
args: { result },
|
|
294
|
+
type: "response"
|
|
295
|
+
};
|
|
296
|
+
this.io.write(serializeMessage(response));
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Sends an error response back to the remote endpoint
|
|
300
|
+
* @param id The ID of the request being responded to
|
|
301
|
+
* @param error The error message to send back
|
|
302
|
+
* @private
|
|
303
|
+
*/
|
|
304
|
+
sendError(id, error) {
|
|
305
|
+
const response = {
|
|
306
|
+
id,
|
|
307
|
+
method: "",
|
|
308
|
+
args: { error },
|
|
309
|
+
type: "response"
|
|
310
|
+
};
|
|
311
|
+
this.io.write(serializeMessage(response));
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Creates a nested proxy object for chaining remote method calls
|
|
315
|
+
* @param chain Array of method names in the chain
|
|
316
|
+
* @returns Proxy object that transforms property access into remote method calls
|
|
317
|
+
* @private
|
|
318
|
+
*/
|
|
319
|
+
createNestedProxy(chain = []) {
|
|
320
|
+
return new Proxy(() => {
|
|
321
|
+
}, {
|
|
322
|
+
get: (_target, prop) => {
|
|
323
|
+
if (typeof prop === "string" && prop !== "then") {
|
|
324
|
+
return this.createNestedProxy([...chain, prop]);
|
|
325
|
+
}
|
|
326
|
+
return void 0;
|
|
327
|
+
},
|
|
328
|
+
apply: (_target, _thisArg, args) => {
|
|
329
|
+
const method = chain.join(".");
|
|
330
|
+
return this.callMethod(method, args);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Returns a proxy object that represents the remote API
|
|
336
|
+
* Methods called on this proxy will be executed on the remote endpoint
|
|
337
|
+
* @returns Proxy object representing the remote API
|
|
338
|
+
*/
|
|
339
|
+
getAPI() {
|
|
340
|
+
return this.createNestedProxy();
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Frees up memory by clearing stored callbacks and callback cache
|
|
344
|
+
* Useful when dealing with many anonymous callback functions to prevent memory leaks
|
|
345
|
+
*/
|
|
346
|
+
freeCallbacks() {
|
|
347
|
+
this.callbacks = {};
|
|
348
|
+
this.callbackCache.clear();
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
352
|
+
0 && (module.exports = {
|
|
353
|
+
DenoIo,
|
|
354
|
+
RPCChannel
|
|
355
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { I as IoInterface } from './channel-D6ZClufP.cjs';
|
|
3
|
+
export { R as RPCChannel } from './channel-D6ZClufP.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Stdio implementation for Deno
|
|
7
|
+
* Deno doesn't have `process` object, and have a completely different stdio API,
|
|
8
|
+
* This implementation wrap Deno's `Deno.stdin` and `Deno.stdout` to follow StdioInterface
|
|
9
|
+
*/
|
|
10
|
+
declare class DenoIo implements IoInterface {
|
|
11
|
+
private readStream;
|
|
12
|
+
private reader;
|
|
13
|
+
name: string;
|
|
14
|
+
constructor(readStream: ReadableStream<Uint8Array>);
|
|
15
|
+
read(): Promise<Buffer | null>;
|
|
16
|
+
write(data: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { DenoIo };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { I as IoInterface } from './channel-D6ZClufP.js';
|
|
3
|
+
export { R as RPCChannel } from './channel-D6ZClufP.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Stdio implementation for Deno
|
|
7
|
+
* Deno doesn't have `process` object, and have a completely different stdio API,
|
|
8
|
+
* This implementation wrap Deno's `Deno.stdin` and `Deno.stdout` to follow StdioInterface
|
|
9
|
+
*/
|
|
10
|
+
declare class DenoIo implements IoInterface {
|
|
11
|
+
private readStream;
|
|
12
|
+
private reader;
|
|
13
|
+
name: string;
|
|
14
|
+
constructor(readStream: ReadableStream<Uint8Array>);
|
|
15
|
+
read(): Promise<Buffer | null>;
|
|
16
|
+
write(data: string): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { DenoIo };
|
package/dist/deno-mod.js
ADDED
package/dist/mod.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// mod.ts
|
|
31
31
|
var mod_exports = {};
|
|
32
32
|
__export(mod_exports, {
|
|
33
|
+
BunIo: () => BunIo,
|
|
33
34
|
ChromeBackgroundIO: () => ChromeBackgroundIO,
|
|
34
35
|
ChromeContentIO: () => ChromeContentIO,
|
|
35
36
|
DenoIo: () => DenoIo,
|
|
@@ -37,6 +38,7 @@ __export(mod_exports, {
|
|
|
37
38
|
HTTPServerIO: () => HTTPServerIO,
|
|
38
39
|
NodeIo: () => NodeIo,
|
|
39
40
|
RPCChannel: () => RPCChannel,
|
|
41
|
+
TauriShellStdio: () => TauriShellStdio,
|
|
40
42
|
WebSocketClientIO: () => WebSocketClientIO,
|
|
41
43
|
WebSocketServerIO: () => WebSocketServerIO,
|
|
42
44
|
WorkerChildIO: () => WorkerChildIO,
|
|
@@ -213,14 +215,36 @@ var ChromeContentIO = class {
|
|
|
213
215
|
}
|
|
214
216
|
};
|
|
215
217
|
|
|
216
|
-
// src/adapters/
|
|
218
|
+
// src/adapters/bun.ts
|
|
217
219
|
var import_node_buffer2 = require("buffer");
|
|
218
|
-
var import_node_stream = require("stream");
|
|
219
220
|
|
|
220
221
|
// src/interface.ts
|
|
221
222
|
var import_node_buffer = require("buffer");
|
|
222
223
|
|
|
224
|
+
// src/adapters/bun.ts
|
|
225
|
+
var BunIo = class {
|
|
226
|
+
name = "bun-io";
|
|
227
|
+
readStream;
|
|
228
|
+
reader;
|
|
229
|
+
constructor(readStream) {
|
|
230
|
+
this.readStream = readStream;
|
|
231
|
+
this.reader = this.readStream.getReader();
|
|
232
|
+
}
|
|
233
|
+
async read() {
|
|
234
|
+
const { value, done } = await this.reader.read();
|
|
235
|
+
if (done) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return import_node_buffer2.Buffer.from(value);
|
|
239
|
+
}
|
|
240
|
+
async write(data) {
|
|
241
|
+
return Bun.write(Bun.stdout, data).then(() => Promise.resolve());
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
223
245
|
// src/adapters/node.ts
|
|
246
|
+
var import_node_buffer3 = require("buffer");
|
|
247
|
+
var import_node_stream = require("stream");
|
|
224
248
|
var NodeIo = class {
|
|
225
249
|
name = "node-io";
|
|
226
250
|
readStream;
|
|
@@ -457,6 +481,26 @@ var HTTPServerIO = class {
|
|
|
457
481
|
}
|
|
458
482
|
};
|
|
459
483
|
|
|
484
|
+
// src/adapters/tauri.ts
|
|
485
|
+
var import_plugin_shell = require("@tauri-apps/plugin-shell");
|
|
486
|
+
var TauriShellStdio = class {
|
|
487
|
+
constructor(readStream, childProcess) {
|
|
488
|
+
this.readStream = readStream;
|
|
489
|
+
this.childProcess = childProcess;
|
|
490
|
+
}
|
|
491
|
+
name = "tauri-shell-stdio";
|
|
492
|
+
read() {
|
|
493
|
+
return new Promise((resolve, reject) => {
|
|
494
|
+
this.readStream.on("data", (chunk) => {
|
|
495
|
+
resolve(chunk);
|
|
496
|
+
});
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
async write(data) {
|
|
500
|
+
return this.childProcess.write(data + "\n");
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
460
504
|
// src/serialization.ts
|
|
461
505
|
var import_superjson2 = __toESM(require("superjson"), 1);
|
|
462
506
|
function serializeMessage(message) {
|
|
@@ -762,11 +806,10 @@ var RPCChannel = class {
|
|
|
762
806
|
};
|
|
763
807
|
|
|
764
808
|
// src/adapters/deno.ts
|
|
765
|
-
var
|
|
809
|
+
var import_node_buffer4 = require("buffer");
|
|
766
810
|
var DenoIo = class {
|
|
767
|
-
constructor(readStream
|
|
811
|
+
constructor(readStream) {
|
|
768
812
|
this.readStream = readStream;
|
|
769
|
-
this.writeStream = writeStream;
|
|
770
813
|
this.reader = this.readStream.getReader();
|
|
771
814
|
}
|
|
772
815
|
reader;
|
|
@@ -776,7 +819,7 @@ var DenoIo = class {
|
|
|
776
819
|
if (done) {
|
|
777
820
|
return null;
|
|
778
821
|
}
|
|
779
|
-
return
|
|
822
|
+
return import_node_buffer4.Buffer.from(value);
|
|
780
823
|
}
|
|
781
824
|
write(data) {
|
|
782
825
|
const encoder = new TextEncoder();
|
|
@@ -787,6 +830,7 @@ var DenoIo = class {
|
|
|
787
830
|
};
|
|
788
831
|
// Annotate the CommonJS export names for ESM import in node:
|
|
789
832
|
0 && (module.exports = {
|
|
833
|
+
BunIo,
|
|
790
834
|
ChromeBackgroundIO,
|
|
791
835
|
ChromeContentIO,
|
|
792
836
|
DenoIo,
|
|
@@ -794,6 +838,7 @@ var DenoIo = class {
|
|
|
794
838
|
HTTPServerIO,
|
|
795
839
|
NodeIo,
|
|
796
840
|
RPCChannel,
|
|
841
|
+
TauriShellStdio,
|
|
797
842
|
WebSocketClientIO,
|
|
798
843
|
WebSocketServerIO,
|
|
799
844
|
WorkerChildIO,
|
package/dist/mod.d.cts
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
export { a as WorkerChildIO, W as WorkerParentIO } from './
|
|
1
|
+
export { T as TauriShellStdio, a as WorkerChildIO, W as WorkerParentIO } from './tauri-CRNRbu3f.cjs';
|
|
2
2
|
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.cjs';
|
|
3
3
|
import { Buffer } from 'node:buffer';
|
|
4
|
-
import { Readable, Writable } from 'node:stream';
|
|
5
4
|
import { I as IoInterface, D as DestroyableIoInterface } from './channel-D6ZClufP.cjs';
|
|
6
5
|
export { R as RPCChannel } from './channel-D6ZClufP.cjs';
|
|
6
|
+
import { Readable, Writable } from 'node:stream';
|
|
7
7
|
export { H as HTTPClientIO, a as HTTPServerIO } from './http-CvGfNM3D.cjs';
|
|
8
|
+
export { DenoIo } from './deno-mod.cjs';
|
|
9
|
+
import '@tauri-apps/plugin-shell';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Node.js implementation of IoInterface
|
|
13
|
+
* Should also work with Bun
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Stdio implementation for Bun
|
|
18
|
+
*/
|
|
19
|
+
declare class BunIo implements IoInterface {
|
|
20
|
+
name: string;
|
|
21
|
+
private readStream;
|
|
22
|
+
private reader;
|
|
23
|
+
constructor(readStream: ReadableStream<Uint8Array>);
|
|
24
|
+
read(): Promise<Buffer | null>;
|
|
25
|
+
write(data: string): Promise<void>;
|
|
26
|
+
}
|
|
8
27
|
|
|
9
28
|
/**
|
|
10
29
|
* Node.js implementation of IoInterface
|
|
@@ -62,19 +81,4 @@ declare class WebSocketServerIO implements DestroyableIoInterface {
|
|
|
62
81
|
signalDestroy(): void;
|
|
63
82
|
}
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
* Stdio implementation for Deno
|
|
67
|
-
* Deno doesn't have `process` object, and have a completely different stdio API,
|
|
68
|
-
* This implementation wrap Deno's `Deno.stdin` and `Deno.stdout` to follow StdioInterface
|
|
69
|
-
*/
|
|
70
|
-
declare class DenoIo implements IoInterface {
|
|
71
|
-
private readStream;
|
|
72
|
-
private writeStream;
|
|
73
|
-
private reader;
|
|
74
|
-
name: string;
|
|
75
|
-
constructor(readStream: ReadableStream<Uint8Array>, writeStream: WritableStream<Uint8Array>);
|
|
76
|
-
read(): Promise<Buffer | null>;
|
|
77
|
-
write(data: string): Promise<void>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export { DenoIo, DestroyableIoInterface, IoInterface, NodeIo, WebSocketClientIO, WebSocketServerIO };
|
|
84
|
+
export { BunIo, DestroyableIoInterface, IoInterface, NodeIo, WebSocketClientIO, WebSocketServerIO };
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
export { a as WorkerChildIO, W as WorkerParentIO } from './
|
|
1
|
+
export { T as TauriShellStdio, a as WorkerChildIO, W as WorkerParentIO } from './tauri-PdcZTVUI.js';
|
|
2
2
|
export { ChromeBackgroundIO, ChromeContentIO, Message, Response, deserializeMessage, deserializeResponse, generateUUID, serializeMessage, serializeResponse } from './chrome.js';
|
|
3
3
|
import { Buffer } from 'node:buffer';
|
|
4
|
-
import { Readable, Writable } from 'node:stream';
|
|
5
4
|
import { I as IoInterface, D as DestroyableIoInterface } from './channel-D6ZClufP.js';
|
|
6
5
|
export { R as RPCChannel } from './channel-D6ZClufP.js';
|
|
6
|
+
import { Readable, Writable } from 'node:stream';
|
|
7
7
|
export { H as HTTPClientIO, a as HTTPServerIO } from './http-Bz7mwStC.js';
|
|
8
|
+
export { DenoIo } from './deno-mod.js';
|
|
9
|
+
import '@tauri-apps/plugin-shell';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Node.js implementation of IoInterface
|
|
13
|
+
* Should also work with Bun
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Stdio implementation for Bun
|
|
18
|
+
*/
|
|
19
|
+
declare class BunIo implements IoInterface {
|
|
20
|
+
name: string;
|
|
21
|
+
private readStream;
|
|
22
|
+
private reader;
|
|
23
|
+
constructor(readStream: ReadableStream<Uint8Array>);
|
|
24
|
+
read(): Promise<Buffer | null>;
|
|
25
|
+
write(data: string): Promise<void>;
|
|
26
|
+
}
|
|
8
27
|
|
|
9
28
|
/**
|
|
10
29
|
* Node.js implementation of IoInterface
|
|
@@ -62,19 +81,4 @@ declare class WebSocketServerIO implements DestroyableIoInterface {
|
|
|
62
81
|
signalDestroy(): void;
|
|
63
82
|
}
|
|
64
83
|
|
|
65
|
-
|
|
66
|
-
* Stdio implementation for Deno
|
|
67
|
-
* Deno doesn't have `process` object, and have a completely different stdio API,
|
|
68
|
-
* This implementation wrap Deno's `Deno.stdin` and `Deno.stdout` to follow StdioInterface
|
|
69
|
-
*/
|
|
70
|
-
declare class DenoIo implements IoInterface {
|
|
71
|
-
private readStream;
|
|
72
|
-
private writeStream;
|
|
73
|
-
private reader;
|
|
74
|
-
name: string;
|
|
75
|
-
constructor(readStream: ReadableStream<Uint8Array>, writeStream: WritableStream<Uint8Array>);
|
|
76
|
-
read(): Promise<Buffer | null>;
|
|
77
|
-
write(data: string): Promise<void>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export { DenoIo, DestroyableIoInterface, IoInterface, NodeIo, WebSocketClientIO, WebSocketServerIO };
|
|
84
|
+
export { BunIo, DestroyableIoInterface, IoInterface, NodeIo, WebSocketClientIO, WebSocketServerIO };
|
package/dist/mod.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
TauriShellStdio,
|
|
2
3
|
WorkerChildIO,
|
|
3
4
|
WorkerParentIO
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KZFPA2BM.js";
|
|
5
6
|
import {
|
|
6
7
|
ChromeBackgroundIO,
|
|
7
8
|
ChromeContentIO
|
|
8
9
|
} from "./chunk-INKNKSKA.js";
|
|
10
|
+
import {
|
|
11
|
+
DenoIo
|
|
12
|
+
} from "./chunk-GRCUBSPR.js";
|
|
9
13
|
import {
|
|
10
14
|
HTTPClientIO,
|
|
11
15
|
HTTPServerIO
|
|
@@ -19,6 +23,28 @@ import {
|
|
|
19
23
|
serializeResponse
|
|
20
24
|
} from "./chunk-ZSSFWNSX.js";
|
|
21
25
|
|
|
26
|
+
// src/adapters/bun.ts
|
|
27
|
+
import { Buffer } from "node:buffer";
|
|
28
|
+
var BunIo = class {
|
|
29
|
+
name = "bun-io";
|
|
30
|
+
readStream;
|
|
31
|
+
reader;
|
|
32
|
+
constructor(readStream) {
|
|
33
|
+
this.readStream = readStream;
|
|
34
|
+
this.reader = this.readStream.getReader();
|
|
35
|
+
}
|
|
36
|
+
async read() {
|
|
37
|
+
const { value, done } = await this.reader.read();
|
|
38
|
+
if (done) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return Buffer.from(value);
|
|
42
|
+
}
|
|
43
|
+
async write(data) {
|
|
44
|
+
return Bun.write(Bun.stdout, data).then(() => Promise.resolve());
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
22
48
|
// src/adapters/node.ts
|
|
23
49
|
var NodeIo = class {
|
|
24
50
|
name = "node-io";
|
|
@@ -165,32 +191,8 @@ var WebSocketServerIO = class {
|
|
|
165
191
|
this.write(DESTROY_SIGNAL);
|
|
166
192
|
}
|
|
167
193
|
};
|
|
168
|
-
|
|
169
|
-
// src/adapters/deno.ts
|
|
170
|
-
import { Buffer } from "node:buffer";
|
|
171
|
-
var DenoIo = class {
|
|
172
|
-
constructor(readStream, writeStream) {
|
|
173
|
-
this.readStream = readStream;
|
|
174
|
-
this.writeStream = writeStream;
|
|
175
|
-
this.reader = this.readStream.getReader();
|
|
176
|
-
}
|
|
177
|
-
reader;
|
|
178
|
-
name = "deno-io";
|
|
179
|
-
async read() {
|
|
180
|
-
const { value, done } = await this.reader.read();
|
|
181
|
-
if (done) {
|
|
182
|
-
return null;
|
|
183
|
-
}
|
|
184
|
-
return Buffer.from(value);
|
|
185
|
-
}
|
|
186
|
-
write(data) {
|
|
187
|
-
const encoder = new TextEncoder();
|
|
188
|
-
const encodedData = encoder.encode(data + "\n");
|
|
189
|
-
Deno.stdout.writeSync(encodedData);
|
|
190
|
-
return Promise.resolve();
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
194
|
export {
|
|
195
|
+
BunIo,
|
|
194
196
|
ChromeBackgroundIO,
|
|
195
197
|
ChromeContentIO,
|
|
196
198
|
DenoIo,
|
|
@@ -198,6 +200,7 @@ export {
|
|
|
198
200
|
HTTPServerIO,
|
|
199
201
|
NodeIo,
|
|
200
202
|
RPCChannel,
|
|
203
|
+
TauriShellStdio,
|
|
201
204
|
WebSocketClientIO,
|
|
202
205
|
WebSocketServerIO,
|
|
203
206
|
WorkerChildIO,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { D as DestroyableIoInterface } from './channel-D6ZClufP.
|
|
1
|
+
import { D as DestroyableIoInterface, I as IoInterface } from './channel-D6ZClufP.cjs';
|
|
2
|
+
import { EventEmitter, OutputEvents, Child } from '@tauri-apps/plugin-shell';
|
|
2
3
|
|
|
3
4
|
declare class WorkerParentIO implements DestroyableIoInterface {
|
|
4
5
|
name: string;
|
|
@@ -24,4 +25,14 @@ declare class WorkerChildIO implements DestroyableIoInterface {
|
|
|
24
25
|
signalDestroy(): void;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
declare class TauriShellStdio implements IoInterface {
|
|
29
|
+
private readStream;
|
|
30
|
+
private childProcess;
|
|
31
|
+
name: string;
|
|
32
|
+
constructor(readStream: EventEmitter<OutputEvents<string>>, // stdout of child process
|
|
33
|
+
childProcess: Child);
|
|
34
|
+
read(): Promise<string | Uint8Array | null>;
|
|
35
|
+
write(data: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { TauriShellStdio as T, WorkerParentIO as W, WorkerChildIO as a };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { D as DestroyableIoInterface } from './channel-D6ZClufP.
|
|
1
|
+
import { D as DestroyableIoInterface, I as IoInterface } from './channel-D6ZClufP.js';
|
|
2
|
+
import { EventEmitter, OutputEvents, Child } from '@tauri-apps/plugin-shell';
|
|
2
3
|
|
|
3
4
|
declare class WorkerParentIO implements DestroyableIoInterface {
|
|
4
5
|
name: string;
|
|
@@ -24,4 +25,14 @@ declare class WorkerChildIO implements DestroyableIoInterface {
|
|
|
24
25
|
signalDestroy(): void;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
declare class TauriShellStdio implements IoInterface {
|
|
29
|
+
private readStream;
|
|
30
|
+
private childProcess;
|
|
31
|
+
name: string;
|
|
32
|
+
constructor(readStream: EventEmitter<OutputEvents<string>>, // stdout of child process
|
|
33
|
+
childProcess: Child);
|
|
34
|
+
read(): Promise<string | Uint8Array | null>;
|
|
35
|
+
write(data: string): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { TauriShellStdio as T, WorkerParentIO as W, WorkerChildIO as a };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kkrpc",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -43,6 +43,15 @@
|
|
|
43
43
|
"import": "./dist/http.js",
|
|
44
44
|
"require": "./dist/http.cjs"
|
|
45
45
|
},
|
|
46
|
+
"./deno": {
|
|
47
|
+
"types": {
|
|
48
|
+
"import": "./dist/deno-mod.d.ts",
|
|
49
|
+
"require": "./dist/deno-mod.cjs",
|
|
50
|
+
"default": "./dist/deno-mod.js"
|
|
51
|
+
},
|
|
52
|
+
"import": "./dist/deno-mod.js",
|
|
53
|
+
"require": "./dist/deno-mod.cjs"
|
|
54
|
+
},
|
|
46
55
|
"./chrome": {
|
|
47
56
|
"types": {
|
|
48
57
|
"import": "./dist/chrome.d.ts",
|
|
@@ -67,6 +76,7 @@
|
|
|
67
76
|
"typescript": "^5.0.0"
|
|
68
77
|
},
|
|
69
78
|
"dependencies": {
|
|
79
|
+
"@tauri-apps/plugin-shell": "^2.2.0",
|
|
70
80
|
"superjson": "^2.2.2",
|
|
71
81
|
"ws": "^8.18.1"
|
|
72
82
|
},
|