@phreshos/server 0.1.21 → 0.1.23
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 +9 -1
- package/dist/domain.d.ts +15 -0
- package/dist/domain.js +20 -0
- package/dist/main.d.ts +3 -3
- package/dist/system.d.ts +1 -131
- package/dist/system.js +5 -1
- package/dist/wire.d.ts +1 -1
- package/dist/wire.js +11 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -136,6 +136,9 @@ A Program owns its scoped Process capability:
|
|
|
136
136
|
const processes = await program.process.list()
|
|
137
137
|
const process = await program.process.find("worker")
|
|
138
138
|
const created = await program.process.create({ name: "worker" })
|
|
139
|
+
for await (const event of program.process.run({ name: "temporary" }, { signal })) {
|
|
140
|
+
// started, output, exited
|
|
141
|
+
}
|
|
139
142
|
const shared = await program.process.findOrCreate({
|
|
140
143
|
name: "shared-server",
|
|
141
144
|
server: true,
|
|
@@ -143,6 +146,11 @@ const shared = await program.process.findOrCreate({
|
|
|
143
146
|
})
|
|
144
147
|
```
|
|
145
148
|
|
|
149
|
+
`run()` creates exactly one Process and yields its ordered `started`, `output`,
|
|
150
|
+
and `exited` lifecycle. Aborting its signal, returning early, or losing the
|
|
151
|
+
calling Server exits that Process; `create()` remains independent of the
|
|
152
|
+
caller.
|
|
153
|
+
|
|
146
154
|
`findOrCreate()` is atomic at the authoritative Core. Concurrent equivalent
|
|
147
155
|
launches converge on one named Process; a different launch for that name
|
|
148
156
|
rejects instead of reconfiguring the existing Process.
|
|
@@ -172,7 +180,7 @@ if (program.hasAgent) console.log(await program.agent())
|
|
|
172
180
|
asset-hosting address. Omitting the size selects `medium`.
|
|
173
181
|
|
|
174
182
|
Installed Programs may persist one ordinary Process launch for the next system
|
|
175
|
-
startup
|
|
183
|
+
startup through the shared Program interface:
|
|
176
184
|
|
|
177
185
|
```ts
|
|
178
186
|
await program.startup.enable({
|
package/dist/domain.d.ts
CHANGED
|
@@ -74,11 +74,26 @@ export interface ProgramProcess extends Omit<CoreProgramProcess, "list" | "first
|
|
|
74
74
|
find(identityOrName: string): Promise<Process | null>;
|
|
75
75
|
/** Creates one Process of this Program. */
|
|
76
76
|
create(launch?: Launch): Promise<Process>;
|
|
77
|
+
/** Runs one Process for exactly as long as its lifecycle iterator remains open. */
|
|
78
|
+
run(launch?: Launch, options?: ProgramProcessRunOptions): AsyncGenerator<ProgramProcessRunEvent, void, void>;
|
|
77
79
|
/** Finds the named Process or atomically creates it with the same resolved launch. */
|
|
78
80
|
findOrCreate(launch: Launch & Readonly<{
|
|
79
81
|
name: string;
|
|
80
82
|
}>): Promise<Process>;
|
|
81
83
|
}
|
|
84
|
+
export type ProgramProcessRunEvent = Readonly<{
|
|
85
|
+
event: "started";
|
|
86
|
+
process: Process;
|
|
87
|
+
}> | (Readonly<{
|
|
88
|
+
event: "output";
|
|
89
|
+
}> & ProgramCommandChunk) | Readonly<{
|
|
90
|
+
event: "exited";
|
|
91
|
+
process: Process;
|
|
92
|
+
exit: Exit;
|
|
93
|
+
}>;
|
|
94
|
+
export type ProgramProcessRunOptions = Readonly<{
|
|
95
|
+
signal?: AbortSignal;
|
|
96
|
+
}>;
|
|
82
97
|
/** Server-visible Process handle. */
|
|
83
98
|
export interface Process<Events extends object = {}> extends CoreProcess<Events> {
|
|
84
99
|
/** Permanent handle to this Process's Server. */
|
package/dist/domain.js
CHANGED
|
@@ -134,6 +134,11 @@ class ProgramProcessHandle {
|
|
|
134
134
|
const answer = await wire.request(["program-process-create", this.address, launch]);
|
|
135
135
|
return process(answer[0]);
|
|
136
136
|
}
|
|
137
|
+
async *run(launch = {}, options = {}) {
|
|
138
|
+
for await (const value of wire.stream(["run", this.address, launch], undefined, options.signal)) {
|
|
139
|
+
yield processRunEvent(value);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
137
142
|
async findOrCreate(launch) {
|
|
138
143
|
const answer = await wire.request(["program-process-find-or-create", this.address, launch]);
|
|
139
144
|
return process(answer[0]);
|
|
@@ -143,6 +148,21 @@ class ProgramProcessHandle {
|
|
|
143
148
|
return answer[0];
|
|
144
149
|
}
|
|
145
150
|
}
|
|
151
|
+
function processRunEvent(value) {
|
|
152
|
+
const event = value;
|
|
153
|
+
if (event?.event === "started" && event.process) {
|
|
154
|
+
return Object.freeze({ event: "started", process: process(event.process) });
|
|
155
|
+
}
|
|
156
|
+
if (event?.event === "output" && (event.stream === "stdout" || event.stream === "stderr") && typeof event.text === "string") {
|
|
157
|
+
return Object.freeze({ event: "output", stream: event.stream, text: event.text });
|
|
158
|
+
}
|
|
159
|
+
if (event?.event === "exited" && event.process) {
|
|
160
|
+
const code = typeof event.exit?.code === "number" ? event.exit.code : null;
|
|
161
|
+
const signal = typeof event.exit?.signal === "string" ? event.exit.signal : null;
|
|
162
|
+
return Object.freeze({ event: "exited", process: process(event.process), exit: exit(code, signal) });
|
|
163
|
+
}
|
|
164
|
+
throw new Error("The System returned an invalid Process run event");
|
|
165
|
+
}
|
|
146
166
|
/** Internal transport address for a Program handle created by this SDK. */
|
|
147
167
|
export function programAddress(value) {
|
|
148
168
|
if (!(value instanceof ProgramHandle))
|
package/dist/main.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { system
|
|
1
|
+
export { system } from "./system.js";
|
|
2
2
|
export { current, type Current, type CurrentClient } from "./current.js";
|
|
3
3
|
export { type Answerer, type Channel, type ChannelCapture, type ChannelEvents, type ChannelMessage } from "./channel.js";
|
|
4
4
|
export { type ProgramStartup } from "./startup.js";
|
|
5
5
|
export { type Storage } from "./storage.js";
|
|
6
6
|
export { ClientServiceHandler, ServerServiceHandler } from "./service.js";
|
|
7
7
|
export { ServiceHandler, type ClientServiceChannel, type ServerServiceChannel, type ServiceChannel, type ServiceKey, type ServiceLifecycleEvents } from "@phreshos/core";
|
|
8
|
-
export { Client, Endpoint, Process, Program, Server, type Window, type ProgramProcess } from "./domain.js";
|
|
9
|
-
export type { AnswerCapture, AnswerMessage, AnswerObserver, Askable, AskCapture, AskMessage, AskObserver, Capture, Captures, ClientTraffic, ClientDeclaration, Cleanup, DirectoryStat, EndpointDeclaration, EndpointTraffic, EntryStat, EventMessage, EventName, EventObserver, EventOptions, EventSubscriber, Exit, FileStat, Launch, LaunchClient, Layer, LogKind, LogRecord, LogSource, Message, OtherStat, Outcome, Position, ProgramEvents, ProgramPermission, ProgramProcessEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, SystemUploads, Upload, ServerTraffic, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TrafficCapture, TrafficEvents, TrafficMessage, Value, Appearance, AppearanceEvents, AppearanceSource, AppearanceSurface, ThemedValue, WritableAppearance, WindowEvents, WindowGeometry, WindowLayer, WindowState } from "@phreshos/core";
|
|
8
|
+
export { Client, Endpoint, Process, Program, Server, type Window, type ProgramProcess, type ProgramProcessRunEvent, type ProgramProcessRunOptions } from "./domain.js";
|
|
9
|
+
export type { AnswerCapture, AnswerMessage, AnswerObserver, Askable, AskCapture, AskMessage, AskObserver, Capture, Captures, ClientTraffic, ClientDeclaration, Cleanup, DirectoryStat, EndpointDeclaration, EndpointTraffic, EntryStat, EventMessage, EventName, EventObserver, EventOptions, EventSubscriber, Exit, FileStat, Launch, LaunchClient, Layer, LogKind, LogRecord, LogSource, Message, OtherStat, Outcome, Position, ProgramEvents, ProgramPermission, ProgramProcessEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, SystemUploads, Upload, ServerTraffic, System, SystemProcess, SystemProcessEntity, SystemProcessEntityEvents, SystemProgram, SystemProgramEntity, SystemProgramProcess, SystemProgramProcessEvents, SystemEndpointEntity, SystemServerEntity, SystemClientEntity, ClientDescription, SystemProcessEvents, SystemProcessExit, SystemProgramEvents, SystemProgramUninstall, ProgramDescription, ServerDescription, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TrafficCapture, TrafficEvents, TrafficMessage, Value, Appearance, AppearanceEvents, AppearanceSource, AppearanceSurface, ThemedValue, WritableAppearance, WindowEvents, WindowGeometry, WindowLayer, WindowState } from "@phreshos/core";
|
package/dist/system.d.ts
CHANGED
|
@@ -1,133 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ClientServiceHandler, ServerServiceHandler } from "./service.js";
|
|
3
|
-
import { type Client, type Process, type Program, type Server } from "./domain.js";
|
|
4
|
-
import { type Storage } from "./storage.js";
|
|
5
|
-
/** Resolved production description for a Program's Server. */
|
|
6
|
-
type ServerDescriptionBase = Readonly<{
|
|
7
|
-
/** Absolute directory containing the production Server files. */
|
|
8
|
-
location: string;
|
|
9
|
-
/** Whether newly created Processes start this Server by default. */
|
|
10
|
-
start?: boolean;
|
|
11
|
-
/** Command used to install the Server's production dependencies. */
|
|
12
|
-
installCommand?: string;
|
|
13
|
-
}>;
|
|
14
|
-
export type ServerDescription = ServerDescriptionBase & (Readonly<{
|
|
15
|
-
/** Command used to start an isolated Server process. */
|
|
16
|
-
startCommand: string;
|
|
17
|
-
entryFile?: never;
|
|
18
|
-
}> | Readonly<{
|
|
19
|
-
startCommand?: never;
|
|
20
|
-
/** JavaScript module loaded as a worker owned by the System. */
|
|
21
|
-
entryFile: string;
|
|
22
|
-
}>);
|
|
23
|
-
/** Resolved production description for a Program's Client and initial Window. */
|
|
24
|
-
export type ClientDescription = Readonly<{
|
|
25
|
-
/** Absolute directory containing the production Client files. */
|
|
26
|
-
location: string;
|
|
27
|
-
/** Whether newly created Processes start this Client by default. */
|
|
28
|
-
start?: boolean;
|
|
29
|
-
/** Default Window title. */
|
|
30
|
-
title?: string;
|
|
31
|
-
/** Default Window size. */
|
|
32
|
-
size?: Size;
|
|
33
|
-
/** Default Window position. */
|
|
34
|
-
position?: Position;
|
|
35
|
-
/** Default Window layer. */
|
|
36
|
-
layer?: Layer;
|
|
37
|
-
/** Whether the Window starts minimized. */
|
|
38
|
-
minimize?: boolean;
|
|
39
|
-
}>;
|
|
40
|
-
type Description = Readonly<{
|
|
41
|
-
/** Stable identity assigned to the Program. */
|
|
42
|
-
identity: string;
|
|
43
|
-
/** Human-readable Program name. */
|
|
44
|
-
name?: string;
|
|
45
|
-
/** Declared Program version. */
|
|
46
|
-
version?: string;
|
|
47
|
-
/** Short human-readable Program description. */
|
|
48
|
-
description?: string;
|
|
49
|
-
/** Absolute validated PNG source used to derive the Program's hosted icon sizes. */
|
|
50
|
-
icon?: string;
|
|
51
|
-
/** Absolute Markdown file describing Program-specific operation to agents. */
|
|
52
|
-
agent?: string;
|
|
53
|
-
/** Absolute directory used for the Program's persistent storage. */
|
|
54
|
-
storage: string;
|
|
55
|
-
}>;
|
|
56
|
-
/** Complete runtime description used to create a Program. */
|
|
57
|
-
export type ProgramDescription = Description & (Readonly<{
|
|
58
|
-
/** Required Server description when no Client is described. */
|
|
59
|
-
server: ServerDescription;
|
|
60
|
-
/** Optional Client description. */
|
|
61
|
-
client?: ClientDescription;
|
|
62
|
-
}> | Readonly<{
|
|
63
|
-
/** Optional Server description. */
|
|
64
|
-
server?: ServerDescription;
|
|
65
|
-
/** Required Client description when no Server is described. */
|
|
66
|
-
client: ClientDescription;
|
|
67
|
-
}>);
|
|
68
|
-
/** An uninstall reported with the affected Program and removal scope. */
|
|
69
|
-
export type SystemProgramUninstall = Readonly<{
|
|
70
|
-
/** Program that left the installed state. */
|
|
71
|
-
program: Program;
|
|
72
|
-
/** Whether all installed resources, including storage, were removed. */
|
|
73
|
-
everythingRemoved: boolean;
|
|
74
|
-
}>;
|
|
75
|
-
/** A Process exit reported with the Process that ended. */
|
|
76
|
-
export type SystemProcessExit = Exit & Readonly<{
|
|
77
|
-
/** Process that ended. */
|
|
78
|
-
process: Process;
|
|
79
|
-
}>;
|
|
80
|
-
/** Authoritative lifecycle events visible to the Server system. */
|
|
81
|
-
export type SystemProgramEvents = {
|
|
82
|
-
/** A Program entered the runtime registry. */
|
|
83
|
-
create: Program;
|
|
84
|
-
/** A Program left the runtime registry. */
|
|
85
|
-
forget: Program;
|
|
86
|
-
/** A Program entered the installed state. */
|
|
87
|
-
install: Program;
|
|
88
|
-
/** A Program left the installed state. */
|
|
89
|
-
uninstall: SystemProgramUninstall;
|
|
90
|
-
};
|
|
91
|
-
/** Authoritative Process lifecycle events visible to the Server system. */
|
|
92
|
-
export type SystemProcessEvents = {
|
|
93
|
-
/** One Process Endpoint entered a new live incarnation. */
|
|
94
|
-
endpointStart: Server | Client;
|
|
95
|
-
/** One Process Endpoint incarnation ended. */
|
|
96
|
-
endpointStop: Server | Client;
|
|
97
|
-
/** A Process entered the runtime set. */
|
|
98
|
-
create: Process;
|
|
99
|
-
/** A Process left the runtime set. */
|
|
100
|
-
exit: SystemProcessExit;
|
|
101
|
-
};
|
|
102
|
-
/** Authoritative Program registry available to a Server endpoint. */
|
|
103
|
-
export interface SystemProgram extends Subscribable<SystemProgramEvents, never> {
|
|
104
|
-
list(onlyInstalled?: boolean): Promise<Program[]>;
|
|
105
|
-
find(identity: string): Promise<Program | null>;
|
|
106
|
-
create(source: ProgramDescription | string): Promise<Program>;
|
|
107
|
-
}
|
|
108
|
-
/** Authoritative Process registry available to a Server endpoint. */
|
|
109
|
-
export interface SystemProcess extends Subscribable<SystemProcessEvents, never> {
|
|
110
|
-
list(): Promise<Process[]>;
|
|
111
|
-
find(identity: string): Promise<Process | null>;
|
|
112
|
-
}
|
|
113
|
-
/** Authoritative system capabilities available to a Server endpoint. */
|
|
114
|
-
export interface System {
|
|
115
|
-
/** Native operating-system home storage available to Server endpoints. */
|
|
116
|
-
readonly storage: Storage;
|
|
117
|
-
/** Complete unresolved Appearance authority owned by the System. */
|
|
118
|
-
readonly appearance: WritableAppearance;
|
|
119
|
-
readonly program: SystemProgram;
|
|
120
|
-
readonly process: SystemProcess;
|
|
121
|
-
/** Flat System-owned public uploads capability. */
|
|
122
|
-
readonly uploads: SystemUploads;
|
|
123
|
-
/** Returns a stable handle for one exact Service identity. */
|
|
124
|
-
service<ServiceEvents extends object = {}>(key: ServiceKey & {
|
|
125
|
-
endpoint: "server";
|
|
126
|
-
}): ServerServiceHandler<ServiceEvents>;
|
|
127
|
-
service<ServiceEvents extends object = {}>(key: ServiceKey & {
|
|
128
|
-
endpoint: "client";
|
|
129
|
-
}): ClientServiceHandler<ServiceEvents>;
|
|
130
|
-
}
|
|
1
|
+
import type { System } from "@phreshos/core";
|
|
131
2
|
/** Authoritative system capabilities for the currently executing Server. */
|
|
132
3
|
export declare const system: System;
|
|
133
|
-
export {};
|
package/dist/system.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Events from "./events.js";
|
|
2
|
-
import { exit, lifecycleEndpoint, process, program } from "./domain.js";
|
|
2
|
+
import { exit, lifecycleEndpoint, process, program, } from "./domain.js";
|
|
3
3
|
import { uploads } from "./uploads.js";
|
|
4
4
|
import ServerAppearance from "./appearance.js";
|
|
5
5
|
import wire from "./wire.js";
|
|
@@ -11,6 +11,10 @@ class ServerSystem {
|
|
|
11
11
|
program = new ServerSystemProgram();
|
|
12
12
|
process = new ServerSystemProcess();
|
|
13
13
|
uploads = uploads;
|
|
14
|
+
async forceCreateProgram(source) {
|
|
15
|
+
const answer = await wire.request(["host-program-force-create", source]);
|
|
16
|
+
return program(answer[0]);
|
|
17
|
+
}
|
|
14
18
|
service(key) { return prepareService(key); }
|
|
15
19
|
}
|
|
16
20
|
class ServerSystemProgram extends Events {
|
package/dist/wire.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ declare class Wire {
|
|
|
20
20
|
request(values: unknown[], timeout?: number): Promise<unknown>;
|
|
21
21
|
requestWithin(values: unknown[], deadline: Deadline): Promise<unknown>;
|
|
22
22
|
/** Opens one long-running system operation and yields its ordered values. */
|
|
23
|
-
stream(values: unknown[], timeout?: number): AsyncIterableIterator<unknown>;
|
|
23
|
+
stream(values: unknown[], timeout?: number, signal?: AbortSignal): AsyncIterableIterator<unknown>;
|
|
24
24
|
/** Resolves this endpoint's Process address only for operations that need it. */
|
|
25
25
|
identity(): Promise<{
|
|
26
26
|
process: string;
|
package/dist/wire.js
CHANGED
|
@@ -74,7 +74,7 @@ class Wire {
|
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
/** Opens one long-running system operation and yields its ordered values. */
|
|
77
|
-
stream(values, timeout = defaultTimeout) {
|
|
77
|
+
stream(values, timeout = defaultTimeout, signal) {
|
|
78
78
|
const wire = this;
|
|
79
79
|
return (async function* () {
|
|
80
80
|
const question = randomUUID();
|
|
@@ -90,6 +90,15 @@ class Wire {
|
|
|
90
90
|
state.wake = null;
|
|
91
91
|
}, timeout)
|
|
92
92
|
};
|
|
93
|
+
const abort = () => {
|
|
94
|
+
state.failure = signal?.reason instanceof Error ? signal.reason : new Error("The operation was cancelled");
|
|
95
|
+
state.wake?.();
|
|
96
|
+
state.wake = null;
|
|
97
|
+
};
|
|
98
|
+
if (signal?.aborted)
|
|
99
|
+
abort();
|
|
100
|
+
else
|
|
101
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
93
102
|
wire.send("boundary", "expect", question);
|
|
94
103
|
wire.streams.set(question, state);
|
|
95
104
|
wire.send("end-host", "stream", question, ...values);
|
|
@@ -107,6 +116,7 @@ class Wire {
|
|
|
107
116
|
}
|
|
108
117
|
}
|
|
109
118
|
finally {
|
|
119
|
+
signal?.removeEventListener("abort", abort);
|
|
110
120
|
clearTimeout(state.timer);
|
|
111
121
|
wire.streams.delete(question);
|
|
112
122
|
wire.send("boundary", "forget", question);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "The SDK used by a Program's server endpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"prepack": "node --run build"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@phreshos/core": "^0.1.
|
|
50
|
+
"@phreshos/core": "^0.1.22"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@msgpack/msgpack": "^3.1.3"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@phreshos/core": "^0.1.
|
|
56
|
+
"@phreshos/core": "^0.1.22",
|
|
57
57
|
"@types/node": "^26.2.0",
|
|
58
58
|
"typescript": "^6.0.3"
|
|
59
59
|
}
|