@github/copilot-language-server 1.528.0 → 1.529.0
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/dist/main.js +66 -66
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/client.js +276 -53
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/copilotRequestHandler.js +9 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/extension.js +21 -6
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/factory.js +123 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/ffiRuntimeHost.js +285 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/generated/rpc.js +587 -46
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/index.js +11 -2
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/session.js +643 -14
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/sessionFsProvider.js +43 -0
- package/dist/node_modules/@github/copilot-sdk/dist/cjs/types.js +30 -3
- package/dist/node_modules/@github/copilot-sdk/package.json +3 -2
- package/dist/node_modules/vscode-jsonrpc/lib/common/connection.js +5 -3
- package/dist/node_modules/vscode-jsonrpc/package.json +1 -1
- package/package.json +14 -14
|
@@ -20,13 +20,17 @@ var extension_exports = {};
|
|
|
20
20
|
__export(extension_exports, {
|
|
21
21
|
Canvas: () => import_canvas.Canvas,
|
|
22
22
|
CanvasError: () => import_canvas.CanvasError,
|
|
23
|
+
FactoryResumeError: () => import_factory.FactoryResumeError,
|
|
23
24
|
createCanvas: () => import_canvas.createCanvas,
|
|
25
|
+
defineFactory: () => import_factory.defineFactory,
|
|
26
|
+
isFactoryRunTerminal: () => import_factory.isFactoryRunTerminal,
|
|
24
27
|
joinSession: () => joinSession
|
|
25
28
|
});
|
|
26
29
|
module.exports = __toCommonJS(extension_exports);
|
|
27
30
|
var import_client = require("./client.js");
|
|
28
31
|
var import_types = require("./types.js");
|
|
29
32
|
var import_canvas = require("./canvas.js");
|
|
33
|
+
var import_factory = require("./factory.js");
|
|
30
34
|
async function joinSession(config = {}) {
|
|
31
35
|
const sessionId = process.env.SESSION_ID;
|
|
32
36
|
if (!sessionId) {
|
|
@@ -35,18 +39,29 @@ async function joinSession(config = {}) {
|
|
|
35
39
|
);
|
|
36
40
|
}
|
|
37
41
|
const client = new import_client.CopilotClient({ _internalConnection: { kind: "parent-process" } });
|
|
38
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
extensionSdkPath: _stripped,
|
|
44
|
+
factories,
|
|
45
|
+
...rest
|
|
46
|
+
} = config;
|
|
39
47
|
void _stripped;
|
|
40
|
-
return client.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
return client.resumeSessionForExtension(
|
|
49
|
+
sessionId,
|
|
50
|
+
{
|
|
51
|
+
...rest,
|
|
52
|
+
onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
|
|
53
|
+
suppressResumeEvent: config.suppressResumeEvent ?? true
|
|
54
|
+
},
|
|
55
|
+
factories
|
|
56
|
+
);
|
|
45
57
|
}
|
|
46
58
|
// Annotate the CommonJS export names for ESM import in node:
|
|
47
59
|
0 && (module.exports = {
|
|
48
60
|
Canvas,
|
|
49
61
|
CanvasError,
|
|
62
|
+
FactoryResumeError,
|
|
50
63
|
createCanvas,
|
|
64
|
+
defineFactory,
|
|
65
|
+
isFactoryRunTerminal,
|
|
51
66
|
joinSession
|
|
52
67
|
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var factory_exports = {};
|
|
20
|
+
__export(factory_exports, {
|
|
21
|
+
FactoryResumeError: () => FactoryResumeError,
|
|
22
|
+
defineFactory: () => defineFactory,
|
|
23
|
+
getFactoryDefinition: () => getFactoryDefinition,
|
|
24
|
+
isFactoryRunTerminal: () => isFactoryRunTerminal
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(factory_exports);
|
|
27
|
+
const FACTORY_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
28
|
+
"completed",
|
|
29
|
+
"halted",
|
|
30
|
+
"cancelled",
|
|
31
|
+
"error"
|
|
32
|
+
]);
|
|
33
|
+
function isFactoryRunTerminal(status) {
|
|
34
|
+
return FACTORY_TERMINAL_STATUSES.has(status);
|
|
35
|
+
}
|
|
36
|
+
class FactoryResumeError extends Error {
|
|
37
|
+
constructor(code, message) {
|
|
38
|
+
super(message);
|
|
39
|
+
this.code = code;
|
|
40
|
+
this.name = "FactoryResumeError";
|
|
41
|
+
}
|
|
42
|
+
code;
|
|
43
|
+
}
|
|
44
|
+
const factoryHandles = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
const MAX_FACTORY_TIMEOUT_SECONDS = 2147483647e-3;
|
|
46
|
+
const NANO_AIU_PER_AIU = 1e9;
|
|
47
|
+
function deepFreeze(value) {
|
|
48
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
49
|
+
Object.freeze(value);
|
|
50
|
+
for (const nested of Object.values(value)) {
|
|
51
|
+
deepFreeze(nested);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
function validateLimits(meta) {
|
|
57
|
+
const limits = meta.limits;
|
|
58
|
+
if (!limits) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
for (const field of ["maxConcurrentSubagents", "maxTotalSubagents"]) {
|
|
62
|
+
const value = limits[field];
|
|
63
|
+
if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) {
|
|
64
|
+
throw new Error(`Factory limit "${field}" must be a positive integer`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (limits.timeoutSeconds !== void 0 && (!Number.isFinite(limits.timeoutSeconds) || limits.timeoutSeconds <= 0)) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
'Factory limit "timeoutSeconds" must be a positive, finite number of seconds'
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
if (limits.timeoutSeconds !== void 0 && limits.timeoutSeconds > MAX_FACTORY_TIMEOUT_SECONDS) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Factory limit "timeoutSeconds" must not exceed ${MAX_FACTORY_TIMEOUT_SECONDS} seconds`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (limits.maxAiCredits !== void 0) {
|
|
78
|
+
const maxNanoAiu = Math.round(limits.maxAiCredits * NANO_AIU_PER_AIU);
|
|
79
|
+
if (!Number.isFinite(limits.maxAiCredits) || limits.maxAiCredits <= 0 || !Number.isSafeInteger(maxNanoAiu) || maxNanoAiu < 1) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
'Factory limit "maxAiCredits" must be a positive, finite number that rounds to a safe positive integer nano-AIU ceiling'
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function validatePhases(meta) {
|
|
87
|
+
const titles = /* @__PURE__ */ new Set();
|
|
88
|
+
for (const phase of meta.phases) {
|
|
89
|
+
if (phase.title.trim().length === 0) {
|
|
90
|
+
throw new Error("Factory phase titles must not be empty");
|
|
91
|
+
}
|
|
92
|
+
if (titles.has(phase.title)) {
|
|
93
|
+
throw new Error(`Factory phase title "${phase.title}" is declared more than once`);
|
|
94
|
+
}
|
|
95
|
+
titles.add(phase.title);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function defineFactory(definition) {
|
|
99
|
+
const meta = deepFreeze(structuredClone(definition.meta));
|
|
100
|
+
validateLimits(meta);
|
|
101
|
+
validatePhases(meta);
|
|
102
|
+
const stored = {
|
|
103
|
+
meta,
|
|
104
|
+
run: definition.run
|
|
105
|
+
};
|
|
106
|
+
const handle = Object.freeze({ meta });
|
|
107
|
+
factoryHandles.set(handle, stored);
|
|
108
|
+
return handle;
|
|
109
|
+
}
|
|
110
|
+
function getFactoryDefinition(handle) {
|
|
111
|
+
const definition = factoryHandles.get(handle);
|
|
112
|
+
if (!definition) {
|
|
113
|
+
throw new Error("Invalid factory handle");
|
|
114
|
+
}
|
|
115
|
+
return definition;
|
|
116
|
+
}
|
|
117
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
118
|
+
0 && (module.exports = {
|
|
119
|
+
FactoryResumeError,
|
|
120
|
+
defineFactory,
|
|
121
|
+
getFactoryDefinition,
|
|
122
|
+
isFactoryRunTerminal
|
|
123
|
+
});
|
|
@@ -0,0 +1,285 @@
|
|
|
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
|
+
var ffiRuntimeHost_exports = {};
|
|
30
|
+
__export(ffiRuntimeHost_exports, {
|
|
31
|
+
FfiRuntimeHost: () => FfiRuntimeHost
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(ffiRuntimeHost_exports);
|
|
34
|
+
var import_node_fs = require("node:fs");
|
|
35
|
+
var import_koffi = __toESM(require("koffi"), 1);
|
|
36
|
+
var import_node_path = require("node:path");
|
|
37
|
+
var import_node_stream = require("node:stream");
|
|
38
|
+
const SYMBOL_PREFIX = "copilot_runtime_";
|
|
39
|
+
const KEEP_ALIVE_INTERVAL_MS = 1 << 30;
|
|
40
|
+
let loadedLibraryPath;
|
|
41
|
+
let loadedLibrary;
|
|
42
|
+
function loadLibrary(libraryPath) {
|
|
43
|
+
if (loadedLibrary) {
|
|
44
|
+
if (loadedLibraryPath !== libraryPath) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`An in-process FFI runtime library is already loaded from '${loadedLibraryPath}'; loading a different library from '${libraryPath}' in the same process is not supported.`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return loadedLibrary;
|
|
50
|
+
}
|
|
51
|
+
const lib = import_koffi.default.load(libraryPath);
|
|
52
|
+
const outboundCallbackType = import_koffi.default.pointer(
|
|
53
|
+
import_koffi.default.proto(
|
|
54
|
+
`void ${SYMBOL_PREFIX}outbound(void *userData, uint8 *bytesPtr, size_t bytesLen)`
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
loadedLibrary = {
|
|
58
|
+
hostStart: lib.func(`${SYMBOL_PREFIX}host_start`, "uint32", [
|
|
59
|
+
"uint8*",
|
|
60
|
+
"size_t",
|
|
61
|
+
"uint8*",
|
|
62
|
+
"size_t"
|
|
63
|
+
]),
|
|
64
|
+
hostShutdown: lib.func(`${SYMBOL_PREFIX}host_shutdown`, "bool", ["uint32"]),
|
|
65
|
+
connectionOpen: lib.func(`${SYMBOL_PREFIX}connection_open`, "uint32", [
|
|
66
|
+
"uint32",
|
|
67
|
+
outboundCallbackType,
|
|
68
|
+
"void*",
|
|
69
|
+
"uint8*",
|
|
70
|
+
"size_t",
|
|
71
|
+
"uint8*",
|
|
72
|
+
"size_t",
|
|
73
|
+
"uint8*",
|
|
74
|
+
"size_t"
|
|
75
|
+
]),
|
|
76
|
+
connectionWrite: lib.func(`${SYMBOL_PREFIX}connection_write`, "bool", [
|
|
77
|
+
"uint32",
|
|
78
|
+
"uint8*",
|
|
79
|
+
"size_t"
|
|
80
|
+
]),
|
|
81
|
+
connectionClose: lib.func(`${SYMBOL_PREFIX}connection_close`, "bool", ["uint32"]),
|
|
82
|
+
outboundCallbackType
|
|
83
|
+
};
|
|
84
|
+
loadedLibraryPath = libraryPath;
|
|
85
|
+
return loadedLibrary;
|
|
86
|
+
}
|
|
87
|
+
function buildArgvJson(cliEntrypoint, args) {
|
|
88
|
+
const argv = cliEntrypoint.toLowerCase().endsWith(".js") ? ["node", cliEntrypoint, "--embedded-host", "--no-auto-update"] : [cliEntrypoint, "--embedded-host", "--no-auto-update"];
|
|
89
|
+
argv.push(...args);
|
|
90
|
+
return Buffer.from(JSON.stringify(argv), "utf8");
|
|
91
|
+
}
|
|
92
|
+
function buildEnvJson(environment) {
|
|
93
|
+
if (!environment) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const obj = {};
|
|
97
|
+
for (const [key, value] of Object.entries(environment)) {
|
|
98
|
+
if (value !== void 0) {
|
|
99
|
+
obj[key] = value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (Object.keys(obj).length === 0) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return Buffer.from(JSON.stringify(obj), "utf8");
|
|
106
|
+
}
|
|
107
|
+
class FfiRuntimeHost {
|
|
108
|
+
constructor(libraryPath, cliEntrypoint, environment, args) {
|
|
109
|
+
this.libraryPath = libraryPath;
|
|
110
|
+
this.cliEntrypoint = cliEntrypoint;
|
|
111
|
+
this.environment = environment;
|
|
112
|
+
this.args = args;
|
|
113
|
+
this.lib = loadLibrary(libraryPath);
|
|
114
|
+
this.receiveStream = new import_node_stream.PassThrough();
|
|
115
|
+
this.sendStream = new import_node_stream.Writable({
|
|
116
|
+
// connection_write enqueues the frame into the runtime's inbound channel and
|
|
117
|
+
// returns immediately, so a synchronous FFI call is sufficient here.
|
|
118
|
+
write: (chunk, _encoding, callback) => {
|
|
119
|
+
try {
|
|
120
|
+
this.writeFrame(chunk);
|
|
121
|
+
callback();
|
|
122
|
+
} catch (error) {
|
|
123
|
+
callback(error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
libraryPath;
|
|
129
|
+
cliEntrypoint;
|
|
130
|
+
environment;
|
|
131
|
+
args;
|
|
132
|
+
lib;
|
|
133
|
+
serverId = 0;
|
|
134
|
+
connectionId = 0;
|
|
135
|
+
disposed = false;
|
|
136
|
+
outboundCallback;
|
|
137
|
+
keepAliveTimer;
|
|
138
|
+
/** The stream JSON-RPC reads server→client frames from. */
|
|
139
|
+
receiveStream;
|
|
140
|
+
/** The stream JSON-RPC writes client→server frames to. */
|
|
141
|
+
sendStream;
|
|
142
|
+
/**
|
|
143
|
+
* Resolves the cdylib next to the given CLI entrypoint and prepares the FFI host.
|
|
144
|
+
* The cdylib is resolved as `prebuilds/<prebuildsFolder>/runtime.node` relative to
|
|
145
|
+
* the entrypoint directory (the napi-rs `<node-platform>-<arch>` layout, e.g.
|
|
146
|
+
* `linux-x64`). Throws if it cannot be found.
|
|
147
|
+
*/
|
|
148
|
+
static create(cliEntrypoint, prebuildsFolder, environment, args) {
|
|
149
|
+
const fullEntrypoint = (0, import_node_path.resolve)(cliEntrypoint);
|
|
150
|
+
const distDir = (0, import_node_path.dirname)(fullEntrypoint);
|
|
151
|
+
const libraryPath = (0, import_node_path.join)(distDir, "prebuilds", prebuildsFolder, "runtime.node");
|
|
152
|
+
if (!(0, import_node_fs.existsSync)(libraryPath)) {
|
|
153
|
+
throw new Error(`FFI runtime library not found. Looked for '${libraryPath}'.`);
|
|
154
|
+
}
|
|
155
|
+
return new FfiRuntimeHost(libraryPath, fullEntrypoint, environment, args);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Starts the in-process runtime: spawns the CLI worker via the native host,
|
|
159
|
+
* waits for readiness, and opens the FFI JSON-RPC connection.
|
|
160
|
+
*/
|
|
161
|
+
async start() {
|
|
162
|
+
const argvJson = buildArgvJson(this.cliEntrypoint, this.args);
|
|
163
|
+
const envJson = buildEnvJson(this.environment);
|
|
164
|
+
this.serverId = await new Promise((resolvePromise, rejectPromise) => {
|
|
165
|
+
this.lib.hostStart.async(
|
|
166
|
+
argvJson,
|
|
167
|
+
argvJson.length,
|
|
168
|
+
envJson,
|
|
169
|
+
envJson ? envJson.length : 0,
|
|
170
|
+
(error, result) => {
|
|
171
|
+
if (error) {
|
|
172
|
+
rejectPromise(error);
|
|
173
|
+
} else {
|
|
174
|
+
resolvePromise(result);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
if (!this.serverId) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`copilot_runtime_host_start failed (library '${this.libraryPath}', entrypoint '${this.cliEntrypoint}').`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
this.outboundCallback = import_koffi.default.register(
|
|
185
|
+
(_userData, bytesPtr, bytesLen) => this.feedInbound(bytesPtr, bytesLen),
|
|
186
|
+
this.lib.outboundCallbackType
|
|
187
|
+
);
|
|
188
|
+
this.connectionId = this.lib.connectionOpen(
|
|
189
|
+
this.serverId,
|
|
190
|
+
this.outboundCallback,
|
|
191
|
+
null,
|
|
192
|
+
null,
|
|
193
|
+
0,
|
|
194
|
+
null,
|
|
195
|
+
0,
|
|
196
|
+
null,
|
|
197
|
+
0
|
|
198
|
+
);
|
|
199
|
+
if (!this.connectionId) {
|
|
200
|
+
this.unregisterCallback();
|
|
201
|
+
this.lib.hostShutdown(this.serverId);
|
|
202
|
+
this.serverId = 0;
|
|
203
|
+
throw new Error("copilot_runtime_connection_open failed.");
|
|
204
|
+
}
|
|
205
|
+
this.keepAliveTimer = setInterval(() => {
|
|
206
|
+
}, KEEP_ALIVE_INTERVAL_MS);
|
|
207
|
+
}
|
|
208
|
+
writeFrame(frame) {
|
|
209
|
+
if (this.disposed || !this.connectionId) {
|
|
210
|
+
throw new Error("The in-process runtime connection is closed.");
|
|
211
|
+
}
|
|
212
|
+
const ok = this.lib.connectionWrite(this.connectionId, frame, frame.length);
|
|
213
|
+
if (!ok) {
|
|
214
|
+
throw new Error("Failed to write a frame to the in-process runtime connection.");
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Native outbound (server→client) callback. koffi delivers it on the JS event loop
|
|
219
|
+
* via a threadsafe function, so the frame is decoded and written straight to
|
|
220
|
+
* {@link receiveStream}. The native pointer is only valid for this call, so the
|
|
221
|
+
* bytes are copied out before returning.
|
|
222
|
+
*/
|
|
223
|
+
feedInbound(bytesPtr, bytesLen) {
|
|
224
|
+
try {
|
|
225
|
+
if (this.disposed || this.receiveStream.writableEnded) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const length = Number(bytesLen);
|
|
229
|
+
if (!bytesPtr || length <= 0) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const bytes = import_koffi.default.decode(
|
|
233
|
+
bytesPtr,
|
|
234
|
+
import_koffi.default.array("uint8", length, "Typed")
|
|
235
|
+
);
|
|
236
|
+
this.receiveStream.write(Buffer.from(bytes));
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error(
|
|
239
|
+
`In-process FFI inbound callback failed: ${error instanceof Error ? error.stack ?? error.message : String(error)}`
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
unregisterCallback() {
|
|
244
|
+
if (this.outboundCallback === void 0) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const callback = this.outboundCallback;
|
|
248
|
+
this.outboundCallback = void 0;
|
|
249
|
+
try {
|
|
250
|
+
import_koffi.default.unregister(callback);
|
|
251
|
+
} catch {
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/** Closes the FFI connection, shuts down the native host, and releases resources. */
|
|
255
|
+
dispose() {
|
|
256
|
+
if (this.disposed) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
this.disposed = true;
|
|
260
|
+
if (this.keepAliveTimer !== void 0) {
|
|
261
|
+
clearInterval(this.keepAliveTimer);
|
|
262
|
+
this.keepAliveTimer = void 0;
|
|
263
|
+
}
|
|
264
|
+
try {
|
|
265
|
+
if (this.connectionId) {
|
|
266
|
+
this.lib.connectionClose(this.connectionId);
|
|
267
|
+
this.connectionId = 0;
|
|
268
|
+
}
|
|
269
|
+
} catch {
|
|
270
|
+
}
|
|
271
|
+
try {
|
|
272
|
+
if (this.serverId) {
|
|
273
|
+
this.lib.hostShutdown(this.serverId);
|
|
274
|
+
this.serverId = 0;
|
|
275
|
+
}
|
|
276
|
+
} catch {
|
|
277
|
+
}
|
|
278
|
+
this.receiveStream.end();
|
|
279
|
+
this.unregisterCallback();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
283
|
+
0 && (module.exports = {
|
|
284
|
+
FfiRuntimeHost
|
|
285
|
+
});
|