@phreshos/client 0.1.24 → 0.1.26
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 +24 -20
- package/dist/context.d.ts +31 -0
- package/dist/{current.js → context.js} +32 -30
- package/dist/domain.d.ts +25 -5
- package/dist/domain.js +57 -21
- package/dist/events.d.ts +7 -3
- package/dist/events.js +60 -53
- package/dist/main.d.ts +4 -5
- package/dist/main.js +1 -2
- package/dist/service.js +20 -33
- package/dist/wire.d.ts +2 -2
- package/dist/wire.js +2 -2
- package/package.json +3 -3
- package/dist/channel.d.ts +0 -12
- package/dist/channel.js +0 -22
- package/dist/current.d.ts +0 -25
package/README.md
CHANGED
|
@@ -51,17 +51,17 @@ requests; subscriptions receive only future publications and never replay a
|
|
|
51
51
|
retained value.
|
|
52
52
|
|
|
53
53
|
Permission decisions belong to the current Program, not to the desktop System.
|
|
54
|
-
They are available from a Program handle and flattened through `
|
|
54
|
+
They are available from a Program handle and flattened through `context` as the
|
|
55
55
|
same canonical capability:
|
|
56
56
|
|
|
57
57
|
```ts
|
|
58
|
-
const program = await
|
|
58
|
+
const program = await context.program()
|
|
59
59
|
|
|
60
60
|
await program.permission.granted("pointer")
|
|
61
|
-
await
|
|
62
|
-
await
|
|
61
|
+
await context.permission.request("pointer")
|
|
62
|
+
await context.permission.timeout(5_000).request("pointer")
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
context.permission === program.permission
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
`granted()` reads the effective decision without prompting. `request()` asks
|
|
@@ -80,7 +80,10 @@ const service = system.service({
|
|
|
80
80
|
})
|
|
81
81
|
|
|
82
82
|
await service.waitReady()
|
|
83
|
-
if (await service.enabled()) await service.
|
|
83
|
+
if (await service.enabled()) await service.ask("value")
|
|
84
|
+
|
|
85
|
+
service.subscribe("changed", message => console.log(message))
|
|
86
|
+
service.lifecycle.subscribe("disable", () => console.log("unavailable"))
|
|
84
87
|
```
|
|
85
88
|
|
|
86
89
|
A Client may traverse `Process.parent()` through any number of ancestors in
|
|
@@ -98,13 +101,13 @@ into the endpoint. Identity, Theme, Process, Window, readiness, lifecycle, and
|
|
|
98
101
|
application values enter only in response to an explicit request or a live
|
|
99
102
|
registration made by Program code.
|
|
100
103
|
|
|
101
|
-
`
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
operations never masquerade as properties of `
|
|
104
|
+
`Context` combines communication with navigation into the executing Client's
|
|
105
|
+
Process. The paired Server is explicitly named as
|
|
106
|
+
`context.server`; its publishing, asking, existence, readiness, start, and stop
|
|
107
|
+
operations never masquerade as properties of `context`. `context.stop()` stops
|
|
105
108
|
the executing Client, while complete Process exit remains available only
|
|
106
|
-
through `
|
|
107
|
-
`
|
|
109
|
+
through `context.process()`. It is the canonical Process-owned handle, so
|
|
110
|
+
`context.server === (await context.process()).server`.
|
|
108
111
|
Endpoint `process()` navigation is asynchronous; contextual ownership is
|
|
109
112
|
requested only when navigation needs it and then retained by the SDK.
|
|
110
113
|
|
|
@@ -121,7 +124,7 @@ absence or incarnation loss rejects without turning the boundary into a waiter.
|
|
|
121
124
|
The package provides two contextual runtime entry points:
|
|
122
125
|
|
|
123
126
|
```ts
|
|
124
|
-
import { system,
|
|
127
|
+
import { system, context } from "@phreshos/client"
|
|
125
128
|
```
|
|
126
129
|
|
|
127
130
|
It also re-exports the shared Core runtime classes—`Program`, `Process`,
|
|
@@ -131,11 +134,12 @@ them. These are the same domain classes used by the Server SDK, so
|
|
|
131
134
|
`ClientTraffic`, is a type-only capability owned by Client and has no
|
|
132
135
|
independent `instanceof` identity.
|
|
133
136
|
|
|
134
|
-
The
|
|
137
|
+
The executing Client's communication belongs directly to `context`. Its
|
|
135
138
|
subscription tools receive events addressed to this Client, while `publish()`
|
|
136
|
-
emits outward from this Client without choosing a destination. Existence
|
|
137
|
-
readiness
|
|
138
|
-
`
|
|
139
|
+
emits outward from this Client without choosing a destination. Existence and
|
|
140
|
+
readiness belong to `context.server`; the current Client stops through
|
|
141
|
+
`context.stop()`, and explicit Endpoint handles expose their own
|
|
142
|
+
`endpoint.lifecycle` subscriptions.
|
|
139
143
|
|
|
140
144
|
An Endpoint handle is also a selective source: `endpoint.subscribe()` follows
|
|
141
145
|
destinationless events emitted by that Endpoint. Its `traffic` property remains
|
|
@@ -151,7 +155,7 @@ They deliberately omit `install()` and `fork()`, and their `Storage` values neve
|
|
|
151
155
|
expose native filesystem paths. Every Client-side Window handle exposes the same
|
|
152
156
|
authoritative, subscribable Window capability and its `window.local` physical
|
|
153
157
|
representation on this desktop. Local reads and updates have no events and do
|
|
154
|
-
not change Server state. `
|
|
158
|
+
not change Server state. `context.window` is only convenient access to the
|
|
155
159
|
executing Client's canonical Window; it has no additional authority.
|
|
156
160
|
|
|
157
161
|
A Client may uninstall only its own Program. The operation is an async
|
|
@@ -186,9 +190,9 @@ two independent operations and can expose an intermediate state remotely.
|
|
|
186
190
|
An `under` or `over` representation may request one local system-rendered Surface:
|
|
187
191
|
|
|
188
192
|
```ts
|
|
189
|
-
await
|
|
193
|
+
await context.window.local.surface.set({ duration: 240, easing: "ease-out", wait: true })
|
|
190
194
|
|
|
191
|
-
await
|
|
195
|
+
await context.window.local.surface.remove({ duration: 180, easing: "ease-in" })
|
|
192
196
|
```
|
|
193
197
|
|
|
194
198
|
The desktop holds local state only for the lifetime of that iframe
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Context as CoreContext, ContextCapture as CoreContextCapture, ContextEvents as CoreContextEvents, ContextMessage as CoreContextMessage } from "@phreshos/core";
|
|
2
|
+
import { Client, Server, type Endpoint, type Process, type Program, type Window } from "./domain.js";
|
|
3
|
+
/** The executing Process's canonical Server handle. */
|
|
4
|
+
export type ContextServer<Events extends object = {}> = Server<Events>;
|
|
5
|
+
/** One value addressed to the current Client, with a client-visible sender. */
|
|
6
|
+
export type ContextMessage<Payload = unknown> = CoreContextMessage<Payload, Endpoint | null>;
|
|
7
|
+
/** Applies the client-visible sender envelope to known Context events. */
|
|
8
|
+
export type ContextEvents<Events extends object> = CoreContextEvents<Events, Endpoint | null>;
|
|
9
|
+
/** Every event observable through the current Client Context. */
|
|
10
|
+
export type ContextCapture<Events extends object = {}> = CoreContextCapture<Events, Endpoint | null>;
|
|
11
|
+
/** Client runtime context: inbound communication, owner hierarchy, and paired Server. */
|
|
12
|
+
export interface Context<Events extends object = {}> extends CoreContext<Events, Endpoint | null>, Pick<Client, "service"> {
|
|
13
|
+
/** The same Server handle exposed by the executing Process. */
|
|
14
|
+
readonly server: ContextServer;
|
|
15
|
+
/** Presentation capability of the executing Client. */
|
|
16
|
+
readonly window: Window;
|
|
17
|
+
/** The same permission capability exposed by the executing Program. */
|
|
18
|
+
readonly permission: Program["permission"];
|
|
19
|
+
/** Returns the Process represented by this Client. */
|
|
20
|
+
process(): Promise<Process>;
|
|
21
|
+
/** Returns the accessible parent Process, or `null` when none exists. */
|
|
22
|
+
parent(): Promise<Process | null>;
|
|
23
|
+
/** Returns the Program that owns this Client. */
|
|
24
|
+
program(): Promise<Program>;
|
|
25
|
+
/** Returns one immutable option supplied when this Process was created. */
|
|
26
|
+
option(name: string): Promise<string | undefined>;
|
|
27
|
+
/** Stops the executing Client; rejects when it is the final live Endpoint. */
|
|
28
|
+
stop(): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** Inbound events, owner hierarchy, and paired Server for this Client runtime. */
|
|
31
|
+
export declare const context: Context;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { channel } from "./channel.js";
|
|
2
1
|
import Deadline from "./deadline.js";
|
|
3
|
-
import { Client, Server, ServerTrafficHandle, TrafficHandle, bindEvents, endpointEvents, process, program, window as windowHandle } from "./domain.js";
|
|
2
|
+
import { Client, Server, ServerTrafficHandle, TrafficHandle, bindEvents, endpointLifecycle, endpointEvents, process, program, visibleEndpoint, window as windowHandle } from "./domain.js";
|
|
3
|
+
import Events from "./events.js";
|
|
4
4
|
import wire from "./wire.js";
|
|
5
|
-
import { endpointService } from "./service.js";
|
|
5
|
+
import { disableCurrentService, enableCurrentService, endpointService } from "./service.js";
|
|
6
6
|
import { currentProgramPermission } from "./permissions.js";
|
|
7
7
|
const ServerBase = Server;
|
|
8
8
|
const ClientBase = Client;
|
|
9
|
-
class
|
|
9
|
+
class ContextServerHandle extends ServerBase {
|
|
10
10
|
owner;
|
|
11
11
|
traffic = new ServerTrafficHandle(null, "server");
|
|
12
|
+
lifecycle = endpointLifecycle(currentAddress, "server");
|
|
12
13
|
constructor(owner) {
|
|
13
14
|
super();
|
|
14
15
|
this.owner = owner;
|
|
@@ -37,12 +38,12 @@ class CurrentServerHandle extends ServerBase {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
let ownerPromise = null;
|
|
40
|
-
let
|
|
41
|
-
let
|
|
41
|
+
let contextServer;
|
|
42
|
+
let contextClient;
|
|
42
43
|
function owner() {
|
|
43
44
|
if (!ownerPromise) {
|
|
44
45
|
const resolving = wire.request(["current-process"]).then(answer => {
|
|
45
|
-
return process(answer[0], { server:
|
|
46
|
+
return process(answer[0], { server: contextServer, client: contextClient });
|
|
46
47
|
});
|
|
47
48
|
const retained = resolving.catch(error => {
|
|
48
49
|
if (ownerPromise === retained)
|
|
@@ -53,14 +54,12 @@ function owner() {
|
|
|
53
54
|
}
|
|
54
55
|
return ownerPromise;
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
-
class
|
|
57
|
+
contextServer = new ContextServerHandle(owner);
|
|
58
|
+
class ContextClientHandle extends ClientBase {
|
|
58
59
|
owner;
|
|
59
60
|
traffic = new TrafficHandle(null, "client");
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return { identity: identity.process, reference: identity.reference };
|
|
63
|
-
});
|
|
61
|
+
lifecycle = endpointLifecycle(currentAddress, "client");
|
|
62
|
+
window = windowHandle(currentAddress);
|
|
64
63
|
constructor(owner) {
|
|
65
64
|
super();
|
|
66
65
|
this.owner = owner;
|
|
@@ -80,13 +79,16 @@ class CurrentClientHandle extends ClientBase {
|
|
|
80
79
|
async stop() { await wire.request(["stop-endpoint", undefined, "client"]); }
|
|
81
80
|
service() { return endpointService(null, "client"); }
|
|
82
81
|
}
|
|
83
|
-
|
|
84
|
-
class
|
|
85
|
-
server =
|
|
86
|
-
window =
|
|
82
|
+
contextClient = new ContextClientHandle(owner);
|
|
83
|
+
class ClientContext extends Events {
|
|
84
|
+
server = contextServer;
|
|
85
|
+
window = contextClient.window;
|
|
87
86
|
permission = currentProgramPermission;
|
|
88
87
|
constructor() {
|
|
89
|
-
|
|
88
|
+
super((event, listener, impossible) => wire.on("end-end", event, value => listener(contextMessage(value)), null, impossible), (listener, impossible) => wire.onAll("end-end", (event, value) => {
|
|
89
|
+
if (typeof event === "string")
|
|
90
|
+
listener(event, contextMessage(value));
|
|
91
|
+
}, null, impossible));
|
|
90
92
|
}
|
|
91
93
|
process() { return owner(); }
|
|
92
94
|
async parent() {
|
|
@@ -103,17 +105,17 @@ class ClientCurrent {
|
|
|
103
105
|
}
|
|
104
106
|
async stop() { await wire.request(["stop-current"]); }
|
|
105
107
|
service() { return endpointService(null, "client"); }
|
|
108
|
+
publish(event, payload = undefined) { wire.send("end-host", "emit", event, payload); }
|
|
109
|
+
async enableService(name) { await enableCurrentService(name); }
|
|
110
|
+
async disableService() { await disableCurrentService(); }
|
|
106
111
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
subscribe: source.subscribe.bind(source),
|
|
111
|
-
waitFor: source.waitFor.bind(source),
|
|
112
|
-
events: source.events.bind(source),
|
|
113
|
-
observe: source.observe.bind(source),
|
|
114
|
-
enableService: source.enableService.bind(source),
|
|
115
|
-
disableService: source.disableService.bind(source)
|
|
116
|
-
});
|
|
112
|
+
async function currentAddress() {
|
|
113
|
+
const identity = await wire.identity();
|
|
114
|
+
return { identity: identity.process, reference: identity.reference };
|
|
117
115
|
}
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
function contextMessage(value) {
|
|
117
|
+
const raw = value;
|
|
118
|
+
return { from: visibleEndpoint(raw.from), payload: raw.payload };
|
|
119
|
+
}
|
|
120
|
+
/** Inbound events, owner hierarchy, and paired Server for this Client runtime. */
|
|
121
|
+
export const context = new ClientContext();
|
package/dist/domain.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client as CoreClient, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, type AnswerCapture as CoreAnswerCapture, type AnswerMessage as CoreAnswerMessage, type
|
|
1
|
+
import { Client as CoreClient, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer, type AnswerCapture as CoreAnswerCapture, type AnswerMessage as CoreAnswerMessage, type AnswerSubscriber as CoreAnswerSubscriber, type AskCapture as CoreAskCapture, type AskMessage as CoreAskMessage, type AskSubscriber as CoreAskSubscriber, type Cleanup, type ClientTraffic as CoreClientTraffic, type ClientDeclaration, type EndpointTraffic as CoreEndpointTraffic, type Exit, type EventOptions, type Launch, type LocalWindow, type Outcome, type Permission, type Position, type ProgramProcess as CoreProgramProcess, type ServerTraffic as CoreServerTraffic, type Size, type TrafficMessage as CoreTrafficMessage, type TrafficCapture as CoreTrafficCapture, type TrafficEvents as CoreTrafficEvents, type Window as CoreWindow, type WindowState } from "@phreshos/core";
|
|
2
2
|
import Events from "./events.js";
|
|
3
3
|
export interface HandleAddress {
|
|
4
4
|
identity: string;
|
|
@@ -86,13 +86,13 @@ export type AskMessage<Payload = unknown> = CoreAskMessage<Payload, Server | nul
|
|
|
86
86
|
/** One question observable in client-visible Endpoint traffic. */
|
|
87
87
|
export type AskCapture<Payload = unknown> = CoreAskCapture<Payload, Server | null>;
|
|
88
88
|
/** Callback that observes questions sent by a client-visible Endpoint. */
|
|
89
|
-
export type
|
|
89
|
+
export type AskSubscriber<Payload = unknown> = CoreAskSubscriber<Payload, Server | null>;
|
|
90
90
|
/** Answer with an Endpoint destination hidden when it crosses the Client boundary. */
|
|
91
91
|
export type AnswerMessage<Result = unknown> = CoreAnswerMessage<Result, Endpoint | null>;
|
|
92
92
|
/** One answer observable in client-visible Server traffic. */
|
|
93
93
|
export type AnswerCapture<Result = unknown> = CoreAnswerCapture<Result, Endpoint | null>;
|
|
94
94
|
/** Callback that observes answers sent by a client-visible Server. */
|
|
95
|
-
export type
|
|
95
|
+
export type AnswerSubscriber<Result = unknown> = CoreAnswerSubscriber<Result, Endpoint | null>;
|
|
96
96
|
/** Directed communication originating from one client-visible Endpoint. */
|
|
97
97
|
export type EndpointTraffic<Events extends object = {}> = CoreEndpointTraffic<Events, Endpoint | null, Server | null>;
|
|
98
98
|
/** Directed communication originating from one client-visible Server. */
|
|
@@ -131,15 +131,35 @@ export declare class TrafficHandle extends Events {
|
|
|
131
131
|
protected readonly target: HandleAddress | null;
|
|
132
132
|
protected readonly kind: "server" | "client";
|
|
133
133
|
constructor(target: HandleAddress | null, kind: "server" | "client");
|
|
134
|
-
|
|
134
|
+
subscribeAsks(subscriber: (capture: AskCapture) => unknown): Cleanup;
|
|
135
|
+
asks(options?: EventOptions): AsyncIterableIterator<Readonly<{
|
|
136
|
+
event: string;
|
|
137
|
+
questionId: string;
|
|
138
|
+
message: Readonly<{
|
|
139
|
+
to: Server<{}> | null;
|
|
140
|
+
payload: unknown;
|
|
141
|
+
}>;
|
|
142
|
+
}>>;
|
|
143
|
+
private followAsks;
|
|
135
144
|
}
|
|
136
145
|
export declare class ServerTrafficHandle extends TrafficHandle {
|
|
137
|
-
|
|
146
|
+
subscribeAnswers(subscriber: (capture: AnswerCapture) => unknown): Cleanup;
|
|
147
|
+
answers(options?: EventOptions): AsyncIterableIterator<Readonly<{
|
|
148
|
+
event: string;
|
|
149
|
+
questionId: string;
|
|
150
|
+
message: Readonly<{
|
|
151
|
+
to: Endpoint<{}> | null;
|
|
152
|
+
outcome: Outcome<unknown>;
|
|
153
|
+
}>;
|
|
154
|
+
}>>;
|
|
155
|
+
private followAnswers;
|
|
138
156
|
}
|
|
139
157
|
type WindowTarget = () => Promise<HandleAddress>;
|
|
140
158
|
export declare function scoped(route: string, subject: string | null, convert: (event: string, values: unknown[]) => unknown): Events;
|
|
141
159
|
/** Destinationless events originating from one Endpoint handle. */
|
|
142
160
|
export declare function endpointEvents(target: HandleAddress | null, half: "server" | "client"): Events;
|
|
161
|
+
/** Start and stop transitions belonging directly to one permanent Endpoint. */
|
|
162
|
+
export declare function endpointLifecycle(target: WindowTarget, half: "server" | "client"): Events;
|
|
143
163
|
export declare function exit(code: unknown, signal: unknown): Exit;
|
|
144
164
|
export declare function trafficMessage(value: unknown): TrafficMessage;
|
|
145
165
|
export declare function bindEvents(target: object, events: Events): void;
|
package/dist/domain.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Client as CoreClient, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer } from "@phreshos/core";
|
|
2
|
-
import Events from "./events.js";
|
|
2
|
+
import Events, { stream } from "./events.js";
|
|
3
3
|
import Deadline from "./deadline.js";
|
|
4
4
|
import HandleRegistry from "./handle-registry.js";
|
|
5
5
|
import { area, sql, store } from "./storage.js";
|
|
@@ -165,38 +165,52 @@ export class TrafficHandle extends Events {
|
|
|
165
165
|
target;
|
|
166
166
|
kind;
|
|
167
167
|
constructor(target, kind) {
|
|
168
|
-
super((event, listener, impossible) => wire.observe(target, kind, "publish", event, value => listener(trafficMessage(value)), impossible),
|
|
168
|
+
super((event, listener, impossible) => wire.observe(target, kind, "publish", event, value => listener(trafficMessage(value)), impossible), (listener, impossible) => wire.observe(target, kind, "publish", null, (event, value) => {
|
|
169
169
|
if (typeof event === "string")
|
|
170
|
-
|
|
171
|
-
}));
|
|
170
|
+
listener(event, trafficMessage(value));
|
|
171
|
+
}, impossible));
|
|
172
172
|
this.target = target;
|
|
173
173
|
this.kind = kind;
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
subscribeAsks(subscriber) {
|
|
176
|
+
return this.followAsks(subscriber);
|
|
177
|
+
}
|
|
178
|
+
asks(options) {
|
|
179
|
+
return stream((subscriber, impossible) => this.followAsks(subscriber, impossible), options);
|
|
180
|
+
}
|
|
181
|
+
followAsks(subscriber, impossible) {
|
|
176
182
|
return wire.observe(this.target, this.kind, "ask", null, (event, questionId, value) => {
|
|
177
183
|
if (typeof event !== "string" || typeof questionId !== "string")
|
|
178
184
|
return;
|
|
179
|
-
|
|
180
|
-
});
|
|
185
|
+
subscriber({ event, questionId, message: trafficMessage(value) });
|
|
186
|
+
}, impossible);
|
|
181
187
|
}
|
|
182
188
|
}
|
|
183
189
|
export class ServerTrafficHandle extends TrafficHandle {
|
|
184
|
-
|
|
190
|
+
subscribeAnswers(subscriber) {
|
|
191
|
+
return this.followAnswers(subscriber);
|
|
192
|
+
}
|
|
193
|
+
answers(options) {
|
|
194
|
+
return stream((subscriber, impossible) => this.followAnswers(subscriber, impossible), options);
|
|
195
|
+
}
|
|
196
|
+
followAnswers(subscriber, impossible) {
|
|
185
197
|
return wire.observe(this.target, "server", "answer", null, (event, questionId, value) => {
|
|
186
198
|
if (typeof event !== "string" || typeof questionId !== "string")
|
|
187
199
|
return;
|
|
188
200
|
const raw = value;
|
|
189
|
-
|
|
190
|
-
});
|
|
201
|
+
subscriber({ event, questionId, message: { to: visibleEndpoint(raw.to), outcome: raw.outcome } });
|
|
202
|
+
}, impossible);
|
|
191
203
|
}
|
|
192
204
|
}
|
|
193
205
|
class ServerHandle extends ServerBase {
|
|
194
206
|
owner;
|
|
195
207
|
traffic;
|
|
208
|
+
lifecycle;
|
|
196
209
|
constructor(owner) {
|
|
197
210
|
super();
|
|
198
211
|
this.owner = owner;
|
|
199
212
|
this.traffic = new ServerTrafficHandle(owner.address, "server");
|
|
213
|
+
this.lifecycle = endpointLifecycle(() => Promise.resolve(owner.address), "server");
|
|
200
214
|
bindEvents(this, endpointEvents(owner.address, "server"));
|
|
201
215
|
}
|
|
202
216
|
async process() { return this.owner; }
|
|
@@ -234,11 +248,13 @@ class ServerHandle extends ServerBase {
|
|
|
234
248
|
class ClientHandle extends ClientBase {
|
|
235
249
|
owner;
|
|
236
250
|
traffic;
|
|
251
|
+
lifecycle;
|
|
237
252
|
window;
|
|
238
253
|
constructor(owner) {
|
|
239
254
|
super();
|
|
240
255
|
this.owner = owner;
|
|
241
256
|
this.traffic = new TrafficHandle(owner.address, "client");
|
|
257
|
+
this.lifecycle = endpointLifecycle(() => Promise.resolve(owner.address), "client");
|
|
242
258
|
this.window = window(async () => owner.address);
|
|
243
259
|
bindEvents(this, endpointEvents(owner.address, "client"));
|
|
244
260
|
}
|
|
@@ -328,13 +344,13 @@ function deferredScoped(route, target, convert) {
|
|
|
328
344
|
listener(convert(event, message));
|
|
329
345
|
}, subject, impossible), impossible);
|
|
330
346
|
},
|
|
331
|
-
|
|
347
|
+
(listener, impossible) => deferred(target, subject => wire.onAll(route, (event, ...values) => {
|
|
332
348
|
if (typeof event !== "string" || !windowEvent(event))
|
|
333
349
|
return;
|
|
334
350
|
const message = unscoped(subject, values);
|
|
335
351
|
if (message)
|
|
336
|
-
|
|
337
|
-
}, subject))
|
|
352
|
+
listener(event, convert(event, message));
|
|
353
|
+
}, subject, impossible), impossible)
|
|
338
354
|
];
|
|
339
355
|
}
|
|
340
356
|
function windowEvent(event) {
|
|
@@ -363,20 +379,41 @@ export function scoped(route, subject, convert) {
|
|
|
363
379
|
const message = unscoped(subject, values);
|
|
364
380
|
if (message)
|
|
365
381
|
listener(convert(event, message));
|
|
366
|
-
}, subject, impossible),
|
|
382
|
+
}, subject, impossible), (listener, impossible) => wire.onAll(route, (event, ...values) => {
|
|
367
383
|
if (typeof event !== "string")
|
|
368
384
|
return;
|
|
369
385
|
const message = unscoped(subject, values);
|
|
370
386
|
if (message)
|
|
371
|
-
|
|
372
|
-
}, subject));
|
|
387
|
+
listener(event, convert(event, message));
|
|
388
|
+
}, subject, impossible));
|
|
373
389
|
}
|
|
374
390
|
/** Destinationless events originating from one Endpoint handle. */
|
|
375
391
|
export function endpointEvents(target, half) {
|
|
376
|
-
return new Events((event, listener, impossible) => wire.follow(target, half, event, listener, impossible),
|
|
392
|
+
return new Events((event, listener, impossible) => wire.follow(target, half, event, listener, impossible), (listener, impossible) => wire.follow(target, half, null, (event, payload) => {
|
|
377
393
|
if (typeof event === "string")
|
|
378
|
-
|
|
379
|
-
}));
|
|
394
|
+
listener(event, payload);
|
|
395
|
+
}, impossible));
|
|
396
|
+
}
|
|
397
|
+
/** Start and stop transitions belonging directly to one permanent Endpoint. */
|
|
398
|
+
export function endpointLifecycle(target, half) {
|
|
399
|
+
return new Events((event, listener, impossible) => deferred(target, subject => wire.on("process-host", endpointLifecycleEvent(event), (...values) => {
|
|
400
|
+
const message = unscoped(subject, values);
|
|
401
|
+
if (message?.[1] === half)
|
|
402
|
+
listener(undefined);
|
|
403
|
+
}, subject, impossible), impossible), (listener, impossible) => deferred(target, subject => wire.onAll("process-host", (event, ...values) => {
|
|
404
|
+
if (event !== "endpointStart" && event !== "endpointStop")
|
|
405
|
+
return;
|
|
406
|
+
const message = unscoped(subject, values);
|
|
407
|
+
if (message?.[1] === half)
|
|
408
|
+
listener(event === "endpointStart" ? "start" : "stop", undefined);
|
|
409
|
+
}, subject, impossible), impossible));
|
|
410
|
+
}
|
|
411
|
+
function endpointLifecycleEvent(event) {
|
|
412
|
+
if (event === "start")
|
|
413
|
+
return "endpointStart";
|
|
414
|
+
if (event === "stop")
|
|
415
|
+
return "endpointStop";
|
|
416
|
+
return event;
|
|
380
417
|
}
|
|
381
418
|
function unscoped(subject, values) {
|
|
382
419
|
if (subject === null)
|
|
@@ -426,8 +463,7 @@ export function bindEvents(target, events) {
|
|
|
426
463
|
Object.assign(target, {
|
|
427
464
|
subscribe: events.subscribe.bind(events),
|
|
428
465
|
waitFor: events.waitFor.bind(events),
|
|
429
|
-
events: events.events.bind(events)
|
|
430
|
-
observe: events.observe.bind(events)
|
|
466
|
+
events: events.events.bind(events)
|
|
431
467
|
});
|
|
432
468
|
}
|
|
433
469
|
export function program(record) {
|
package/dist/events.d.ts
CHANGED
|
@@ -2,15 +2,19 @@ import type { Capture, Cleanup, EventOptions } from "@phreshos/core";
|
|
|
2
2
|
export declare const defaultTimeout = 10000;
|
|
3
3
|
type Failure = (error: Error) => void;
|
|
4
4
|
type Listener = (message: unknown) => unknown;
|
|
5
|
-
type
|
|
5
|
+
type EveryListener = (event: string, message: unknown) => unknown;
|
|
6
|
+
type Register<Message> = (listener: (message: Message) => unknown, impossible?: Failure) => Cleanup;
|
|
6
7
|
/** SDK-owned waits, queues and callbacks over boundary forwarding state. */
|
|
7
8
|
export default class Events {
|
|
8
9
|
private readonly listen;
|
|
9
10
|
private readonly listenAll;
|
|
10
|
-
constructor(listen: (event: string, listener: Listener, impossible?: Failure) => Cleanup, listenAll: (
|
|
11
|
+
constructor(listen: (event: string, listener: Listener, impossible?: Failure) => Cleanup, listenAll: (listener: EveryListener, impossible?: Failure) => Cleanup);
|
|
11
12
|
subscribe(event: string, subscriber: Listener): Cleanup;
|
|
13
|
+
subscribe(subscriber: (capture: Capture<string, unknown>) => unknown): Cleanup;
|
|
12
14
|
waitFor(event: string, timeout?: number): Promise<unknown>;
|
|
13
15
|
events(event: string, options?: EventOptions): AsyncIterableIterator<unknown>;
|
|
14
|
-
|
|
16
|
+
events(options?: EventOptions): AsyncIterableIterator<Capture<string, unknown>>;
|
|
15
17
|
}
|
|
18
|
+
/** Converts one persistent registration into a bounded asynchronous iterator. */
|
|
19
|
+
export declare function stream<Message>(register: Register<Message>, options?: EventOptions): AsyncIterableIterator<Message>;
|
|
16
20
|
export {};
|
package/dist/events.js
CHANGED
|
@@ -7,8 +7,10 @@ export default class Events {
|
|
|
7
7
|
this.listen = listen;
|
|
8
8
|
this.listenAll = listenAll;
|
|
9
9
|
}
|
|
10
|
-
subscribe(
|
|
11
|
-
|
|
10
|
+
subscribe(eventOrSubscriber, subscriber) {
|
|
11
|
+
if (typeof eventOrSubscriber === "string")
|
|
12
|
+
return this.listen(eventOrSubscriber, subscriber);
|
|
13
|
+
return this.listenAll((event, message) => eventOrSubscriber({ event, message }));
|
|
12
14
|
}
|
|
13
15
|
waitFor(event, timeout = defaultTimeout) {
|
|
14
16
|
return new Promise((resolve, reject) => {
|
|
@@ -26,58 +28,63 @@ export default class Events {
|
|
|
26
28
|
stop = this.listen(event, message => finish(() => resolve(message)), error => finish(() => reject(error)));
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
|
-
events(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new Error("An event queue capacity must be a non-negative integer or Infinity");
|
|
31
|
+
events(eventOrOptions = {}, namedOptions = {}) {
|
|
32
|
+
if (typeof eventOrOptions === "string") {
|
|
33
|
+
return stream((listener, impossible) => this.listen(eventOrOptions, listener, impossible), namedOptions);
|
|
33
34
|
}
|
|
34
|
-
|
|
35
|
-
return (async function* () {
|
|
36
|
-
const queue = [];
|
|
37
|
-
let ended = false;
|
|
38
|
-
let failure = null;
|
|
39
|
-
let wake = null;
|
|
40
|
-
const stop = listen(event, message => {
|
|
41
|
-
if (ended || failure)
|
|
42
|
-
return;
|
|
43
|
-
if (queue.length >= capacity)
|
|
44
|
-
failure = new Error(`Event queue exceeded its capacity of ${capacity}`);
|
|
45
|
-
else
|
|
46
|
-
queue.push(message);
|
|
47
|
-
wake?.();
|
|
48
|
-
wake = null;
|
|
49
|
-
}, error => {
|
|
50
|
-
if (ended || failure)
|
|
51
|
-
return;
|
|
52
|
-
failure = error;
|
|
53
|
-
wake?.();
|
|
54
|
-
wake = null;
|
|
55
|
-
});
|
|
56
|
-
const abort = () => {
|
|
57
|
-
ended = true;
|
|
58
|
-
wake?.();
|
|
59
|
-
wake = null;
|
|
60
|
-
};
|
|
61
|
-
options.signal?.addEventListener("abort", abort, { once: true });
|
|
62
|
-
try {
|
|
63
|
-
while (!ended) {
|
|
64
|
-
if (queue.length) {
|
|
65
|
-
yield queue.shift();
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
if (failure)
|
|
69
|
-
throw failure;
|
|
70
|
-
await new Promise(resolve => { wake = resolve; });
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
finally {
|
|
74
|
-
ended = true;
|
|
75
|
-
stop();
|
|
76
|
-
options.signal?.removeEventListener("abort", abort);
|
|
77
|
-
}
|
|
78
|
-
})();
|
|
35
|
+
return stream((listener, impossible) => this.listenAll((event, message) => listener({ event, message }), impossible), eventOrOptions);
|
|
79
36
|
}
|
|
80
|
-
|
|
81
|
-
|
|
37
|
+
}
|
|
38
|
+
/** Converts one persistent registration into a bounded asynchronous iterator. */
|
|
39
|
+
export function stream(register, options = {}) {
|
|
40
|
+
const capacity = options.capacity ?? 64;
|
|
41
|
+
if (capacity !== Infinity && (!Number.isInteger(capacity) || capacity < 0)) {
|
|
42
|
+
throw new Error("An event queue capacity must be a non-negative integer or Infinity");
|
|
82
43
|
}
|
|
44
|
+
return (async function* () {
|
|
45
|
+
const queue = [];
|
|
46
|
+
let ended = false;
|
|
47
|
+
let failure = null;
|
|
48
|
+
let wake = null;
|
|
49
|
+
const stop = register(message => {
|
|
50
|
+
if (ended || failure)
|
|
51
|
+
return;
|
|
52
|
+
if (queue.length >= capacity)
|
|
53
|
+
failure = new Error(`Event queue exceeded its capacity of ${capacity}`);
|
|
54
|
+
else
|
|
55
|
+
queue.push(message);
|
|
56
|
+
wake?.();
|
|
57
|
+
wake = null;
|
|
58
|
+
}, error => {
|
|
59
|
+
if (ended || failure)
|
|
60
|
+
return;
|
|
61
|
+
failure = error;
|
|
62
|
+
wake?.();
|
|
63
|
+
wake = null;
|
|
64
|
+
});
|
|
65
|
+
const abort = () => {
|
|
66
|
+
ended = true;
|
|
67
|
+
wake?.();
|
|
68
|
+
wake = null;
|
|
69
|
+
};
|
|
70
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
71
|
+
if (options.signal?.aborted)
|
|
72
|
+
abort();
|
|
73
|
+
try {
|
|
74
|
+
while (!ended) {
|
|
75
|
+
if (queue.length) {
|
|
76
|
+
yield queue.shift();
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (failure)
|
|
80
|
+
throw failure;
|
|
81
|
+
await new Promise(resolve => { wake = resolve; });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
ended = true;
|
|
86
|
+
stop();
|
|
87
|
+
options.signal?.removeEventListener("abort", abort);
|
|
88
|
+
}
|
|
89
|
+
})();
|
|
83
90
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export { system, type System } from "./system.js";
|
|
2
2
|
export { type SystemPointer, type PointerEvents, type PointerPosition } from "./pointer.js";
|
|
3
3
|
export { type DesktopEvents, type DesktopSize, type SystemDesktop } from "./desktop.js";
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export type { Askable, Capture, Captures, ClientDeclaration, Cleanup, DirectoryStat, EndpointDeclaration, EntryStat, EventMessage, EventName, EventObserver, EventOptions, EventSubscriber, Exit, FileStat, Launch, LaunchClient, Layer, LogKind, LogRecord, LogSource, Message, OtherStat, Outcome, PermissionDecision, Permission, Position, Storage, ProgramEvents, ProgramProcessEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, SystemUploads, Upload, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TimedPermission, Timeoutable, Appearance, AppearanceEvents, AppearanceSource, AppearanceSurface, AnimationsPreference, DesktopPreferences, DesktopPreferencesEvents, DesktopPreferencesUpdate, SystemDesktopPreferences, ThemedValue, Theme, ThemePreference, Value, WindowEvents, WindowGeometry, WindowLayer, WindowState, Easing, LocalWindow, LocalWindowSurface, VisibilityTransition, Transaction } from "@phreshos/core";
|
|
4
|
+
export { context, type Context, type ContextCapture, type ContextEvents, type ContextMessage, type ContextServer } from "./context.js";
|
|
5
|
+
export { ClientService, ServerService, Service, type ServiceKey, type ServiceLifecycle, type ServiceLifecycleEvents } from "@phreshos/core";
|
|
6
|
+
export { Client, Endpoint, Process, Program, Server, type Window, type ProgramProcess, type AnswerCapture, type AnswerMessage, type AnswerSubscriber, type AskCapture, type AskMessage, type AskSubscriber, type ClientTraffic, type EndpointTraffic, type ServerTraffic, type TrafficCapture, type TrafficEvents, type TrafficMessage } from "./domain.js";
|
|
7
|
+
export type { Askable, Capture, Captures, CaptureSubscriber, ClientDeclaration, Cleanup, DirectoryStat, EndpointDeclaration, EndpointLifecycle, EndpointLifecycleEvents, EntryStat, EventMessage, EventName, EventOptions, EventSubscriber, Exit, FileStat, Launch, LaunchClient, Layer, LogKind, LogRecord, LogSource, Message, OtherStat, Outcome, PermissionDecision, Permission, Position, Storage, ProgramEvents, ProgramProcessEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, SystemUploads, Upload, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TimedPermission, Timeoutable, Appearance, AppearanceEvents, AppearanceSource, AppearanceSurface, AnimationsPreference, DesktopPreferences, DesktopPreferencesEvents, DesktopPreferencesUpdate, SystemDesktopPreferences, ThemedValue, Theme, ThemePreference, Value, WindowEvents, WindowGeometry, WindowLayer, WindowState, Easing, LocalWindow, LocalWindowSurface, VisibilityTransition, Transaction } from "@phreshos/core";
|
package/dist/main.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export { system } from "./system.js";
|
|
2
2
|
export {} from "./pointer.js";
|
|
3
3
|
export {} from "./desktop.js";
|
|
4
|
-
export {
|
|
5
|
-
export {} from "./channel.js";
|
|
4
|
+
export { context } from "./context.js";
|
|
6
5
|
export { ClientService, ServerService, Service } from "@phreshos/core";
|
|
7
6
|
export { Client, Endpoint, Process, Program, Server } from "./domain.js";
|
package/dist/service.js
CHANGED
|
@@ -6,11 +6,16 @@ import wire from "./wire.js";
|
|
|
6
6
|
const handles = new HandleRegistry();
|
|
7
7
|
const ServerServiceBase = CoreServerService;
|
|
8
8
|
const ClientServiceBase = CoreClientService;
|
|
9
|
-
class
|
|
9
|
+
class ServerHandler extends ServerServiceBase {
|
|
10
10
|
key;
|
|
11
|
+
name;
|
|
12
|
+
lifecycle;
|
|
11
13
|
constructor(key) {
|
|
12
|
-
super(
|
|
14
|
+
super();
|
|
13
15
|
this.key = key;
|
|
16
|
+
this.name = key.name;
|
|
17
|
+
this.lifecycle = new Events(...serviceEvents(key, "lifecycle"));
|
|
18
|
+
bindEvents(this, new Events(...serviceEvents(key, "events")));
|
|
14
19
|
}
|
|
15
20
|
publish(event, payload = undefined) {
|
|
16
21
|
wire.send("end-host", "service-send", this.key, event, payload);
|
|
@@ -25,6 +30,13 @@ class ServerChannelHandle extends Events {
|
|
|
25
30
|
}
|
|
26
31
|
};
|
|
27
32
|
}
|
|
33
|
+
async enabled() {
|
|
34
|
+
const answer = await wire.request(["service-enabled", this.key]);
|
|
35
|
+
return answer[0];
|
|
36
|
+
}
|
|
37
|
+
async waitReady(timeout) {
|
|
38
|
+
await wire.request(["service-wait-ready", this.key, timeout], timeout);
|
|
39
|
+
}
|
|
28
40
|
async askWithin(deadline, event, payload) {
|
|
29
41
|
const identity = await wire.identity();
|
|
30
42
|
const address = `client:${identity.process}:${crypto.randomUUID()}`;
|
|
@@ -39,40 +51,16 @@ class ServerChannelHandle extends Events {
|
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
|
-
class ClientChannelHandle extends Events {
|
|
43
|
-
constructor(key) {
|
|
44
|
-
super(...serviceEvents(key, "channel"));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
class ServerHandler extends ServerServiceBase {
|
|
48
|
-
key;
|
|
49
|
-
name;
|
|
50
|
-
channel;
|
|
51
|
-
constructor(key) {
|
|
52
|
-
super();
|
|
53
|
-
this.key = key;
|
|
54
|
-
this.name = key.name;
|
|
55
|
-
this.channel = new ServerChannelHandle(key);
|
|
56
|
-
bindEvents(this, new Events(...serviceEvents(key, "lifecycle")));
|
|
57
|
-
}
|
|
58
|
-
async enabled() {
|
|
59
|
-
const answer = await wire.request(["service-enabled", this.key]);
|
|
60
|
-
return answer[0];
|
|
61
|
-
}
|
|
62
|
-
async waitReady(timeout) {
|
|
63
|
-
await wire.request(["service-wait-ready", this.key, timeout], timeout);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
54
|
class ClientHandler extends ClientServiceBase {
|
|
67
55
|
key;
|
|
68
56
|
name;
|
|
69
|
-
|
|
57
|
+
lifecycle;
|
|
70
58
|
constructor(key) {
|
|
71
59
|
super();
|
|
72
60
|
this.key = key;
|
|
73
61
|
this.name = key.name;
|
|
74
|
-
this.
|
|
75
|
-
bindEvents(this, new Events(...serviceEvents(key, "
|
|
62
|
+
this.lifecycle = new Events(...serviceEvents(key, "lifecycle"));
|
|
63
|
+
bindEvents(this, new Events(...serviceEvents(key, "events")));
|
|
76
64
|
}
|
|
77
65
|
async enabled() {
|
|
78
66
|
const answer = await wire.request(["service-enabled", this.key]);
|
|
@@ -106,9 +94,9 @@ export async function endpointService(target, endpoint) {
|
|
|
106
94
|
function serviceEvents(key, scope) {
|
|
107
95
|
return [
|
|
108
96
|
(event, listener) => wire.followService(key, scope, event, listener),
|
|
109
|
-
(
|
|
97
|
+
(listener) => wire.followService(key, scope, null, (event, payload) => {
|
|
110
98
|
if (typeof event === "string")
|
|
111
|
-
|
|
99
|
+
listener(event, payload);
|
|
112
100
|
})
|
|
113
101
|
];
|
|
114
102
|
}
|
|
@@ -116,7 +104,6 @@ function bindEvents(target, events) {
|
|
|
116
104
|
Object.assign(target, {
|
|
117
105
|
subscribe: events.subscribe.bind(events),
|
|
118
106
|
waitFor: events.waitFor.bind(events),
|
|
119
|
-
events: events.events.bind(events)
|
|
120
|
-
observe: events.observe.bind(events)
|
|
107
|
+
events: events.events.bind(events)
|
|
121
108
|
});
|
|
122
109
|
}
|
package/dist/wire.d.ts
CHANGED
|
@@ -32,12 +32,12 @@ declare class Wire {
|
|
|
32
32
|
expectWithin(question: string, deadline: Deadline): Promise<unknown>;
|
|
33
33
|
forget(question: string): void;
|
|
34
34
|
on(route: string, event: string, handler: Handler, subject?: string | null, impossible?: Failure): Cleanup;
|
|
35
|
-
onAll(route: string, handler: Handler, subject?: string | null): Cleanup;
|
|
35
|
+
onAll(route: string, handler: Handler, subject?: string | null, impossible?: Failure): Cleanup;
|
|
36
36
|
observe(target: HandleAddress | null, half: "server" | "client", kind: TrafficKind, event: string | null, handler: Handler, impossible?: Failure): Cleanup;
|
|
37
37
|
/** Follow destinationless events emitted by one Endpoint. */
|
|
38
38
|
follow(target: HandleAddress | null, half: "server" | "client", event: string | null, handler: Handler, impossible?: Failure): Cleanup;
|
|
39
39
|
/** Follow one exact service lifecycle or application event route. */
|
|
40
|
-
followService(key: ServiceKey, scope: "lifecycle" | "
|
|
40
|
+
followService(key: ServiceKey, scope: "lifecycle" | "events", event: string | null, handler: Handler): Cleanup;
|
|
41
41
|
samplePointer(movementX: number, movementY: number): void;
|
|
42
42
|
private register;
|
|
43
43
|
private unregister;
|
package/dist/wire.js
CHANGED
|
@@ -221,11 +221,11 @@ class Wire {
|
|
|
221
221
|
this.unregister(subscription);
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
|
-
onAll(route, handler, subject = null) {
|
|
224
|
+
onAll(route, handler, subject = null, impossible) {
|
|
225
225
|
const handlers = this.every.get(route) ?? new Set();
|
|
226
226
|
handlers.add(handler);
|
|
227
227
|
this.every.set(route, handlers);
|
|
228
|
-
const subscription = this.register("publish", route, null, subject);
|
|
228
|
+
const subscription = this.register("publish", route, null, subject, impossible);
|
|
229
229
|
return once(() => {
|
|
230
230
|
handlers.delete(handler);
|
|
231
231
|
if (!handlers.size)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "The SDK used by a Program's client 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.26"
|
|
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.26",
|
|
57
57
|
"typescript": "^6.0.3"
|
|
58
58
|
}
|
|
59
59
|
}
|
package/dist/channel.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Channel as CoreChannel, ChannelCapture as CoreChannelCapture, ChannelEvents as CoreChannelEvents, ChannelMessage as CoreChannelMessage } from "@phreshos/core";
|
|
2
|
-
import { type Endpoint } from "./domain.js";
|
|
3
|
-
/** One value addressed to the current Client, with a client-visible sender. */
|
|
4
|
-
export type ChannelMessage<Payload = unknown> = CoreChannelMessage<Payload, Endpoint | null>;
|
|
5
|
-
/** Applies the client-visible sender envelope to known Channel events. */
|
|
6
|
-
export type ChannelEvents<Events extends object> = CoreChannelEvents<Events, Endpoint | null>;
|
|
7
|
-
/** Every event observable through the current Client's Channel. */
|
|
8
|
-
export type ChannelCapture<Events extends object = {}> = CoreChannelCapture<Events, Endpoint | null>;
|
|
9
|
-
/** Events explicitly accepted by the current Client. */
|
|
10
|
-
export interface Channel<Events extends object = {}> extends CoreChannel<Events, Endpoint | null> {
|
|
11
|
-
}
|
|
12
|
-
export declare const channel: Channel;
|
package/dist/channel.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { visibleEndpoint } from "./domain.js";
|
|
2
|
-
import Events from "./events.js";
|
|
3
|
-
import wire from "./wire.js";
|
|
4
|
-
import { disableCurrentService, enableCurrentService } from "./service.js";
|
|
5
|
-
class ClientChannel extends Events {
|
|
6
|
-
constructor() {
|
|
7
|
-
super((event, listener, impossible) => wire.on("end-end", event, value => listener(message(value)), null, impossible), observer => wire.onAll("end-end", (event, value) => {
|
|
8
|
-
if (typeof event === "string")
|
|
9
|
-
observer(event, message(value));
|
|
10
|
-
}));
|
|
11
|
-
}
|
|
12
|
-
publish(event, payload = undefined) {
|
|
13
|
-
wire.send("end-host", "emit", event, payload);
|
|
14
|
-
}
|
|
15
|
-
async enableService(name) { await enableCurrentService(name); }
|
|
16
|
-
async disableService() { await disableCurrentService(); }
|
|
17
|
-
}
|
|
18
|
-
function message(value) {
|
|
19
|
-
const raw = value;
|
|
20
|
-
return { from: visibleEndpoint(raw.from), payload: raw.payload };
|
|
21
|
-
}
|
|
22
|
-
export const channel = new ClientChannel();
|
package/dist/current.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { type Channel } from "./channel.js";
|
|
2
|
-
import { Client, Server, type Process, type Program, type Window } from "./domain.js";
|
|
3
|
-
/** The current Process's canonical Server handle. */
|
|
4
|
-
export type CurrentServer<Events extends object = {}> = Server<Events>;
|
|
5
|
-
/** Current Client context: its inbound Channel, owner hierarchy, and paired Server. */
|
|
6
|
-
export interface Current<Events extends object = {}> extends Channel<Events>, Pick<Client, "service"> {
|
|
7
|
-
/** The same Server handle exposed by the current Process. */
|
|
8
|
-
readonly server: CurrentServer;
|
|
9
|
-
/** Presentation capability of this current Client. */
|
|
10
|
-
readonly window: Window;
|
|
11
|
-
/** The same permission capability exposed by the current Program. */
|
|
12
|
-
readonly permission: Program["permission"];
|
|
13
|
-
/** Returns the Process represented by this Client. */
|
|
14
|
-
process(): Promise<Process>;
|
|
15
|
-
/** Returns the accessible parent Process, or `null` when none exists. */
|
|
16
|
-
parent(): Promise<Process | null>;
|
|
17
|
-
/** Returns the Program that owns this Client. */
|
|
18
|
-
program(): Promise<Program>;
|
|
19
|
-
/** Returns one immutable option supplied when this Process was created. */
|
|
20
|
-
option(name: string): Promise<string | undefined>;
|
|
21
|
-
/** Stops the current Client; rejects when it is the final live Endpoint. */
|
|
22
|
-
stop(): Promise<void>;
|
|
23
|
-
}
|
|
24
|
-
/** Inbound events, owner hierarchy, and paired Server for the current Client. */
|
|
25
|
-
export declare const current: Current;
|