@c0sc0s/orbit 0.5.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/README.md +38 -0
- package/assets/README.md +9 -0
- package/assets/app-icon.png +0 -0
- package/assets/icon.icns +0 -0
- package/assets/logo.png +0 -0
- package/dist/cdp/client.d.ts +33 -0
- package/dist/cdp/client.d.ts.map +1 -0
- package/dist/cdp/client.js +159 -0
- package/dist/cdp/client.js.map +1 -0
- package/dist/cdp/expressions.d.ts +8 -0
- package/dist/cdp/expressions.d.ts.map +1 -0
- package/dist/cdp/expressions.js +27 -0
- package/dist/cdp/expressions.js.map +1 -0
- package/dist/cdp/target-registry.d.ts +33 -0
- package/dist/cdp/target-registry.d.ts.map +1 -0
- package/dist/cdp/target-registry.js +139 -0
- package/dist/cdp/target-registry.js.map +1 -0
- package/dist/cli/arguments.d.ts +13 -0
- package/dist/cli/arguments.d.ts.map +1 -0
- package/dist/cli/arguments.js +29 -0
- package/dist/cli/arguments.js.map +1 -0
- package/dist/cli/platform.d.ts +2 -0
- package/dist/cli/platform.d.ts.map +1 -0
- package/dist/cli/platform.js +68 -0
- package/dist/cli/platform.js.map +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +148 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +13 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/manifest.d.ts +12 -0
- package/dist/config/manifest.d.ts.map +1 -0
- package/dist/config/manifest.js +71 -0
- package/dist/config/manifest.js.map +1 -0
- package/dist/host/daemon.d.ts +54 -0
- package/dist/host/daemon.d.ts.map +1 -0
- package/dist/host/daemon.js +185 -0
- package/dist/host/daemon.js.map +1 -0
- package/dist/host/plugin-host.d.ts +50 -0
- package/dist/host/plugin-host.d.ts.map +1 -0
- package/dist/host/plugin-host.js +230 -0
- package/dist/host/plugin-host.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/installation/entry.d.ts +2 -0
- package/dist/installation/entry.d.ts.map +1 -0
- package/dist/installation/entry.js +14 -0
- package/dist/installation/entry.js.map +1 -0
- package/dist/installation/files.d.ts +5 -0
- package/dist/installation/files.d.ts.map +1 -0
- package/dist/installation/files.js +101 -0
- package/dist/installation/files.js.map +1 -0
- package/dist/installation/legacy.d.ts +19 -0
- package/dist/installation/legacy.d.ts.map +1 -0
- package/dist/installation/legacy.js +52 -0
- package/dist/installation/legacy.js.map +1 -0
- package/dist/installation/lock.d.ts +2 -0
- package/dist/installation/lock.d.ts.map +1 -0
- package/dist/installation/lock.js +18 -0
- package/dist/installation/lock.js.map +1 -0
- package/dist/installation/manager.d.ts +180 -0
- package/dist/installation/manager.d.ts.map +1 -0
- package/dist/installation/manager.js +469 -0
- package/dist/installation/manager.js.map +1 -0
- package/dist/lifecycle/resource-scope.d.ts +11 -0
- package/dist/lifecycle/resource-scope.d.ts.map +1 -0
- package/dist/lifecycle/resource-scope.js +40 -0
- package/dist/lifecycle/resource-scope.js.map +1 -0
- package/dist/platform/codex-process.d.ts +33 -0
- package/dist/platform/codex-process.d.ts.map +1 -0
- package/dist/platform/codex-process.js +122 -0
- package/dist/platform/codex-process.js.map +1 -0
- package/dist/platform/launcher.d.ts +12 -0
- package/dist/platform/launcher.d.ts.map +1 -0
- package/dist/platform/launcher.js +46 -0
- package/dist/platform/launcher.js.map +1 -0
- package/dist/plugins/codex-extension.d.ts +12 -0
- package/dist/plugins/codex-extension.d.ts.map +1 -0
- package/dist/plugins/codex-extension.js +100 -0
- package/dist/plugins/codex-extension.js.map +1 -0
- package/dist/plugins/manifest.d.ts +20 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +51 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/registry.d.ts +3 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +26 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/protocol/ipc.d.ts +38 -0
- package/dist/protocol/ipc.d.ts.map +1 -0
- package/dist/protocol/ipc.js +5 -0
- package/dist/protocol/ipc.js.map +1 -0
- package/dist/protocol/types.d.ts +55 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +2 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/renderer/loader.d.ts +32 -0
- package/dist/renderer/loader.d.ts.map +1 -0
- package/dist/renderer/loader.js +130 -0
- package/dist/renderer/loader.js.map +1 -0
- package/dist/renderer/transport.d.ts +28 -0
- package/dist/renderer/transport.d.ts.map +1 -0
- package/dist/renderer/transport.js +89 -0
- package/dist/renderer/transport.js.map +1 -0
- package/dist/sdk/contracts.d.ts +50 -0
- package/dist/sdk/contracts.d.ts.map +1 -0
- package/dist/sdk/contracts.js +2 -0
- package/dist/sdk/contracts.js.map +1 -0
- package/dist/service/module.d.ts +24 -0
- package/dist/service/module.d.ts.map +1 -0
- package/dist/service/module.js +97 -0
- package/dist/service/module.js.map +1 -0
- package/dist/service/process.d.ts +32 -0
- package/dist/service/process.d.ts.map +1 -0
- package/dist/service/process.js +95 -0
- package/dist/service/process.js.map +1 -0
- package/dist/service/worker.d.ts +2 -0
- package/dist/service/worker.d.ts.map +1 -0
- package/dist/service/worker.js +116 -0
- package/dist/service/worker.js.map +1 -0
- package/examples/hello.js +10 -0
- package/examples/loader.json +4 -0
- package/examples/service-loader.json +4 -0
- package/examples/service.js +10 -0
- package/examples/service.mjs +3 -0
- package/package.json +40 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type ServiceRequest = {
|
|
2
|
+
type: "activate";
|
|
3
|
+
id: number;
|
|
4
|
+
entry: string;
|
|
5
|
+
pluginId: string;
|
|
6
|
+
config: Record<string, unknown>;
|
|
7
|
+
stateDirectory: string;
|
|
8
|
+
} | {
|
|
9
|
+
type: "cancel";
|
|
10
|
+
requestId: number;
|
|
11
|
+
} | {
|
|
12
|
+
type: "dispose";
|
|
13
|
+
id: number;
|
|
14
|
+
} | {
|
|
15
|
+
type: "connect" | "disconnect";
|
|
16
|
+
id: number;
|
|
17
|
+
clientId: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: "call";
|
|
20
|
+
id: number;
|
|
21
|
+
method: string;
|
|
22
|
+
payload?: unknown;
|
|
23
|
+
clientId: string;
|
|
24
|
+
};
|
|
25
|
+
export type ServiceEvent = {
|
|
26
|
+
type: "event";
|
|
27
|
+
topic: string;
|
|
28
|
+
payload: unknown;
|
|
29
|
+
clientId?: string;
|
|
30
|
+
};
|
|
31
|
+
export type ServiceReply = {
|
|
32
|
+
type?: "reply";
|
|
33
|
+
id: number;
|
|
34
|
+
error?: string;
|
|
35
|
+
value?: unknown;
|
|
36
|
+
};
|
|
37
|
+
export declare function assertMessageSize(value: unknown): void;
|
|
38
|
+
//# sourceMappingURL=ipc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../../src/protocol/ipc.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC1H;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AACtF,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACjG,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAC3F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,QAE/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc.js","sourceRoot":"","sources":["../../src/protocol/ipc.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;AACzH,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { PluginEntry } from "../sdk/contracts.js";
|
|
2
|
+
export interface PluginDescriptor {
|
|
3
|
+
id: string;
|
|
4
|
+
version: string;
|
|
5
|
+
expression: string;
|
|
6
|
+
instanceId?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface PluginEndpoint {
|
|
9
|
+
binding: string | null;
|
|
10
|
+
token: string | null;
|
|
11
|
+
}
|
|
12
|
+
export interface PluginSource {
|
|
13
|
+
id: string;
|
|
14
|
+
version: string;
|
|
15
|
+
source: string;
|
|
16
|
+
apiVersion?: 1;
|
|
17
|
+
config?: Record<string, unknown>;
|
|
18
|
+
owner?: string | null;
|
|
19
|
+
endpoint?: PluginEndpoint;
|
|
20
|
+
}
|
|
21
|
+
export interface LoaderManifest {
|
|
22
|
+
path: string;
|
|
23
|
+
root: string;
|
|
24
|
+
plugins: PluginEntry[];
|
|
25
|
+
}
|
|
26
|
+
export interface Target {
|
|
27
|
+
id: string;
|
|
28
|
+
type?: string;
|
|
29
|
+
url?: string;
|
|
30
|
+
webSocketDebuggerUrl: string;
|
|
31
|
+
}
|
|
32
|
+
export interface BindingCall {
|
|
33
|
+
name: string;
|
|
34
|
+
payload: string;
|
|
35
|
+
executionContextId: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PluginResult {
|
|
38
|
+
targetId?: string;
|
|
39
|
+
pluginId: string | null;
|
|
40
|
+
status?: unknown;
|
|
41
|
+
injected?: boolean;
|
|
42
|
+
stage?: string;
|
|
43
|
+
error?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface CleanupFailure {
|
|
46
|
+
pluginId: string;
|
|
47
|
+
stage: string;
|
|
48
|
+
}
|
|
49
|
+
export interface PluginSummary {
|
|
50
|
+
id: string;
|
|
51
|
+
version: string;
|
|
52
|
+
instanceId?: string;
|
|
53
|
+
state: string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/protocol/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE;AAC1G,MAAM,WAAW,cAAc;IAAG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AAChF,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE;AACjL,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE;AACtF,MAAM,WAAW,MAAM;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAA;CAAE;AACjG,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAE;AAC1F,MAAM,WAAW,YAAY;IAAG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAClJ,MAAM,WAAW,cAAc;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACnE,MAAM,WAAW,aAAa;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/protocol/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { RendererContext, RendererPlugin, MaybePromise } from "../sdk/contracts.js";
|
|
2
|
+
import type { PluginEndpoint, PluginSummary } from "../protocol/types.js";
|
|
3
|
+
import type { createResourceScope as scopeFactory } from "../lifecycle/resource-scope.js";
|
|
4
|
+
import type { createRendererTransport as transportFactory, TransportMessage } from "./transport.js";
|
|
5
|
+
interface RendererManifest {
|
|
6
|
+
apiVersion: number;
|
|
7
|
+
id: string;
|
|
8
|
+
version: string;
|
|
9
|
+
instanceId?: string;
|
|
10
|
+
owner?: string | null;
|
|
11
|
+
endpoint?: PluginEndpoint;
|
|
12
|
+
}
|
|
13
|
+
interface RendererLoader {
|
|
14
|
+
apiVersion: number;
|
|
15
|
+
version: string;
|
|
16
|
+
claim(id: string, owner: string): boolean;
|
|
17
|
+
release(id: string, owner: string): Promise<boolean>;
|
|
18
|
+
status(id?: string): PluginSummary[] | PluginSummary | null;
|
|
19
|
+
load(manifest: RendererManifest, activate: (context: RendererContext) => MaybePromise<RendererPlugin | void>, config?: Record<string, unknown>): Promise<PluginSummary | null>;
|
|
20
|
+
unload(id: string): Promise<boolean>;
|
|
21
|
+
deliver(id: string, message: TransportMessage): boolean;
|
|
22
|
+
dispatch(id: string, message: unknown): MaybePromise<unknown>;
|
|
23
|
+
inspect(id: string): unknown;
|
|
24
|
+
}
|
|
25
|
+
declare global {
|
|
26
|
+
interface Window {
|
|
27
|
+
__codexPluginLoader?: RendererLoader;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export declare function installLoader(createResourceScope: typeof scopeFactory, version: string, createRendererTransport: typeof transportFactory): RendererLoader;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/renderer/loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,mBAAmB,IAAI,YAAY,EAAiB,MAAM,gCAAgC,CAAC;AACzG,OAAO,KAAK,EAAE,uBAAuB,IAAI,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpG,UAAU,gBAAgB;IAAG,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE;AAErJ,UAAU,cAAc;IACtB,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IACpC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1C,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,aAAa,GAAG,IAAI,CAAC;IAC5D,IAAI,CAAC,QAAQ,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAC/K,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;IACxD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AACD,OAAO,CAAC,MAAM,CAAC;IAAE,UAAU,MAAM;QAAG,mBAAmB,CAAC,EAAE,cAAc,CAAA;KAAE;CAAE;AAE5E,wBAAgB,aAAa,CAAC,mBAAmB,EAAE,OAAO,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,OAAO,gBAAgB,GAAG,cAAc,CAqGzJ"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// This function is serialized into the renderer; keep it independent of module scope.
|
|
2
|
+
export function installLoader(createResourceScope, version, createRendererTransport) {
|
|
3
|
+
const existing = window.__codexPluginLoader;
|
|
4
|
+
if (existing) {
|
|
5
|
+
if (existing.apiVersion === 1 && existing.version === version)
|
|
6
|
+
return existing;
|
|
7
|
+
if (existing.apiVersion !== 1 || existing.status().length)
|
|
8
|
+
throw new Error("Incompatible Codex Plugin Loader is active; unload its plugins before upgrading");
|
|
9
|
+
}
|
|
10
|
+
const plugins = new Map();
|
|
11
|
+
const owners = new Map();
|
|
12
|
+
const queues = new Map();
|
|
13
|
+
const serialize = (id, operation) => {
|
|
14
|
+
const next = (queues.get(id) ?? Promise.resolve()).catch(() => { }).then(operation);
|
|
15
|
+
queues.set(id, next);
|
|
16
|
+
next.finally(() => { if (queues.get(id) === next)
|
|
17
|
+
queues.delete(id); }).catch(() => { });
|
|
18
|
+
return next;
|
|
19
|
+
};
|
|
20
|
+
const isActive = (record) => {
|
|
21
|
+
try {
|
|
22
|
+
return record.instance?.isActive?.() !== false;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const summary = (record) => record ? {
|
|
29
|
+
id: record.id, version: record.version,
|
|
30
|
+
...(record.instanceId ? { instanceId: record.instanceId } : {}),
|
|
31
|
+
state: record.state === "active" && !isActive(record) ? "inactive" : record.state,
|
|
32
|
+
} : null;
|
|
33
|
+
const clean = async (record) => {
|
|
34
|
+
record.state = "unloading";
|
|
35
|
+
try {
|
|
36
|
+
await record.scope.close();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
record.state = "cleanup-failed";
|
|
40
|
+
throw new Error(`Plugin ${record.id} cleanup failed`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const loader = {
|
|
44
|
+
apiVersion: 1,
|
|
45
|
+
version,
|
|
46
|
+
claim(id, owner) {
|
|
47
|
+
if (owners.has(id) && owners.get(id) !== owner)
|
|
48
|
+
return false;
|
|
49
|
+
owners.set(id, owner);
|
|
50
|
+
return true;
|
|
51
|
+
},
|
|
52
|
+
async release(id, owner) {
|
|
53
|
+
if (owners.has(id) && owners.get(id) !== owner)
|
|
54
|
+
throw new Error("Plugin belongs to another Loader configuration");
|
|
55
|
+
const result = await loader.unload(id);
|
|
56
|
+
owners.delete(id);
|
|
57
|
+
return result;
|
|
58
|
+
},
|
|
59
|
+
status: (id) => id === undefined ? [...plugins.values()].map(record => summary(record)) : summary(plugins.get(id)),
|
|
60
|
+
load: (manifest, activate, config = {}) => {
|
|
61
|
+
if (!manifest || manifest.apiVersion !== 1 || typeof manifest.id !== "string" || !/^[a-z][a-z0-9.-]{0,63}$/.test(manifest.id)
|
|
62
|
+
|| typeof manifest.version !== "string" || !manifest.version || typeof activate !== "function") {
|
|
63
|
+
return Promise.reject(new Error("Invalid plugin contract"));
|
|
64
|
+
}
|
|
65
|
+
return serialize(manifest.id, async () => {
|
|
66
|
+
if (manifest.owner && owners.get(manifest.id) !== manifest.owner)
|
|
67
|
+
throw new Error("Plugin ownership changed");
|
|
68
|
+
const previous = plugins.get(manifest.id);
|
|
69
|
+
if (summary(previous)?.state === "active" && previous?.version === manifest.version && previous.instanceId === manifest.instanceId)
|
|
70
|
+
return summary(previous);
|
|
71
|
+
if (previous?.state === "cleanup-failed")
|
|
72
|
+
throw new Error(`Plugin ${manifest.id} requires a renderer reload after failed cleanup`);
|
|
73
|
+
if (previous) {
|
|
74
|
+
await clean(previous);
|
|
75
|
+
plugins.delete(manifest.id);
|
|
76
|
+
}
|
|
77
|
+
const record = { id: manifest.id, version: manifest.version, instanceId: manifest.instanceId, state: "loading", scope: createResourceScope(), instance: null };
|
|
78
|
+
plugins.set(manifest.id, record);
|
|
79
|
+
record.transport = createRendererTransport(manifest.endpoint ?? { binding: null, token: null }, record.scope);
|
|
80
|
+
try {
|
|
81
|
+
const activation = Promise.resolve().then(() => activate(Object.freeze({
|
|
82
|
+
id: manifest.id, config, signal: record.scope.signal, onDispose: record.scope.onDispose,
|
|
83
|
+
rpc: record.transport.rpc, events: record.transport.events,
|
|
84
|
+
}))).then((instance) => {
|
|
85
|
+
if (typeof instance?.dispose === "function")
|
|
86
|
+
record.scope.onDispose(() => instance.dispose?.());
|
|
87
|
+
return instance;
|
|
88
|
+
});
|
|
89
|
+
record.instance = await record.scope.bounded(() => activation, "Activation");
|
|
90
|
+
if (record.scope.signal.aborted)
|
|
91
|
+
throw new Error("Activation cancelled");
|
|
92
|
+
record.state = "active";
|
|
93
|
+
return summary(record);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
await clean(record);
|
|
97
|
+
record.state = error instanceof Error && error.message === "Activation timed out" ? "cleanup-failed" : "failed";
|
|
98
|
+
throw new Error(`Plugin ${manifest.id} activation failed`);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
unload: (id) => {
|
|
103
|
+
plugins.get(id)?.scope.abort();
|
|
104
|
+
return serialize(id, async () => {
|
|
105
|
+
const record = plugins.get(id);
|
|
106
|
+
if (!record)
|
|
107
|
+
return false;
|
|
108
|
+
if (record.state === "cleanup-failed")
|
|
109
|
+
throw new Error(`Plugin ${id} requires a renderer reload after failed cleanup`);
|
|
110
|
+
await clean(record);
|
|
111
|
+
plugins.delete(id);
|
|
112
|
+
return true;
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
deliver: (id, message) => plugins.get(id)?.transport?.deliver(message) ?? false,
|
|
116
|
+
dispatch: (id, message) => {
|
|
117
|
+
const record = plugins.get(id);
|
|
118
|
+
if (summary(record)?.state !== "active")
|
|
119
|
+
return false;
|
|
120
|
+
return record?.instance?.handleMessage?.(message) ?? false;
|
|
121
|
+
},
|
|
122
|
+
inspect: (id) => {
|
|
123
|
+
const record = plugins.get(id);
|
|
124
|
+
return record?.state === "active" ? record.instance?.status?.() ?? summary(record) : summary(record);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
window.__codexPluginLoader = Object.freeze(loader);
|
|
128
|
+
return loader;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/renderer/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { MaybePromise, RpcOptions } from "../sdk/contracts.js";
|
|
2
|
+
import type { PluginEndpoint } from "../protocol/types.js";
|
|
3
|
+
import type { ResourceScope } from "../lifecycle/resource-scope.js";
|
|
4
|
+
type Reply = {
|
|
5
|
+
type: "reply";
|
|
6
|
+
token?: string;
|
|
7
|
+
id: number;
|
|
8
|
+
error?: string;
|
|
9
|
+
value?: unknown;
|
|
10
|
+
};
|
|
11
|
+
type EventMessage = {
|
|
12
|
+
type: "event";
|
|
13
|
+
token?: string;
|
|
14
|
+
topic: string;
|
|
15
|
+
payload?: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type TransportMessage = Reply | EventMessage;
|
|
18
|
+
export declare function createRendererTransport(endpoint: PluginEndpoint, scope: ResourceScope): {
|
|
19
|
+
rpc: Readonly<{
|
|
20
|
+
call<T = unknown>(method: string, payload?: unknown, options?: RpcOptions): Promise<T>;
|
|
21
|
+
}>;
|
|
22
|
+
events: Readonly<{
|
|
23
|
+
subscribe(topic: string, handler: (payload: unknown) => MaybePromise<unknown>): () => void;
|
|
24
|
+
}>;
|
|
25
|
+
deliver(message: TransportMessage): boolean;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/renderer/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,KAAK,KAAK,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAC5F,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACxF,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,YAAY,CAAC;AAEpD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa;;aAYxD,CAAC,oBAAoB,MAAM,YAAW,OAAO,YAAkB,UAAU,GAAQ,OAAO,CAAC,CAAC,CAAC;;;yBAyB5E,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,KAAK,YAAY,CAAC,OAAO,CAAC;;qBAQpF,gBAAgB;EAmBpC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Serialized with the Loader; no module-scope dependencies are available in the renderer.
|
|
2
|
+
export function createRendererTransport(endpoint, scope) {
|
|
3
|
+
const pending = new Map();
|
|
4
|
+
const subscribers = new Map();
|
|
5
|
+
let sequence = 0;
|
|
6
|
+
const send = (message) => {
|
|
7
|
+
const encoded = JSON.stringify({ ...message, token: endpoint.token });
|
|
8
|
+
if (new TextEncoder().encode(encoded).byteLength > 65_536)
|
|
9
|
+
throw new Error("RPC request exceeds 64 KiB");
|
|
10
|
+
const binding = window[endpoint.binding ?? ""];
|
|
11
|
+
if (typeof binding !== "function")
|
|
12
|
+
throw new Error("Plugin service is unavailable");
|
|
13
|
+
binding(encoded);
|
|
14
|
+
};
|
|
15
|
+
const transport = {
|
|
16
|
+
rpc: Object.freeze({ call(method, payload = null, options = {}) {
|
|
17
|
+
if (scope.signal.aborted || options.signal?.aborted)
|
|
18
|
+
return Promise.reject(new Error("RPC cancelled"));
|
|
19
|
+
if (typeof method !== "string" || !method || method.length > 128)
|
|
20
|
+
return Promise.reject(new Error("Invalid RPC method"));
|
|
21
|
+
if (pending.size >= 128)
|
|
22
|
+
return Promise.reject(new Error("Too many pending RPC requests"));
|
|
23
|
+
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
24
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs < 1 || timeoutMs > 30_000)
|
|
25
|
+
return Promise.reject(new Error("RPC timeout must be between 1 and 30000 ms"));
|
|
26
|
+
const id = ++sequence;
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
const finish = (error, value) => {
|
|
29
|
+
if (!pending.delete(id))
|
|
30
|
+
return;
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
options.signal?.removeEventListener("abort", abort);
|
|
33
|
+
error ? reject(error) : resolve(value);
|
|
34
|
+
};
|
|
35
|
+
const cancel = (reason) => {
|
|
36
|
+
try {
|
|
37
|
+
send({ type: "cancel", id });
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
finish(new Error(reason));
|
|
41
|
+
};
|
|
42
|
+
const abort = () => cancel("RPC cancelled");
|
|
43
|
+
const timer = setTimeout(() => cancel("RPC timed out"), timeoutMs);
|
|
44
|
+
pending.set(id, { finish, cancel });
|
|
45
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
46
|
+
try {
|
|
47
|
+
send({ type: "call", id, method, payload, timeoutMs });
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
finish(error);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
} }),
|
|
54
|
+
events: Object.freeze({ subscribe(topic, handler) {
|
|
55
|
+
if (scope.signal.aborted)
|
|
56
|
+
throw new Error("Plugin is closing");
|
|
57
|
+
if (typeof topic !== "string" || !topic || typeof handler !== "function")
|
|
58
|
+
throw new Error("Invalid event subscription");
|
|
59
|
+
const handlers = subscribers.get(topic) ?? new Set();
|
|
60
|
+
subscribers.set(topic, handlers);
|
|
61
|
+
handlers.add(handler);
|
|
62
|
+
return () => { handlers.delete(handler); if (!handlers.size)
|
|
63
|
+
subscribers.delete(topic); };
|
|
64
|
+
} }),
|
|
65
|
+
deliver(message) {
|
|
66
|
+
if (scope.signal.aborted || message?.token !== endpoint.token)
|
|
67
|
+
return false;
|
|
68
|
+
if (message.type === "reply") {
|
|
69
|
+
const request = pending.get(message.id);
|
|
70
|
+
request?.finish(message.error ? new Error(message.error) : null, message.value);
|
|
71
|
+
return Boolean(request);
|
|
72
|
+
}
|
|
73
|
+
if (message.type === "event") {
|
|
74
|
+
for (const handler of subscribers.get(message.topic) ?? [])
|
|
75
|
+
Promise.resolve().then(() => { if (!scope.signal.aborted)
|
|
76
|
+
return handler(message.payload); }).catch(() => { });
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
scope.onDispose(() => {
|
|
83
|
+
for (const request of [...pending.values()])
|
|
84
|
+
request.cancel("Plugin unloaded");
|
|
85
|
+
subscribers.clear();
|
|
86
|
+
});
|
|
87
|
+
return transport;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/renderer/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
2
|
+
export interface PluginEntry {
|
|
3
|
+
id: string;
|
|
4
|
+
version: string;
|
|
5
|
+
entry: string;
|
|
6
|
+
service?: string;
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
config?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface ResourceContext {
|
|
11
|
+
id: string;
|
|
12
|
+
config: Record<string, unknown>;
|
|
13
|
+
signal: AbortSignal;
|
|
14
|
+
onDispose(dispose: () => MaybePromise<unknown>): void;
|
|
15
|
+
}
|
|
16
|
+
export interface RpcOptions {
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface RendererContext extends ResourceContext {
|
|
21
|
+
rpc: {
|
|
22
|
+
call<T = unknown>(method: string, payload?: unknown, options?: RpcOptions): Promise<T>;
|
|
23
|
+
};
|
|
24
|
+
events: {
|
|
25
|
+
subscribe(topic: string, handler: (payload: unknown) => MaybePromise<unknown>): () => void;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export interface RendererPlugin {
|
|
29
|
+
dispose?(): MaybePromise<unknown>;
|
|
30
|
+
isActive?(): boolean;
|
|
31
|
+
status?(): unknown;
|
|
32
|
+
handleMessage?(message: unknown): MaybePromise<unknown>;
|
|
33
|
+
}
|
|
34
|
+
export interface ServiceContext extends ResourceContext {
|
|
35
|
+
stateDirectory: string;
|
|
36
|
+
rpc: {
|
|
37
|
+
handle(method: string, handler: (payload: unknown, request: {
|
|
38
|
+
clientId: string;
|
|
39
|
+
signal: AbortSignal;
|
|
40
|
+
}) => MaybePromise<unknown>): void;
|
|
41
|
+
};
|
|
42
|
+
events: {
|
|
43
|
+
publish(topic: string, payload: unknown, clientId?: string): void;
|
|
44
|
+
};
|
|
45
|
+
clients: {
|
|
46
|
+
onConnect(handler: (clientId: string) => MaybePromise<unknown>): () => void;
|
|
47
|
+
onDisconnect(handler: (clientId: string) => MaybePromise<unknown>): () => void;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=contracts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/sdk/contracts.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7C,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAClJ,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IACjE,SAAS,CAAC,OAAO,EAAE,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;CACvD;AACD,MAAM,WAAW,UAAU;IAAG,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACxE,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,GAAG,EAAE;QAAE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;IAChG,MAAM,EAAE;QAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,YAAY,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAA;KAAE,CAAC;CACxG;AACD,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,OAAO,CAAC;IACrB,MAAM,CAAC,IAAI,OAAO,CAAC;IACnB,aAAa,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;CACzD;AACD,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE;QAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,WAAW,CAAA;SAAE,KAAK,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC;IAChJ,MAAM,EAAE;QAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC9E,OAAO,EAAE;QACP,SAAS,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,YAAY,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;QAC5E,YAAY,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,YAAY,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI,CAAC;KAChF,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/sdk/contracts.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CdpClient } from "../cdp/client.js";
|
|
2
|
+
import type { PluginEntry, MaybePromise } from "../sdk/contracts.js";
|
|
3
|
+
import type { PluginDescriptor, BindingCall } from "../protocol/types.js";
|
|
4
|
+
import type { ResourceScope } from "../lifecycle/resource-scope.js";
|
|
5
|
+
export interface HostModule {
|
|
6
|
+
renderer(client: CdpClient): MaybePromise<PluginDescriptor>;
|
|
7
|
+
bindings?: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
handle(client: CdpClient, params: BindingCall): MaybePromise<unknown>;
|
|
10
|
+
}>;
|
|
11
|
+
cancelPending?(): void;
|
|
12
|
+
tick?(): MaybePromise<void>;
|
|
13
|
+
onReady?(client: CdpClient): MaybePromise<unknown>;
|
|
14
|
+
onTargetRemoved?(id: string): MaybePromise<void>;
|
|
15
|
+
dispose?(): MaybePromise<void>;
|
|
16
|
+
}
|
|
17
|
+
/** Adapts the business SDK to the host's private target lifecycle. */
|
|
18
|
+
export declare function createServiceModule(entry: PluginEntry, { root, stateDirectory, owner, onDispose }: {
|
|
19
|
+
root: string;
|
|
20
|
+
stateDirectory: string;
|
|
21
|
+
owner: string | null;
|
|
22
|
+
onDispose: ResourceScope["onDispose"];
|
|
23
|
+
}): Promise<HostModule>;
|
|
24
|
+
//# sourceMappingURL=module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/service/module.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAiB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAC5D,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC1G,aAAa,CAAC,IAAI,IAAI,CAAC;IACvB,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,CAAC,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnD,eAAe,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;CAChC;AAED,sEAAsE;AACtE,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CA4DpO"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { buildPluginExpression } from "../cdp/expressions.js";
|
|
4
|
+
import { resolvePluginEntry } from "../config/manifest.js";
|
|
5
|
+
import { ServiceProcess } from "./process.js";
|
|
6
|
+
/** Adapts the business SDK to the host's private target lifecycle. */
|
|
7
|
+
export async function createServiceModule(entry, { root, stateDirectory, owner, onDispose }) {
|
|
8
|
+
const source = await readFile(await resolvePluginEntry(root, entry.entry), "utf8");
|
|
9
|
+
const clients = new Map();
|
|
10
|
+
const binding = `__codexPlugin_${entry.id.replaceAll(/[^a-z0-9]/g, "_")}_${randomBytes(6).toString("hex")}`;
|
|
11
|
+
const deliver = async (state, message) => {
|
|
12
|
+
if (!state.client.connected || state.client.generation !== state.generation || clients.get(state.client.target.id) !== state)
|
|
13
|
+
return;
|
|
14
|
+
return state.client.evaluate(`window.__codexPluginLoader?.deliver(${JSON.stringify(entry.id)}, ${JSON.stringify({ ...message, token: state.token })})`, state.contextId);
|
|
15
|
+
};
|
|
16
|
+
const service = entry.service ? new ServiceProcess({
|
|
17
|
+
entry: await resolvePluginEntry(root, entry.service), id: entry.id, config: entry.config ?? {}, stateDirectory,
|
|
18
|
+
onEvent: (message) => Promise.allSettled([...clients.values()].filter((state) => message.clientId === undefined || state.token === message.clientId).map((state) => deliver(state, message))),
|
|
19
|
+
}) : null;
|
|
20
|
+
onDispose(() => service?.close());
|
|
21
|
+
await service?.ready;
|
|
22
|
+
const disconnect = async (id) => {
|
|
23
|
+
const state = clients.get(id);
|
|
24
|
+
if (!state)
|
|
25
|
+
return;
|
|
26
|
+
clients.delete(id);
|
|
27
|
+
for (const request of state.pending.values())
|
|
28
|
+
request.abort();
|
|
29
|
+
await service?.request("disconnect", { clientId: state.token }, { timeoutMs: 1000 }).catch(() => { });
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
cancelPending() { for (const state of clients.values())
|
|
33
|
+
for (const controller of state.pending.values())
|
|
34
|
+
controller.abort(); },
|
|
35
|
+
tick() { if (service?.closed)
|
|
36
|
+
throw new Error("Plugin service exited"); },
|
|
37
|
+
async renderer(client) {
|
|
38
|
+
if (service?.closed)
|
|
39
|
+
throw new Error("Plugin service exited; restart the module");
|
|
40
|
+
const status = await client.evaluate(`window.__codexPluginLoader?.status(${JSON.stringify(entry.id)})`);
|
|
41
|
+
if (clients.has(client.target.id) && status?.state !== "active")
|
|
42
|
+
await disconnect(client.target.id);
|
|
43
|
+
let state = clients.get(client.target.id);
|
|
44
|
+
if (!state) {
|
|
45
|
+
state = { client, token: randomBytes(24).toString("hex"), generation: client.generation, contextId: client.worldContextId, pending: new Map() };
|
|
46
|
+
clients.set(client.target.id, state);
|
|
47
|
+
}
|
|
48
|
+
return state.descriptor ??= { id: entry.id, version: entry.version, instanceId: state.token, expression: buildPluginExpression({
|
|
49
|
+
...entry, source, owner, endpoint: { binding, token: state.token },
|
|
50
|
+
}) };
|
|
51
|
+
},
|
|
52
|
+
bindings: service ? [{ name: binding, async handle(client, params) {
|
|
53
|
+
const state = clients.get(client.target.id);
|
|
54
|
+
if (!state || state.client !== client || state.generation !== client.generation || typeof params.payload !== "string" || Buffer.byteLength(params.payload) > 65_536)
|
|
55
|
+
return;
|
|
56
|
+
let request;
|
|
57
|
+
try {
|
|
58
|
+
request = JSON.parse(params.payload);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (request?.token !== state.token || !Number.isSafeInteger(request.id) || request.id < 1)
|
|
64
|
+
return;
|
|
65
|
+
if (state.contextId !== undefined && state.contextId !== params.executionContextId)
|
|
66
|
+
return;
|
|
67
|
+
state.contextId = params.executionContextId;
|
|
68
|
+
if (request.type === "cancel") {
|
|
69
|
+
state.pending.get(request.id)?.abort();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (request.type !== "call" || !Number.isFinite(request.timeoutMs) || request.timeoutMs < 1 || request.timeoutMs > 30_000 || typeof request.method !== "string" || request.method.length > 128 || state.pending.has(request.id))
|
|
73
|
+
return;
|
|
74
|
+
if (state.pending.size >= 128) {
|
|
75
|
+
await deliver(state, { type: "reply", id: request.id, error: "Too many pending RPC requests" });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const controller = new AbortController();
|
|
79
|
+
state.pending.set(request.id, controller);
|
|
80
|
+
try {
|
|
81
|
+
const value = await service.request("call", { method: request.method, payload: request.payload, clientId: state.token }, { signal: controller.signal, timeoutMs: request.timeoutMs });
|
|
82
|
+
await deliver(state, { type: "reply", id: request.id, value });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
await deliver(state, { type: "reply", id: request.id, error: "Plugin service request failed" });
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
state.pending.delete(request.id);
|
|
89
|
+
}
|
|
90
|
+
} }] : [],
|
|
91
|
+
onReady: (client) => service?.request("connect", { clientId: clients.get(client.target.id).token }),
|
|
92
|
+
onTargetRemoved: disconnect,
|
|
93
|
+
async dispose() { for (const id of [...clients.keys()])
|
|
94
|
+
await disconnect(id); },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=module.js.map
|