@phreshos/node 0.1.3 → 0.1.4
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/system.d.ts +1 -191
- package/dist/system.js +101 -95
- package/package.json +2 -2
package/dist/system.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { Client as CoreClient, ClientService as CoreClientService, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, ServerService as CoreServerService, type
|
|
2
|
-
import Events from "./events.js";
|
|
3
|
-
import { type TransportEvent } from "./transport.js";
|
|
1
|
+
import { Client as CoreClient, ClientService as CoreClientService, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, ServerService as CoreServerService, type ProgramDefinition, type ProgramCommandChunk, type ServiceKey, type System as CoreSystem, type SystemClientEntity, type SystemEndpointEntity, type SystemProcessEntity, type SystemProcess, type SystemProgram, type SystemProgramEntity, type SystemServerEntity, type SystemUploads, type WritableAppearance } from "@phreshos/core";
|
|
4
2
|
export type ProgramProcessRunOptions = Readonly<{
|
|
5
3
|
signal?: AbortSignal;
|
|
6
4
|
}>;
|
|
@@ -14,29 +12,13 @@ export type ProgramProcessRunEvent = Readonly<{
|
|
|
14
12
|
process: SystemProcessEntity;
|
|
15
13
|
exit: import("@phreshos/core").Exit;
|
|
16
14
|
}>;
|
|
17
|
-
interface SystemTransport {
|
|
18
|
-
control(request: object, signal?: AbortSignal): Promise<unknown>;
|
|
19
|
-
api(request: object, signal?: AbortSignal): Promise<unknown>;
|
|
20
|
-
lifecycle(request: object, signal?: AbortSignal): AsyncGenerator<TransportEvent, void, void>;
|
|
21
|
-
}
|
|
22
|
-
declare const ProgramBase: new () => object;
|
|
23
|
-
declare const ProcessBase: new () => object;
|
|
24
|
-
declare const ServerBase: new () => object;
|
|
25
|
-
declare const ClientBase: new () => object;
|
|
26
15
|
/** One connected owner-local implementation of the shared System contract. */
|
|
27
16
|
export declare class System implements CoreSystem {
|
|
28
|
-
private readonly connection;
|
|
29
|
-
readonly home: string;
|
|
30
|
-
readonly address: string;
|
|
31
17
|
readonly storage: import("@phreshos/core").Storage;
|
|
32
18
|
readonly appearance: WritableAppearance;
|
|
33
19
|
readonly program: SystemProgram;
|
|
34
20
|
readonly process: SystemProcess;
|
|
35
21
|
readonly uploads: SystemUploads;
|
|
36
|
-
readonly transport: SystemTransport;
|
|
37
|
-
private closed;
|
|
38
|
-
private readonly lifetime;
|
|
39
|
-
private readonly handles;
|
|
40
22
|
private constructor();
|
|
41
23
|
/** Connect to the System selected by argument, environment, or owner default. */
|
|
42
24
|
static connect(home?: string): Promise<System>;
|
|
@@ -50,148 +32,6 @@ export declare class System implements CoreSystem {
|
|
|
50
32
|
service<EventsMap extends object = {}>(key: ServiceKey & {
|
|
51
33
|
endpoint: "client";
|
|
52
34
|
}): ClientService<EventsMap>;
|
|
53
|
-
programHandle(snapshot: ProgramSnapshot): ProgramHandle;
|
|
54
|
-
processHandle(snapshot: ProcessSnapshot): ProcessHandle;
|
|
55
|
-
private signal;
|
|
56
|
-
private requireConnected;
|
|
57
|
-
}
|
|
58
|
-
interface ProgramHandle extends SystemProgramEntity {
|
|
59
|
-
}
|
|
60
|
-
declare class ProgramHandle extends ProgramBase {
|
|
61
|
-
private readonly system;
|
|
62
|
-
private readonly reference;
|
|
63
|
-
readonly identity: string;
|
|
64
|
-
readonly process: ProgramProcesses;
|
|
65
|
-
readonly startup: ProgramStartup;
|
|
66
|
-
private snapshot;
|
|
67
|
-
constructor(system: System, snapshot: ProgramSnapshot);
|
|
68
|
-
get name(): string;
|
|
69
|
-
get version(): string | null;
|
|
70
|
-
get description(): string | null;
|
|
71
|
-
get hasAgent(): boolean;
|
|
72
|
-
get server(): EndpointDeclaration | null;
|
|
73
|
-
get client(): ClientDeclaration | null;
|
|
74
|
-
update(snapshot: ProgramSnapshot): void;
|
|
75
|
-
agent(): Promise<string | null>;
|
|
76
|
-
installed(): Promise<boolean>;
|
|
77
|
-
install(): AsyncGenerator<Readonly<{
|
|
78
|
-
stream: "stdout" | "stderr";
|
|
79
|
-
text: string;
|
|
80
|
-
}>, void, void>;
|
|
81
|
-
uninstall(everything?: boolean): AsyncGenerator<Readonly<{
|
|
82
|
-
stream: "stdout" | "stderr";
|
|
83
|
-
text: string;
|
|
84
|
-
}>, void, void>;
|
|
85
|
-
forget(): Promise<void>;
|
|
86
|
-
address(): Readonly<{
|
|
87
|
-
identity: string;
|
|
88
|
-
reference: string;
|
|
89
|
-
}>;
|
|
90
|
-
}
|
|
91
|
-
declare class ProgramStartup {
|
|
92
|
-
private readonly system;
|
|
93
|
-
private readonly program;
|
|
94
|
-
constructor(system: System, program: ProgramHandle);
|
|
95
|
-
get(): Promise<Readonly<{
|
|
96
|
-
name?: string;
|
|
97
|
-
server?: boolean;
|
|
98
|
-
client?: boolean | LaunchClient;
|
|
99
|
-
options?: Readonly<Record<string, string>>;
|
|
100
|
-
}> | null>;
|
|
101
|
-
enable(launch?: Launch): Promise<void>;
|
|
102
|
-
disable(): Promise<void>;
|
|
103
|
-
private change;
|
|
104
|
-
}
|
|
105
|
-
declare class ProgramProcesses extends Events<SystemProgramProcessEvents> {
|
|
106
|
-
private readonly system;
|
|
107
|
-
private readonly program;
|
|
108
|
-
constructor(system: System, program: ProgramHandle);
|
|
109
|
-
list(): Promise<ProcessHandle[]>;
|
|
110
|
-
first(): Promise<ProcessHandle | null>;
|
|
111
|
-
last(): Promise<ProcessHandle | null>;
|
|
112
|
-
find(identityOrName: string): Promise<ProcessHandle | null>;
|
|
113
|
-
create(launch?: Launch): Promise<ProcessHandle>;
|
|
114
|
-
run(launch?: Launch, options?: ProgramProcessRunOptions): AsyncGenerator<ProgramProcessRunEvent, void, void>;
|
|
115
|
-
findOrCreate(launch: Launch & {
|
|
116
|
-
name: string;
|
|
117
|
-
}): Promise<ProcessHandle>;
|
|
118
|
-
exitAll(): Promise<string[]>;
|
|
119
|
-
private createExact;
|
|
120
|
-
}
|
|
121
|
-
interface ProcessHandle extends SystemProcessEntity {
|
|
122
|
-
}
|
|
123
|
-
declare class ProcessHandle extends ProcessBase {
|
|
124
|
-
private readonly system;
|
|
125
|
-
private readonly snapshot;
|
|
126
|
-
readonly identity: string;
|
|
127
|
-
readonly name: string | null;
|
|
128
|
-
readonly startedAt: Date;
|
|
129
|
-
readonly server: ServerEndpoint;
|
|
130
|
-
readonly client: ClientEndpoint;
|
|
131
|
-
constructor(system: System, snapshot: ProcessSnapshot);
|
|
132
|
-
program(): ProgramHandle;
|
|
133
|
-
exit(): Promise<void>;
|
|
134
|
-
exited(): Promise<boolean>;
|
|
135
|
-
}
|
|
136
|
-
interface ServerEndpoint extends SystemServerEntity {
|
|
137
|
-
}
|
|
138
|
-
declare class ServerEndpoint extends ServerBase {
|
|
139
|
-
private readonly system;
|
|
140
|
-
private readonly owner;
|
|
141
|
-
readonly endpoint: "server";
|
|
142
|
-
private readonly base;
|
|
143
|
-
constructor(system: System, owner: ProcessHandle);
|
|
144
|
-
process(): Promise<ProcessHandle>;
|
|
145
|
-
exists(): Promise<boolean>;
|
|
146
|
-
start(): Promise<void>;
|
|
147
|
-
stop(): Promise<void>;
|
|
148
|
-
publish(event: string, payload?: unknown): void;
|
|
149
|
-
ask<Answer = unknown>(event: string, payload?: unknown): Promise<Answer>;
|
|
150
|
-
timeout(milliseconds: number): {
|
|
151
|
-
ask: <Answer = unknown>(event: string, payload?: unknown) => Promise<Answer>;
|
|
152
|
-
};
|
|
153
|
-
waitReady(timeout?: number): Promise<void>;
|
|
154
|
-
service<EventsMap extends object = {}>(): Promise<ServerService<EventsMap> | null>;
|
|
155
|
-
}
|
|
156
|
-
interface ClientEndpoint extends SystemClientEntity {
|
|
157
|
-
}
|
|
158
|
-
declare class ClientEndpoint extends ClientBase {
|
|
159
|
-
readonly endpoint: "client";
|
|
160
|
-
readonly window: SystemWindow;
|
|
161
|
-
private readonly base;
|
|
162
|
-
constructor(system: System, owner: ProcessHandle);
|
|
163
|
-
process(): Promise<ProcessHandle>;
|
|
164
|
-
exists(): Promise<boolean>;
|
|
165
|
-
start(overrides?: LaunchClient): Promise<void>;
|
|
166
|
-
stop(): Promise<void>;
|
|
167
|
-
publish(event: string, payload?: unknown): void;
|
|
168
|
-
service<EventsMap extends object = {}>(): Promise<ClientService<EventsMap> | null>;
|
|
169
|
-
}
|
|
170
|
-
declare class SystemWindow extends Events<WindowEvents> implements Window {
|
|
171
|
-
private readonly system;
|
|
172
|
-
private readonly process;
|
|
173
|
-
constructor(system: System, process: ProcessHandle);
|
|
174
|
-
title(): Promise<string>;
|
|
175
|
-
position(): Promise<Readonly<{
|
|
176
|
-
x: import("@phreshos/core").Value;
|
|
177
|
-
y: import("@phreshos/core").Value;
|
|
178
|
-
}>>;
|
|
179
|
-
size(): Promise<Readonly<{
|
|
180
|
-
width: import("@phreshos/core").Value;
|
|
181
|
-
height: import("@phreshos/core").Value;
|
|
182
|
-
}>>;
|
|
183
|
-
minimized(): Promise<boolean>;
|
|
184
|
-
front(): Promise<boolean>;
|
|
185
|
-
layer(): Promise<import("@phreshos/core").Layer>;
|
|
186
|
-
location(): Promise<string>;
|
|
187
|
-
move(position: Position): Promise<void>;
|
|
188
|
-
resize(size: Size): Promise<void>;
|
|
189
|
-
setGeometry(geometry: WindowGeometry): Promise<void>;
|
|
190
|
-
minimize(minimized?: boolean): Promise<void>;
|
|
191
|
-
changeTitle(title: string): Promise<void>;
|
|
192
|
-
raise(): Promise<void>;
|
|
193
|
-
private snapshot;
|
|
194
|
-
private change;
|
|
195
35
|
}
|
|
196
36
|
/** Node-SDK handle for a Service provided by a Server Endpoint. */
|
|
197
37
|
export declare class ServerService<EventsMap extends object = {}> extends CoreServerService<EventsMap> {
|
|
@@ -201,35 +41,6 @@ export declare class ServerService<EventsMap extends object = {}> extends CoreSe
|
|
|
201
41
|
export declare class ClientService<EventsMap extends object = {}> extends CoreClientService<EventsMap> {
|
|
202
42
|
protected constructor();
|
|
203
43
|
}
|
|
204
|
-
interface ProgramSnapshot {
|
|
205
|
-
reference: string;
|
|
206
|
-
identity: string;
|
|
207
|
-
name: string;
|
|
208
|
-
version: string | null;
|
|
209
|
-
description: string | null;
|
|
210
|
-
installed?: boolean;
|
|
211
|
-
hasAgent: boolean;
|
|
212
|
-
server: {
|
|
213
|
-
start: boolean;
|
|
214
|
-
} | null;
|
|
215
|
-
client: ClientDeclaration | null;
|
|
216
|
-
}
|
|
217
|
-
interface ProcessSnapshot {
|
|
218
|
-
reference: string;
|
|
219
|
-
identity: string;
|
|
220
|
-
name: string | null;
|
|
221
|
-
program: string;
|
|
222
|
-
programSnapshot?: ProgramSnapshot;
|
|
223
|
-
startedAt: string;
|
|
224
|
-
server: {
|
|
225
|
-
declared: boolean;
|
|
226
|
-
running: boolean;
|
|
227
|
-
};
|
|
228
|
-
client: {
|
|
229
|
-
declared: boolean;
|
|
230
|
-
running: boolean;
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
44
|
export type Program = SystemProgramEntity;
|
|
234
45
|
export declare const Program: typeof CoreProgram;
|
|
235
46
|
export type Process = SystemProcessEntity;
|
|
@@ -240,4 +51,3 @@ export type Server<EventsMap extends object = {}> = SystemServerEntity<EventsMap
|
|
|
240
51
|
export declare const Server: typeof CoreServer;
|
|
241
52
|
export type Client<EventsMap extends object = {}> = SystemClientEntity<EventsMap>;
|
|
242
53
|
export declare const Client: typeof CoreClient;
|
|
243
|
-
export {};
|
package/dist/system.js
CHANGED
|
@@ -7,88 +7,94 @@ import { resolveHome } from "./home.js";
|
|
|
7
7
|
import { filesystemStorage } from "./storage.js";
|
|
8
8
|
import { openConnection, request, streamProgram } from "./transport.js";
|
|
9
9
|
import Uploads from "./uploads.js";
|
|
10
|
+
const systems = new WeakMap();
|
|
10
11
|
const ProgramBase = CoreProgram;
|
|
11
12
|
const ProcessBase = CoreProcess;
|
|
12
13
|
const ServerBase = CoreServer;
|
|
13
14
|
const ClientBase = CoreClient;
|
|
14
15
|
/** One connected owner-local implementation of the shared System contract. */
|
|
15
16
|
export class System {
|
|
16
|
-
connection;
|
|
17
|
-
home;
|
|
18
|
-
address;
|
|
19
17
|
storage = filesystemStorage(homedir(), "the native home directory");
|
|
20
18
|
appearance;
|
|
21
19
|
program;
|
|
22
20
|
process;
|
|
23
21
|
uploads;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.address = address;
|
|
32
|
-
this.transport = {
|
|
33
|
-
control: (value, signal) => request(address, "system", value, this.signal(signal)),
|
|
34
|
-
api: (value, signal) => request(address, "api", value, this.signal(signal)),
|
|
35
|
-
lifecycle: (value, signal) => streamProgram(address, value, this.signal(signal))
|
|
22
|
+
constructor(address, connection) {
|
|
23
|
+
const lifetime = new AbortController();
|
|
24
|
+
const handles = new HandleRegistry();
|
|
25
|
+
const transport = {
|
|
26
|
+
control: (value, signal) => request(address, "system", value, connectedSignal(this, signal)),
|
|
27
|
+
api: (value, signal) => request(address, "api", value, connectedSignal(this, signal)),
|
|
28
|
+
lifecycle: (value, signal) => streamProgram(address, value, connectedSignal(this, signal))
|
|
36
29
|
};
|
|
37
|
-
this
|
|
30
|
+
systems.set(this, { address, connection, handles, lifetime, transport, closed: false });
|
|
31
|
+
this.appearance = new SystemAppearance(transport);
|
|
38
32
|
this.program = new ProgramRegistry(this);
|
|
39
33
|
this.process = new ProcessRegistry(this);
|
|
40
|
-
this.uploads = new Uploads(value =>
|
|
34
|
+
this.uploads = new Uploads(value => transport.api(value));
|
|
41
35
|
}
|
|
42
36
|
/** Connect to the System selected by argument, environment, or owner default. */
|
|
43
37
|
static async connect(home) {
|
|
44
38
|
const resolved = resolveHome(home);
|
|
45
39
|
const address = gatewayAddress(resolved);
|
|
46
|
-
return new System(
|
|
40
|
+
return new System(address, await openConnection(address));
|
|
47
41
|
}
|
|
48
42
|
/** Atomically replace one runtime Program without touching its installed form. */
|
|
49
43
|
async forceCreateProgram(source) {
|
|
50
|
-
|
|
51
|
-
for await (const event of this.
|
|
44
|
+
requireConnected(this);
|
|
45
|
+
for await (const event of transport(this).lifecycle({ word: "force-create", program: source })) {
|
|
52
46
|
if (event.event === "created")
|
|
53
|
-
return
|
|
47
|
+
return programHandle(this, required(event.program));
|
|
54
48
|
}
|
|
55
49
|
throw new Error("The System did not confirm the created Program");
|
|
56
50
|
}
|
|
57
51
|
/** Close this owner connection and abort every attached operation it owns. */
|
|
58
52
|
async disconnect() {
|
|
59
|
-
|
|
53
|
+
const state = systemState(this);
|
|
54
|
+
if (state.closed)
|
|
60
55
|
return;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
state.closed = true;
|
|
57
|
+
state.lifetime.abort(new Error("This System connection is closed"));
|
|
58
|
+
state.connection.destroy();
|
|
59
|
+
state.handles.clear();
|
|
65
60
|
}
|
|
66
61
|
service(key) {
|
|
67
|
-
|
|
62
|
+
requireConnected(this);
|
|
68
63
|
if (!isServiceKey(key))
|
|
69
64
|
throw new Error("A complete service key is required");
|
|
70
65
|
const normalized = Object.freeze({ program: key.program, endpoint: key.endpoint, name: key.name });
|
|
71
66
|
const identity = JSON.stringify([normalized.program, normalized.endpoint, normalized.name]);
|
|
72
|
-
return this.handles.obtain(`service:${identity}`, () => normalized.endpoint === "server"
|
|
67
|
+
return systemState(this).handles.obtain(`service:${identity}`, () => normalized.endpoint === "server"
|
|
73
68
|
? new ServerServiceHandle(this, normalized)
|
|
74
69
|
: new ClientServiceHandle(this, normalized));
|
|
75
70
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
71
|
+
}
|
|
72
|
+
function systemState(system) {
|
|
73
|
+
const state = systems.get(system);
|
|
74
|
+
if (!state)
|
|
75
|
+
throw new Error("Unknown System connection");
|
|
76
|
+
return state;
|
|
77
|
+
}
|
|
78
|
+
function requireConnected(system) {
|
|
79
|
+
if (systemState(system).closed)
|
|
80
|
+
throw new Error("This System connection is closed");
|
|
81
|
+
}
|
|
82
|
+
function connectedSignal(system, signal) {
|
|
83
|
+
const lifetime = systemState(system).lifetime.signal;
|
|
84
|
+
requireConnected(system);
|
|
85
|
+
return signal ? AbortSignal.any([signal, lifetime]) : lifetime;
|
|
86
|
+
}
|
|
87
|
+
function transport(system) {
|
|
88
|
+
requireConnected(system);
|
|
89
|
+
return systemState(system).transport;
|
|
90
|
+
}
|
|
91
|
+
function programHandle(system, snapshot) {
|
|
92
|
+
const handle = systemState(system).handles.obtain(`program:${snapshot.reference}`, () => new ProgramHandle(system, snapshot));
|
|
93
|
+
handle.update(snapshot);
|
|
94
|
+
return handle;
|
|
95
|
+
}
|
|
96
|
+
function processHandle(system, snapshot) {
|
|
97
|
+
return systemState(system).handles.obtain(`process:${snapshot.reference}`, () => new ProcessHandle(system, snapshot));
|
|
92
98
|
}
|
|
93
99
|
class SystemAppearance extends Events {
|
|
94
100
|
transport;
|
|
@@ -106,7 +112,7 @@ class SystemAppearance extends Events {
|
|
|
106
112
|
class ProgramRegistry extends Events {
|
|
107
113
|
system;
|
|
108
114
|
constructor(system) {
|
|
109
|
-
super(["create", "forget", "install", "uninstall"], (event, signal, timeout) => (system.
|
|
115
|
+
super(["create", "forget", "install", "uninstall"], (event, signal, timeout) => (transport(system).control({ capability: "program", operation: "wait", input: { event, timeout } }, signal)
|
|
110
116
|
.then(value => this.event(value))));
|
|
111
117
|
this.system = system;
|
|
112
118
|
}
|
|
@@ -114,12 +120,12 @@ class ProgramRegistry extends Events {
|
|
|
114
120
|
const programs = [];
|
|
115
121
|
let offset = 0;
|
|
116
122
|
while (true) {
|
|
117
|
-
const page = await this.system.
|
|
123
|
+
const page = await transport(this.system).control({
|
|
118
124
|
capability: "program",
|
|
119
125
|
operation: "list",
|
|
120
126
|
input: { installedOnly: onlyInstalled, limit: 100, offset }
|
|
121
127
|
});
|
|
122
|
-
programs.push(...page.data.map(snapshot => this.system
|
|
128
|
+
programs.push(...page.data.map(snapshot => programHandle(this.system, snapshot)));
|
|
123
129
|
offset += page.data.length;
|
|
124
130
|
if (!page.truncated || !page.data.length)
|
|
125
131
|
return programs;
|
|
@@ -127,8 +133,8 @@ class ProgramRegistry extends Events {
|
|
|
127
133
|
}
|
|
128
134
|
async find(identity) {
|
|
129
135
|
try {
|
|
130
|
-
const snapshot = await this.system.
|
|
131
|
-
return this.system
|
|
136
|
+
const snapshot = await transport(this.system).control({ capability: "program", operation: "inspect", input: { program: identity } });
|
|
137
|
+
return programHandle(this.system, snapshot);
|
|
132
138
|
}
|
|
133
139
|
catch (error) {
|
|
134
140
|
if (unknown(error, "Program"))
|
|
@@ -137,9 +143,9 @@ class ProgramRegistry extends Events {
|
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
145
|
async create(source) {
|
|
140
|
-
for await (const event of this.system.
|
|
146
|
+
for await (const event of transport(this.system).lifecycle({ word: "create", program: source })) {
|
|
141
147
|
if (event.event === "created")
|
|
142
|
-
return this.system
|
|
148
|
+
return programHandle(this.system, required(event.program));
|
|
143
149
|
}
|
|
144
150
|
throw new Error("The System did not confirm the created Program");
|
|
145
151
|
}
|
|
@@ -147,9 +153,9 @@ class ProgramRegistry extends Events {
|
|
|
147
153
|
const waited = value;
|
|
148
154
|
if (waited.event === "uninstall") {
|
|
149
155
|
const payload = waited.payload;
|
|
150
|
-
return { program: this.system
|
|
156
|
+
return { program: programHandle(this.system, required(payload.program)), everythingRemoved: payload.everythingRemoved === true };
|
|
151
157
|
}
|
|
152
|
-
return this.system
|
|
158
|
+
return programHandle(this.system, required(waited.payload));
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
class ProgramHandle extends ProgramBase {
|
|
@@ -163,7 +169,7 @@ class ProgramHandle extends ProgramBase {
|
|
|
163
169
|
super();
|
|
164
170
|
this.system = system;
|
|
165
171
|
this.snapshot = snapshot;
|
|
166
|
-
bindEvents(this, new Events(["forget", "uninstall"], (event, signal, timeout) => system.
|
|
172
|
+
bindEvents(this, new Events(["forget", "uninstall"], (event, signal, timeout) => transport(system).control({
|
|
167
173
|
capability: "program", operation: "wait", input: { program: snapshot.identity, event, timeout }
|
|
168
174
|
}, signal).then(value => value.payload)));
|
|
169
175
|
this.reference = snapshot.reference;
|
|
@@ -196,11 +202,11 @@ class ProgramHandle extends ProgramBase {
|
|
|
196
202
|
async agent() {
|
|
197
203
|
if (!this.hasAgent)
|
|
198
204
|
return null;
|
|
199
|
-
const value = await this.system.
|
|
205
|
+
const value = await transport(this.system).control({ capability: "program", operation: "agent", input: { program: this.identity } });
|
|
200
206
|
return typeof value.content === "string" ? value.content : null;
|
|
201
207
|
}
|
|
202
208
|
async installed() {
|
|
203
|
-
for await (const event of this.system.
|
|
209
|
+
for await (const event of transport(this.system).lifecycle({ word: "installed", handle: this.address() })) {
|
|
204
210
|
if (event.event === "installedState")
|
|
205
211
|
return event.installed === true;
|
|
206
212
|
}
|
|
@@ -209,7 +215,7 @@ class ProgramHandle extends ProgramBase {
|
|
|
209
215
|
install() { return command(this.system, { word: "install-existing", handle: this.address() }); }
|
|
210
216
|
uninstall(everything = false) { return command(this.system, { word: "uninstall-existing", handle: this.address(), everything }); }
|
|
211
217
|
async forget() {
|
|
212
|
-
for await (const _event of this.system.
|
|
218
|
+
for await (const _event of transport(this.system).lifecycle({ word: "forget", handle: this.address() })) { /* consume completion */ }
|
|
213
219
|
}
|
|
214
220
|
address() { return Object.freeze({ identity: this.identity, reference: this.reference }); }
|
|
215
221
|
}
|
|
@@ -221,7 +227,7 @@ class ProgramStartup {
|
|
|
221
227
|
this.program = program;
|
|
222
228
|
}
|
|
223
229
|
async get() {
|
|
224
|
-
for await (const event of this.system.
|
|
230
|
+
for await (const event of transport(this.system).lifecycle({
|
|
225
231
|
word: "startup", handle: this.program.address(), operation: "get"
|
|
226
232
|
})) {
|
|
227
233
|
if (event.event === "startup")
|
|
@@ -236,7 +242,7 @@ class ProgramStartup {
|
|
|
236
242
|
await this.change("disable");
|
|
237
243
|
}
|
|
238
244
|
async change(operation, launch) {
|
|
239
|
-
for await (const event of this.system.
|
|
245
|
+
for await (const event of transport(this.system).lifecycle({
|
|
240
246
|
word: "startup", handle: this.program.address(), operation, launch
|
|
241
247
|
})) {
|
|
242
248
|
if (event.event === "startup")
|
|
@@ -249,7 +255,7 @@ class ProgramProcesses extends Events {
|
|
|
249
255
|
system;
|
|
250
256
|
program;
|
|
251
257
|
constructor(system, program) {
|
|
252
|
-
super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => system.
|
|
258
|
+
super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => transport(system).control({
|
|
253
259
|
capability: "process", operation: "wait", input: { program: program.identity, event, timeout }
|
|
254
260
|
}, signal).then(value => processEvent(system, value)));
|
|
255
261
|
this.system = system;
|
|
@@ -265,13 +271,13 @@ class ProgramProcesses extends Events {
|
|
|
265
271
|
create(launch = {}) { return this.createExact("create-process", launch); }
|
|
266
272
|
async *run(launch = {}, options = {}) {
|
|
267
273
|
let process = null;
|
|
268
|
-
for await (const event of this.system.
|
|
274
|
+
for await (const event of transport(this.system).lifecycle({
|
|
269
275
|
word: "run-process",
|
|
270
276
|
handle: this.program.address(),
|
|
271
277
|
launch
|
|
272
278
|
}, options.signal)) {
|
|
273
279
|
if (event.event === "started") {
|
|
274
|
-
process = this.system
|
|
280
|
+
process = processHandle(this.system, required(event.process));
|
|
275
281
|
yield Object.freeze({ event: "started", process });
|
|
276
282
|
}
|
|
277
283
|
else if (event.event === "output") {
|
|
@@ -312,9 +318,9 @@ class ProgramProcesses extends Events {
|
|
|
312
318
|
return processes.map(process => process.identity);
|
|
313
319
|
}
|
|
314
320
|
async createExact(word, launch) {
|
|
315
|
-
for await (const event of this.system.
|
|
321
|
+
for await (const event of transport(this.system).lifecycle({ word, handle: this.program.address(), launch })) {
|
|
316
322
|
if (event.event === "createdProcess")
|
|
317
|
-
return this.system
|
|
323
|
+
return processHandle(this.system, required(event.process));
|
|
318
324
|
}
|
|
319
325
|
throw new Error("The System did not confirm the created Process");
|
|
320
326
|
}
|
|
@@ -322,7 +328,7 @@ class ProgramProcesses extends Events {
|
|
|
322
328
|
class ProcessRegistry extends Events {
|
|
323
329
|
system;
|
|
324
330
|
constructor(system) {
|
|
325
|
-
super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => system.
|
|
331
|
+
super(["endpointStart", "endpointStop", "create", "exit"], (event, signal, timeout) => transport(system).control({
|
|
326
332
|
capability: "process", operation: "wait", input: { event, timeout }
|
|
327
333
|
}, signal).then(value => processEvent(system, value)));
|
|
328
334
|
this.system = system;
|
|
@@ -330,8 +336,8 @@ class ProcessRegistry extends Events {
|
|
|
330
336
|
list() { return listProcesses(this.system); }
|
|
331
337
|
async find(identity) {
|
|
332
338
|
try {
|
|
333
|
-
const snapshot = await this.system.
|
|
334
|
-
return this.system
|
|
339
|
+
const snapshot = await transport(this.system).control({ capability: "process", operation: "inspect", input: { process: identity } });
|
|
340
|
+
return processHandle(this.system, snapshot);
|
|
335
341
|
}
|
|
336
342
|
catch (error) {
|
|
337
343
|
if (unknown(error, "Process"))
|
|
@@ -352,7 +358,7 @@ class ProcessHandle extends ProcessBase {
|
|
|
352
358
|
super();
|
|
353
359
|
this.system = system;
|
|
354
360
|
this.snapshot = snapshot;
|
|
355
|
-
bindEvents(this, new Events(["endpointStart", "endpointStop", "exit"], (event, signal, timeout) => system.
|
|
361
|
+
bindEvents(this, new Events(["endpointStart", "endpointStop", "exit"], (event, signal, timeout) => transport(system).control({
|
|
356
362
|
capability: "process", operation: "wait", input: { process: snapshot.identity, event, timeout }
|
|
357
363
|
}, signal).then(value => processEvent(system, value))));
|
|
358
364
|
this.identity = snapshot.identity;
|
|
@@ -361,9 +367,9 @@ class ProcessHandle extends ProcessBase {
|
|
|
361
367
|
this.server = new ServerEndpoint(system, this);
|
|
362
368
|
this.client = new ClientEndpoint(system, this);
|
|
363
369
|
}
|
|
364
|
-
program() { return this.system
|
|
370
|
+
program() { return programHandle(this.system, required(this.snapshot.programSnapshot, this.snapshot.program)); }
|
|
365
371
|
async exit() {
|
|
366
|
-
await this.system.
|
|
372
|
+
await transport(this.system).control({ capability: "process", operation: "exit", input: { process: this.identity } });
|
|
367
373
|
}
|
|
368
374
|
async exited() { return await this.system.process.find(this.identity) === null; }
|
|
369
375
|
}
|
|
@@ -373,8 +379,8 @@ class EndpointOperations extends Events {
|
|
|
373
379
|
endpoint;
|
|
374
380
|
constructor(system, owner, endpoint) {
|
|
375
381
|
super([], (event, signal, timeout) => event === null
|
|
376
|
-
? system.
|
|
377
|
-
: system.
|
|
382
|
+
? transport(system).api({ capability: "endpoint", operation: "wait", process: owner.identity, endpoint, event, timeout }, signal)
|
|
383
|
+
: transport(system).control({
|
|
378
384
|
capability: "endpoint", operation: "wait", input: { process: owner.identity, endpoint, event, timeout }
|
|
379
385
|
}, signal).then(value => value.payload));
|
|
380
386
|
this.system = system;
|
|
@@ -389,21 +395,21 @@ class EndpointOperations extends Events {
|
|
|
389
395
|
async start(client) { await this.operation("start", client); }
|
|
390
396
|
async stop() { await this.operation("stop"); }
|
|
391
397
|
async service() {
|
|
392
|
-
const key = await this.system.
|
|
398
|
+
const key = await transport(this.system).api({ capability: "endpoint", operation: "service", process: this.owner.identity, endpoint: this.endpoint });
|
|
393
399
|
return key ? this.system.service(key) : null;
|
|
394
400
|
}
|
|
395
401
|
publish(event, payload) {
|
|
396
|
-
void this.system.
|
|
402
|
+
void transport(this.system).control({ capability: "endpoint", operation: "publish", input: {
|
|
397
403
|
process: this.owner.identity, endpoint: this.endpoint, event, payload
|
|
398
404
|
} });
|
|
399
405
|
}
|
|
400
406
|
inspect() {
|
|
401
|
-
return this.system.
|
|
407
|
+
return transport(this.system).control({ capability: "endpoint", operation: "inspect", input: {
|
|
402
408
|
process: this.owner.identity, endpoint: this.endpoint
|
|
403
409
|
} });
|
|
404
410
|
}
|
|
405
411
|
async operation(operation, client) {
|
|
406
|
-
await this.system.
|
|
412
|
+
await transport(this.system).control({ capability: "endpoint", operation, input: {
|
|
407
413
|
process: this.owner.identity, endpoint: this.endpoint, ...(client ? { client } : {})
|
|
408
414
|
} });
|
|
409
415
|
}
|
|
@@ -426,17 +432,17 @@ class ServerEndpoint extends ServerBase {
|
|
|
426
432
|
stop() { return this.base.stop(); }
|
|
427
433
|
publish(event, payload) { return this.base.publish(event, payload); }
|
|
428
434
|
async ask(event, payload) {
|
|
429
|
-
return await this.system.
|
|
435
|
+
return await transport(this.system).control({ capability: "endpoint", operation: "ask", input: {
|
|
430
436
|
process: this.owner.identity, endpoint: "server", event, payload
|
|
431
437
|
} });
|
|
432
438
|
}
|
|
433
439
|
timeout(milliseconds) {
|
|
434
|
-
return { ask: (event, payload) => this.system.
|
|
440
|
+
return { ask: (event, payload) => transport(this.system).control({
|
|
435
441
|
capability: "endpoint", operation: "ask", input: { process: this.owner.identity, endpoint: "server", event, payload, timeout: milliseconds }
|
|
436
442
|
}) };
|
|
437
443
|
}
|
|
438
444
|
async waitReady(timeout) {
|
|
439
|
-
await this.system.
|
|
445
|
+
await transport(this.system).control({ capability: "endpoint", operation: "waitReady", input: { process: this.owner.identity, endpoint: "server", timeout } });
|
|
440
446
|
}
|
|
441
447
|
async service() {
|
|
442
448
|
return await this.base.service();
|
|
@@ -465,7 +471,7 @@ class SystemWindow extends Events {
|
|
|
465
471
|
system;
|
|
466
472
|
process;
|
|
467
473
|
constructor(system, process) {
|
|
468
|
-
super(["move", "resize", "geometry", "minimize", "changeTitle", "front"], (event, signal, timeout) => system.
|
|
474
|
+
super(["move", "resize", "geometry", "minimize", "changeTitle", "front"], (event, signal, timeout) => transport(system).control({
|
|
469
475
|
capability: "window", operation: "wait", input: { process: process.identity, event, timeout }
|
|
470
476
|
}, signal).then(value => value.payload));
|
|
471
477
|
this.system = system;
|
|
@@ -485,10 +491,10 @@ class SystemWindow extends Events {
|
|
|
485
491
|
async changeTitle(title) { await this.change("changeTitle", { title }); }
|
|
486
492
|
async raise() { await this.change("raise", {}); }
|
|
487
493
|
snapshot() {
|
|
488
|
-
return this.system.
|
|
494
|
+
return transport(this.system).control({ capability: "window", operation: "inspect", input: { process: this.process.identity } });
|
|
489
495
|
}
|
|
490
496
|
async change(operation, input) {
|
|
491
|
-
await this.system.
|
|
497
|
+
await transport(this.system).control({ capability: "window", operation, input: { process: this.process.identity, ...input } });
|
|
492
498
|
}
|
|
493
499
|
}
|
|
494
500
|
class ServiceBase extends Events {
|
|
@@ -496,15 +502,15 @@ class ServiceBase extends Events {
|
|
|
496
502
|
key;
|
|
497
503
|
name;
|
|
498
504
|
constructor(system, key) {
|
|
499
|
-
super(["enable", "disable"], (event, signal, timeout) => system.
|
|
505
|
+
super(["enable", "disable"], (event, signal, timeout) => transport(system).api({
|
|
500
506
|
capability: "service", operation: "wait", scope: "lifecycle", key, event, timeout
|
|
501
507
|
}, signal));
|
|
502
508
|
this.system = system;
|
|
503
509
|
this.key = key;
|
|
504
510
|
this.name = key.name;
|
|
505
511
|
}
|
|
506
|
-
async enabled() { return await this.system.
|
|
507
|
-
async waitReady(timeout) { await this.system.
|
|
512
|
+
async enabled() { return await transport(this.system).api({ capability: "service", operation: "enabled", key: this.key }); }
|
|
513
|
+
async waitReady(timeout) { await transport(this.system).api({ capability: "service", operation: "waitReady", key: this.key, timeout }); }
|
|
508
514
|
}
|
|
509
515
|
/** Node-SDK handle for a Service provided by a Server Endpoint. */
|
|
510
516
|
export class ServerService extends CoreServerService {
|
|
@@ -546,37 +552,37 @@ class ClientServiceChannelHandle extends Events {
|
|
|
546
552
|
system;
|
|
547
553
|
key;
|
|
548
554
|
constructor(system, key) {
|
|
549
|
-
super([], (event, signal, timeout) => system.
|
|
555
|
+
super([], (event, signal, timeout) => transport(system).api({ capability: "service", operation: "wait", scope: "channel", key, event, timeout }, signal));
|
|
550
556
|
this.system = system;
|
|
551
557
|
this.key = key;
|
|
552
558
|
}
|
|
553
559
|
}
|
|
554
560
|
class ServerServiceChannelHandle extends ClientServiceChannelHandle {
|
|
555
561
|
async ask(event, payload) {
|
|
556
|
-
return await this.system.
|
|
562
|
+
return await transport(this.system).api({ capability: "service", operation: "ask", key: this.key, event, payload });
|
|
557
563
|
}
|
|
558
564
|
timeout(milliseconds) {
|
|
559
|
-
return { ask: (event, payload) => this.system.
|
|
565
|
+
return { ask: (event, payload) => transport(this.system).api({
|
|
560
566
|
capability: "service", operation: "ask", key: this.key, event, payload, timeout: milliseconds
|
|
561
567
|
}) };
|
|
562
568
|
}
|
|
563
569
|
publish(event, payload) {
|
|
564
|
-
void this.system.
|
|
570
|
+
void transport(this.system).api({ capability: "service", operation: "publish", key: this.key, event, payload });
|
|
565
571
|
}
|
|
566
572
|
}
|
|
567
573
|
async function listProcesses(system, program) {
|
|
568
574
|
const processes = [];
|
|
569
575
|
let offset = 0;
|
|
570
576
|
while (true) {
|
|
571
|
-
const page = await system.
|
|
572
|
-
processes.push(...page.data.map(snapshot =>
|
|
577
|
+
const page = await transport(system).control({ capability: "process", operation: "list", input: { program, limit: 100, offset } });
|
|
578
|
+
processes.push(...page.data.map(snapshot => processHandle(system, snapshot)));
|
|
573
579
|
offset += page.data.length;
|
|
574
580
|
if (!page.truncated || !page.data.length)
|
|
575
581
|
return processes;
|
|
576
582
|
}
|
|
577
583
|
}
|
|
578
584
|
async function* command(system, request) {
|
|
579
|
-
for await (const event of system.
|
|
585
|
+
for await (const event of transport(system).lifecycle(request)) {
|
|
580
586
|
if (event.event === "output")
|
|
581
587
|
yield {
|
|
582
588
|
stream: event.stream === "stderr" ? "stderr" : "stdout",
|
|
@@ -589,17 +595,17 @@ function processEvent(system, value) {
|
|
|
589
595
|
const payload = waited.payload;
|
|
590
596
|
if (waited.event === "exit" && payload)
|
|
591
597
|
return {
|
|
592
|
-
process:
|
|
598
|
+
process: processHandle(system, required(payload.processSnapshot, String(payload.process ?? ""))),
|
|
593
599
|
status: payload.status,
|
|
594
600
|
code: payload.code,
|
|
595
601
|
signal: payload.signal
|
|
596
602
|
};
|
|
597
603
|
if ((waited.event === "endpointStart" || waited.event === "endpointStop") && payload?.processSnapshot) {
|
|
598
|
-
const process =
|
|
604
|
+
const process = processHandle(system, payload.processSnapshot);
|
|
599
605
|
return payload.endpoint === "client" ? process.client : process.server;
|
|
600
606
|
}
|
|
601
607
|
if (payload && typeof payload.identity === "string")
|
|
602
|
-
return
|
|
608
|
+
return processHandle(system, payload);
|
|
603
609
|
return payload;
|
|
604
610
|
}
|
|
605
611
|
function bindEvents(target, events) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/node",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Node.js access to PhreshOS and Program projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"prepack": "node --run build"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@phreshos/core": "^0.1.
|
|
35
|
+
"@phreshos/core": "^0.1.25",
|
|
36
36
|
"adm-zip": "^0.6.0",
|
|
37
37
|
"jiti": "^2.7.0"
|
|
38
38
|
},
|