@dsh-electron/dsh-plugin-multi-root-workspace 0.1.12 → 0.1.14
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/CHANGELOG.en.md +29 -1
- package/CHANGELOG.md +29 -1
- package/README.en.md +9 -8
- package/README.md +9 -8
- package/cordis.patch.yml +4 -0
- package/detail/DETAIL.en.md +1 -0
- package/detail/DETAIL.md +1 -0
- package/detail/preview.svg +1 -0
- package/detail/preview.zh.svg +1 -0
- package/lib/client.js +492 -87
- package/lib/client.js.map +1 -1
- package/lib/{command-CmLekG1M.js → command-Dcz6nULo.js} +25 -3
- package/lib/command.js +1 -1
- package/lib/{compat-Bg2HFVMX.js → compat-veDqCOoa.js} +3 -1
- package/lib/compat.js +1 -1
- package/lib/{fs-CfzJq2wd.js → fs-Uws0ZpmV.js} +38 -0
- package/lib/fs.js +1 -1
- package/lib/index.js +4 -4
- package/lib/{native-win32-2waCRkPI.js → native-win32-CRNXr11U.js} +2 -1
- package/lib/{protocol-4zdwV7u4.js → protocol-CnR1KTXy.js} +62 -9
- package/lib/{registry-YTUOjmVu.js → registry-DR_sMuvS.js} +425 -125
- package/lib/{registry-lease-win32-DVTq9d4D.js → registry-lease-win32-DDO-c7ig.js} +2 -1
- package/lib/registry.js +2 -2
- package/lib/scope.js +36 -2
- package/lib/types/authority/protocol.d.ts +1 -1
- package/lib/types/authority/recovery.d.ts +58 -0
- package/lib/types/client/RootSwitcher.d.ts +8 -3
- package/lib/types/client/auto-review-settings.d.ts +18 -0
- package/lib/types/client/files-tree/FilesTree.d.ts +4 -1
- package/lib/types/client/files-tree/adapter.d.ts +63 -1
- package/lib/types/client/files-tree/locales.d.ts +1 -1
- package/lib/types/client/locales.d.ts +12 -0
- package/lib/types/client/open-in-app/locales.d.ts +1 -1
- package/lib/types/client/skills-settings.d.ts +12 -0
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/compat/auto-review-client.d.ts +58 -0
- package/lib/types/compat/connection-rpc.d.ts +12 -0
- package/lib/types/compat/dsh-version.d.ts +1 -1
- package/lib/types/compat/files-tree.d.ts +36 -0
- package/lib/types/compat/fs-patch.d.ts +6 -0
- package/lib/types/compat/koffi.d.ts +2 -0
- package/lib/types/fs.d.ts +3 -1
- package/lib/types/registry.d.ts +98 -0
- package/lib/types/scope.d.ts +18 -0
- package/locale/en.json +7 -0
- package/locale/zh.json +7 -0
- package/package.json +89 -82
- package/src/auto-review/README.en.md +1 -1
- package/src/auto-review/README.md +1 -1
|
@@ -2,11 +2,33 @@ import { t as effectiveDirectory } from "./session-directory-BLOstut1.js";
|
|
|
2
2
|
import { r as canonicalPath$1 } from "./windows-runner-contract-B5R2K3mM.js";
|
|
3
3
|
import { i as canonicalRoot, o as entryRootRef, p as resolveRootRef, r as availableRoots, t as RootValidationError } from "./roots-Ca_W1S9n.js";
|
|
4
4
|
import { c as skillsRequestSchema, i as parsePanelCall, r as effectiveRootAccess, s as SKILLS_ENDPOINTS, t as PANEL_CHANNEL } from "./contract-CStSEOcK.js";
|
|
5
|
-
import { n as AuthorityRpcError } from "./protocol-
|
|
5
|
+
import { n as AuthorityRpcError } from "./protocol-CnR1KTXy.js";
|
|
6
6
|
import { closeSync, lstatSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { isAbsolute, join } from "node:path";
|
|
8
8
|
import "@deepseek-ai/cordis";
|
|
9
9
|
import { canonicalPath } from "@deepseek-ai/dsh-sandbox";
|
|
10
|
+
//#region src/compat/connection-rpc.ts
|
|
11
|
+
/**
|
|
12
|
+
* Newer Cordis keeps a service getter's definition site when tracing it, so
|
|
13
|
+
* even reading Connection from the root can make its RPC getter capture the
|
|
14
|
+
* provider's context (which does not inject webServer). Invoke the public
|
|
15
|
+
* accessor with the actual consumer context instead. A data property is used
|
|
16
|
+
* unchanged for simpler Connection implementations. The service is not
|
|
17
|
+
* modified and the route remains owned by the injecting fiber.
|
|
18
|
+
*/
|
|
19
|
+
function connectionRpcFor(ctx, connection) {
|
|
20
|
+
for (let proto = connection; proto !== null; proto = Object.getPrototypeOf(proto)) {
|
|
21
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, "rpc");
|
|
22
|
+
if (descriptor === void 0) continue;
|
|
23
|
+
if (typeof descriptor.get !== "function") return connection.rpc;
|
|
24
|
+
const receiver = new Proxy(connection, { get(target, key, proxy) {
|
|
25
|
+
return key === "ctx" ? ctx : Reflect.get(target, key, proxy);
|
|
26
|
+
} });
|
|
27
|
+
return Reflect.apply(descriptor.get, receiver, []);
|
|
28
|
+
}
|
|
29
|
+
return connection.rpc;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
10
32
|
//#region src/profile-isolation.ts
|
|
11
33
|
/**
|
|
12
34
|
* Profile pnpm import isolation — the host-side maintenance behind
|
|
@@ -751,12 +773,12 @@ function apply(ctx, config = {}) {
|
|
|
751
773
|
handler: async (invocation) => await runCommand(ctx, invocation, config)
|
|
752
774
|
});
|
|
753
775
|
ctx.inject(["connection", "webServer"], (connectionCtx) => {
|
|
754
|
-
const connection = connectionCtx.
|
|
776
|
+
const connection = connectionCtx.get("connection");
|
|
755
777
|
if (connection === void 0) {
|
|
756
778
|
ctx.logger.warn("multi-root: connection resolved without the service; the panel channel is not mounted");
|
|
757
779
|
return;
|
|
758
780
|
}
|
|
759
|
-
const dispose = connection.
|
|
781
|
+
const dispose = connectionRpcFor(connectionCtx, connection).handle(PANEL_CHANNEL, async (endpoint, payload, signal) => await dispatchPanelRequest(ctx, endpoint, payload, signal));
|
|
760
782
|
return () => {
|
|
761
783
|
dispose();
|
|
762
784
|
};
|
package/lib/command.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, n as apply, o as resolvePanelPrimaryRoot, r as inject, s as revealAccepted, t as COMMAND_NAME } from "./command-
|
|
1
|
+
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, n as apply, o as resolvePanelPrimaryRoot, r as inject, s as revealAccepted, t as COMMAND_NAME } from "./command-Dcz6nULo.js";
|
|
2
2
|
export { COMMAND_NAME, apply, inject, parseFoldersCommand, renderRootsReport, resolvePanelPrimaryRoot, revealAccepted, revealArgv };
|
package/lib/compat.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as inject, i as assertSupportedInstallation, n as MultiRootCompatService, r as apply, t as DshCompatUnsupportedError } from "./compat-
|
|
1
|
+
import { a as inject, i as assertSupportedInstallation, n as MultiRootCompatService, r as apply, t as DshCompatUnsupportedError } from "./compat-veDqCOoa.js";
|
|
2
2
|
export { DshCompatUnsupportedError, MultiRootCompatService, apply, assertSupportedInstallation, inject };
|
|
@@ -5,6 +5,30 @@ import { canonicalPath, writableRoots } from "@deepseek-ai/dsh-sandbox";
|
|
|
5
5
|
import { stat } from "node:fs/promises";
|
|
6
6
|
import { FsError } from "@deepseek-ai/dsh-fs";
|
|
7
7
|
import { LocalFileSystem } from "@deepseek-ai/dsh-fs-local";
|
|
8
|
+
//#region src/compat/fs-patch.ts
|
|
9
|
+
/**
|
|
10
|
+
* Adapt the mutation methods introduced by newer filesystem backends.
|
|
11
|
+
* Older supported backends do not expose these methods at all.
|
|
12
|
+
*/
|
|
13
|
+
/** Install only methods present on the actual backend, preserving the caller as `this`. */
|
|
14
|
+
function installAdditionalMutations(prototype, fence) {
|
|
15
|
+
for (const method of [
|
|
16
|
+
"patchText",
|
|
17
|
+
"deleteFile",
|
|
18
|
+
"moveFile"
|
|
19
|
+
]) {
|
|
20
|
+
const inherited = Reflect.get(LocalFileSystem.prototype, method);
|
|
21
|
+
if (typeof inherited !== "function") continue;
|
|
22
|
+
Object.defineProperty(prototype, method, {
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: function(...args) {
|
|
26
|
+
return fence(this, method, args, (next) => Reflect.apply(inherited, this, next));
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
8
32
|
//#region src/containment.ts
|
|
9
33
|
const MISSING_CODES = /* @__PURE__ */ new Set(["ENOENT", "ENOTDIR"]);
|
|
10
34
|
function isMissing(error) {
|
|
@@ -67,6 +91,9 @@ async function isPathUnder(path, root, caseSensitive = process.platform !== "win
|
|
|
67
91
|
*/
|
|
68
92
|
var MultiRootFileSystem = class extends LocalFileSystem {
|
|
69
93
|
static inject = ["sandboxPolicy", "multiRootScope"];
|
|
94
|
+
static {
|
|
95
|
+
installAdditionalMutations(this.prototype, (receiver, method, args, invoke) => receiver.additionalMutation(method, args, invoke));
|
|
96
|
+
}
|
|
70
97
|
defaultMode;
|
|
71
98
|
constructor(ctx, config) {
|
|
72
99
|
super(ctx, config);
|
|
@@ -107,6 +134,17 @@ var MultiRootFileSystem = class extends LocalFileSystem {
|
|
|
107
134
|
const policy = structuredClone(sandboxPolicy ?? this.ctx.sandboxPolicy.resolve());
|
|
108
135
|
return this.withOperation(policy, "fs-edit", async (scope) => super.editText(await this.checkedTarget(target, policy, scope), edit, expected, signal));
|
|
109
136
|
}
|
|
137
|
+
/** Fence every endpoint of a patch, delete, or move under one admission. */
|
|
138
|
+
async additionalMutation(method, args, invoke) {
|
|
139
|
+
const policyIndex = method === "deleteFile" ? 3 : 4;
|
|
140
|
+
const policy = structuredClone(args[policyIndex] ?? this.ctx.sandboxPolicy.resolve());
|
|
141
|
+
return this.withOperation(policy, method === "patchText" ? "fs-edit" : "fs-write", async (scope) => {
|
|
142
|
+
const checked = [...args];
|
|
143
|
+
checked[0] = await this.checkedTarget(args[0], policy, scope);
|
|
144
|
+
if (method === "moveFile") checked[1] = await this.checkedTarget(args[1], policy, scope);
|
|
145
|
+
return await invoke(checked);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
110
148
|
/** The provider must also work without the gated registry (ADR-0009). */
|
|
111
149
|
async withOperation(policy, kind, body) {
|
|
112
150
|
const registry = this.ctx.get("multiRootRegistry");
|
package/lib/fs.js
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { i as renderInstructions, n as instructionsApi, t as createInstructionMessage } from "./llm-message-fYORacvh.js";
|
|
2
2
|
import { a as composeInstructionMessage, r as PLUGIN_SOURCE, t as DEFAULT_MAX_BYTES } from "./instructions-KsUwUFE0.js";
|
|
3
3
|
import { a as classifyStoredRoots, c as indexedStatuses, i as canonicalRoot, l as isCanonicallyUnder, m as validateRootCandidate, n as additionalRootId, p as resolveRootRef, r as availableRoots, s as expandRootInput, t as RootValidationError, u as removeStatusAt } from "./roots-Ca_W1S9n.js";
|
|
4
|
-
import { _ as classifyInstallation, c as agentPtyMarkerVerdict, d as HOST_SERVICE_PACKAGES, f as OPTIONAL_CORE_PACKAGES, g as SUPPORTED_DSH_RELEASES, h as RUNTIME_OPTIONAL_PACKAGES, i as assertSupportedInstallation, l as assertAgentPtyMarker, m as RUNNER_ANCHORED_PACKAGES, n as MultiRootCompatService, o as AGENT_PTY_MARKER, p as REQUIRED_CORE_PACKAGES, s as PtyMarkerContractError, t as DshCompatUnsupportedError, u as CORE_PACKAGES, v as compatEnforcement, y as readInstalledVersion } from "./compat-
|
|
4
|
+
import { _ as classifyInstallation, c as agentPtyMarkerVerdict, d as HOST_SERVICE_PACKAGES, f as OPTIONAL_CORE_PACKAGES, g as SUPPORTED_DSH_RELEASES, h as RUNTIME_OPTIONAL_PACKAGES, i as assertSupportedInstallation, l as assertAgentPtyMarker, m as RUNNER_ANCHORED_PACKAGES, n as MultiRootCompatService, o as AGENT_PTY_MARKER, p as REQUIRED_CORE_PACKAGES, s as PtyMarkerContractError, t as DshCompatUnsupportedError, u as CORE_PACKAGES, v as compatEnforcement, y as readInstalledVersion } from "./compat-veDqCOoa.js";
|
|
5
5
|
import { l as widenConfined } from "./dialects-Dr4rDR-H.js";
|
|
6
6
|
import { MULTI_ROOT_PROVIDER_BRAND, MultiRootProviders, brandMultiRootProvider, isMultiRootProvider } from "./providers.js";
|
|
7
|
-
import { t as MultiRootFileSystem } from "./fs-
|
|
7
|
+
import { t as MultiRootFileSystem } from "./fs-Uws0ZpmV.js";
|
|
8
8
|
import { t as MultiRootSandboxProvider } from "./sandbox-C-vCJCp3.js";
|
|
9
9
|
import { a as parseRevealedView, i as parsePanelCall, n as PANEL_ENDPOINTS, o as parseRootsView, t as PANEL_CHANNEL } from "./contract-CStSEOcK.js";
|
|
10
10
|
import { MultiRootScopeService, renderWorkspaceRootsContext, sanitizeAdditionalRoots } from "./scope.js";
|
|
11
|
-
import { a as MultiRootRegistry, c as multiRootDomainSpec, i as MAX_ALIAS_LENGTH, l as RegistryAuthorityLease, n as DOMAIN_NAME, o as REGISTRY_CONTENDED_MESSAGE, r as MAX_ADDITIONAL_ROOTS_CEILING, t as DEFAULT_MAX_ADDITIONAL_ROOTS, u as RegistryLeaseContendedError } from "./registry-
|
|
12
|
-
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, o as resolvePanelPrimaryRoot, t as COMMAND_NAME } from "./command-
|
|
11
|
+
import { a as MultiRootRegistry, c as multiRootDomainSpec, i as MAX_ALIAS_LENGTH, l as RegistryAuthorityLease, n as DOMAIN_NAME, o as REGISTRY_CONTENDED_MESSAGE, r as MAX_ADDITIONAL_ROOTS_CEILING, t as DEFAULT_MAX_ADDITIONAL_ROOTS, u as RegistryLeaseContendedError } from "./registry-DR_sMuvS.js";
|
|
12
|
+
import { a as renderRootsReport, c as revealArgv, i as parseFoldersCommand, o as resolvePanelPrimaryRoot, t as COMMAND_NAME } from "./command-Dcz6nULo.js";
|
|
13
13
|
//#region src/index.ts
|
|
14
14
|
/**
|
|
15
15
|
* Carrier plugin face for the bare-package-name loader row (see the module
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { c as loadHostKoffi } from "./protocol-CnR1KTXy.js";
|
|
1
2
|
import { EventEmitter } from "node:events";
|
|
2
3
|
//#region src/authority/native-win32.ts
|
|
3
4
|
/** Windows local pipes: tokens, never a caller-supplied PID or a bearer file. */
|
|
4
5
|
var RestrictedRegistryPeerError = class extends Error {};
|
|
5
6
|
let apiPromise;
|
|
6
7
|
async function load() {
|
|
7
|
-
const koffi =
|
|
8
|
+
const koffi = await loadHostKoffi();
|
|
8
9
|
const kernel = koffi.load("kernel32.dll"), advapi = koffi.load("advapi32.dll");
|
|
9
10
|
const k = (name, ret, args) => kernel.func("__stdcall", name, ret, args);
|
|
10
11
|
const a = (name, ret, args) => advapi.func("__stdcall", name, ret, args);
|
|
@@ -1,8 +1,50 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { closeSync, lstatSync, mkdirSync, readFileSync, realpathSync, statSync, unlinkSync } from "node:fs";
|
|
2
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
4
6
|
import { z } from "zod";
|
|
5
7
|
import { Socket } from "node:net";
|
|
8
|
+
//#region src/compat/koffi.ts
|
|
9
|
+
/**
|
|
10
|
+
* Koffi must be the host's own copy, not this package's `dependencies` entry:
|
|
11
|
+
* `dsh plugin add` installs a private koffi beside the one the host already
|
|
12
|
+
* loaded, and two `koffi.node` images in one process SIGBUS on darwin-arm64
|
|
13
|
+
* pointer authentication (packed-install smoke, 2026-11-01). `dsh-fs-local`
|
|
14
|
+
* carries koffi on every supported release, so anchoring at it yields the
|
|
15
|
+
* single binary the host itself loaded.
|
|
16
|
+
*
|
|
17
|
+
* Two ways to reach that same binary, in order:
|
|
18
|
+
* 1. `require('koffi')` from the host anchor — the live CJS `module.exports`.
|
|
19
|
+
* The host occasionally exposes a partial `{}` exports object for koffi's
|
|
20
|
+
* CJS entry (mid-evaluation or an intercepted require in the addon loader),
|
|
21
|
+
* so the result is validated instead of trusted.
|
|
22
|
+
* 2. The host koffi's own ESM entry (`index.js` beside the resolved CJS
|
|
23
|
+
* entry) — a separate module instance over the same `koffi.node`, immune
|
|
24
|
+
* to a broken CJS cache entry and never a second native image.
|
|
25
|
+
* Only when no host tree resolves at all does the package-local copy load.
|
|
26
|
+
*/
|
|
27
|
+
const pick = (candidate) => {
|
|
28
|
+
let cur = candidate;
|
|
29
|
+
for (let i = 0; i < 3; i++) {
|
|
30
|
+
if (typeof cur?.load === "function") return cur;
|
|
31
|
+
cur = cur?.default;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
async function loadHostKoffi() {
|
|
35
|
+
try {
|
|
36
|
+
const anchor = createRequire(import.meta.url).resolve("@deepseek-ai/dsh-fs-local/package.json");
|
|
37
|
+
const hostRequire = createRequire(anchor);
|
|
38
|
+
const cjs = pick(hostRequire("koffi"));
|
|
39
|
+
if (cjs !== void 0) return cjs;
|
|
40
|
+
const esm = pick(await import(pathToFileURL(join(dirname(hostRequire.resolve("koffi")), "index.js")).href));
|
|
41
|
+
if (esm !== void 0) return esm;
|
|
42
|
+
} catch {}
|
|
43
|
+
const own = pick(await import("koffi"));
|
|
44
|
+
if (own !== void 0) return own;
|
|
45
|
+
return (await import("koffi")).default;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
6
48
|
//#region src/authority/native.ts
|
|
7
49
|
/** Kernel-authenticated local IPC. No credential file and no inherited capability. */
|
|
8
50
|
function storeIdentity(root) {
|
|
@@ -34,7 +76,7 @@ function storeIdentity(root) {
|
|
|
34
76
|
}
|
|
35
77
|
let posixPromise;
|
|
36
78
|
async function loadPosix() {
|
|
37
|
-
const koffi =
|
|
79
|
+
const koffi = await loadHostKoffi();
|
|
38
80
|
const libc = koffi.load(process.platform === "darwin" ? "/usr/lib/libSystem.B.dylib" : "libc.so.6");
|
|
39
81
|
const bind = (name, ret, args) => libc.func(name, ret, args);
|
|
40
82
|
const socketpair = bind("socketpair", "int", [
|
|
@@ -170,7 +212,7 @@ function posix$1() {
|
|
|
170
212
|
return posixPromise ??= loadPosix();
|
|
171
213
|
}
|
|
172
214
|
async function connectNative(endpoint) {
|
|
173
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
215
|
+
if (process.platform === "win32") return (await import("./native-win32-CRNXr11U.js")).connectWindows(endpoint);
|
|
174
216
|
const api = await posix$1(), address = api.address(endpoint), fd = api.open();
|
|
175
217
|
if (api.connect(fd, address, address.length) !== 0) {
|
|
176
218
|
closeSync(fd);
|
|
@@ -180,7 +222,7 @@ async function connectNative(endpoint) {
|
|
|
180
222
|
}
|
|
181
223
|
/** Called only by the kernel lease holder. Never removes another epoch's socket. */
|
|
182
224
|
async function listenNative(endpoint, accepted) {
|
|
183
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
225
|
+
if (process.platform === "win32") return (await import("./native-win32-CRNXr11U.js")).listenWindows(endpoint, accepted);
|
|
184
226
|
const api = await posix$1(), address = api.address(endpoint), fd = api.open();
|
|
185
227
|
try {
|
|
186
228
|
unlinkSync(endpoint);
|
|
@@ -222,14 +264,14 @@ async function listenNative(endpoint, accepted) {
|
|
|
222
264
|
}
|
|
223
265
|
/** Capability probe for native tests and diagnostics; not an authorization bypass. */
|
|
224
266
|
async function nativeHostAvailability() {
|
|
225
|
-
if (process.platform === "win32") return (await import("./native-win32-
|
|
267
|
+
if (process.platform === "win32") return (await import("./native-win32-CRNXr11U.js")).windowsHostAvailability();
|
|
226
268
|
if (process.platform === "linux") {
|
|
227
269
|
if (!/^NoNewPrivs:\s+0$/m.test(readFileSync("/proc/self/status", "utf8"))) return {
|
|
228
270
|
available: false,
|
|
229
271
|
reason: "the Host itself has NoNewPrivs; shared IPC refuses restricted peers"
|
|
230
272
|
};
|
|
231
273
|
} else if (process.platform === "darwin") {
|
|
232
|
-
if ((await
|
|
274
|
+
if ((await loadHostKoffi()).load("/usr/lib/libsandbox.dylib").func("int sandbox_check(int pid, const char *operation, int filter)")(process.pid, null, 0) !== 0) return {
|
|
233
275
|
available: false,
|
|
234
276
|
reason: "the Host itself is sandboxed; shared IPC refuses sandboxed peers"
|
|
235
277
|
};
|
|
@@ -407,8 +449,16 @@ var AuthorityClient = class AuthorityClient {
|
|
|
407
449
|
else request.reject(new AuthorityRpcError(reply.code, reply.message));
|
|
408
450
|
});
|
|
409
451
|
}
|
|
410
|
-
static async connect(endpoint, store, limit, onChange, disconnected) {
|
|
411
|
-
|
|
452
|
+
static async connect(endpoint, store, limit, onChange, disconnected, signal) {
|
|
453
|
+
if (signal?.aborted) throw new AuthorityRpcError("authority-cancelled", "registry handshake was cancelled");
|
|
454
|
+
const channel = await connectNative(endpoint);
|
|
455
|
+
if (signal?.aborted) {
|
|
456
|
+
channel.destroy();
|
|
457
|
+
throw new AuthorityRpcError("authority-cancelled", "registry handshake was cancelled");
|
|
458
|
+
}
|
|
459
|
+
const client = new AuthorityClient(channel, store, limit, onChange, disconnected);
|
|
460
|
+
const onAbort = () => client.close();
|
|
461
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
412
462
|
try {
|
|
413
463
|
const hello = helloSchema.parse(await client.request("hello", [limit]));
|
|
414
464
|
if (hello.store !== store || hello.limit !== limit) throw new Error("registry configuration mismatch");
|
|
@@ -416,7 +466,10 @@ var AuthorityClient = class AuthorityClient {
|
|
|
416
466
|
return client;
|
|
417
467
|
} catch (error) {
|
|
418
468
|
client.close();
|
|
469
|
+
if (signal?.aborted) throw new AuthorityRpcError("authority-cancelled", "registry handshake was cancelled");
|
|
419
470
|
throw error;
|
|
471
|
+
} finally {
|
|
472
|
+
signal?.removeEventListener("abort", onAbort);
|
|
420
473
|
}
|
|
421
474
|
}
|
|
422
475
|
request(method, args) {
|
|
@@ -638,4 +691,4 @@ function parseArguments(method, args) {
|
|
|
638
691
|
return argumentSchemas[method].parse(args);
|
|
639
692
|
}
|
|
640
693
|
//#endregion
|
|
641
|
-
export { snapshotSchema as a, parseArguments as i, AuthorityRpcError as n, nativeHostAvailability as o, AuthorityServer as r, storeIdentity as s, AuthorityClient as t };
|
|
694
|
+
export { snapshotSchema as a, loadHostKoffi as c, parseArguments as i, AuthorityRpcError as n, nativeHostAvailability as o, AuthorityServer as r, storeIdentity as s, AuthorityClient as t };
|