@phreshos/server 0.1.22 → 0.1.24
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 +2 -2
- package/dist/system.js +4 -0
- 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
|
@@ -5,5 +5,5 @@ 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, System, SystemProcess, SystemProcessEntity, SystemProcessEntityEvents, SystemProgram, SystemProgramEntity, SystemProgramProcess, SystemProgramProcessEvents, SystemEndpointEntity, SystemServerEntity, SystemClientEntity,
|
|
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, ClientDefinition, SystemProcessEvents, SystemProcessExit, SystemProgramEvents, SystemProgramUninstall, ProgramDefinition, ServerDefinition, 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.js
CHANGED
|
@@ -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.24",
|
|
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.23"
|
|
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.23",
|
|
57
57
|
"@types/node": "^26.2.0",
|
|
58
58
|
"typescript": "^6.0.3"
|
|
59
59
|
}
|