@phreshos/client 0.1.0 → 0.1.1
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/LICENSE +19 -0
- package/README.md +101 -13
- package/dist/channel.d.ts +4 -0
- package/dist/channel.js +3 -0
- package/dist/current.d.ts +13 -10
- package/dist/current.js +67 -14
- package/dist/domain.d.ts +83 -30
- package/dist/domain.js +202 -77
- package/dist/handle-registry.d.ts +7 -0
- package/dist/handle-registry.js +24 -0
- package/dist/host.d.ts +15 -20
- package/dist/host.js +10 -35
- package/dist/main.d.ts +5 -3
- package/dist/main.js +3 -1
- package/dist/permissions.d.ts +8 -0
- package/dist/permissions.js +21 -0
- package/dist/pointer.d.ts +35 -0
- package/dist/pointer.js +54 -0
- package/dist/surface.d.ts +29 -0
- package/dist/surface.js +34 -0
- package/dist/theme.d.ts +13 -0
- package/dist/theme.js +29 -0
- package/dist/wire.d.ts +12 -4
- package/dist/wire.js +52 -29
- package/package.json +29 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2026 Zohayr SLILEH
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -17,9 +17,31 @@ It uses the domain objects and shared contracts from `@phreshos/core` through
|
|
|
17
17
|
a peer dependency. It does not redefine those objects, own server-side
|
|
18
18
|
capabilities, or contain host and transport implementations.
|
|
19
19
|
|
|
20
|
-
Its `Host` contract exposes only desktop-session capabilities:
|
|
21
|
-
pointer state, publicly served values, and
|
|
22
|
-
|
|
20
|
+
Its `Host` contract exposes only desktop-session capabilities: the public
|
|
21
|
+
system Theme, surface and pointer state, publicly served values, and
|
|
22
|
+
unrestricted server-side Fetch. `host.theme.snapshot()` explicitly and
|
|
23
|
+
asynchronously reads the current snapshot retained by the desktop host.
|
|
24
|
+
`host.theme.subscribe("change", listener)` is an ordinary live subscription:
|
|
25
|
+
it receives only complete replacements published after registration, with no
|
|
26
|
+
initial value or replay. The Client cannot write the authoritative value. The
|
|
27
|
+
Host does not expose system-wide Program or Process discovery.
|
|
28
|
+
|
|
29
|
+
Surface and pointer access are independent objects rather than events merged
|
|
30
|
+
into Host:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const surface = await host.surface.size()
|
|
34
|
+
const stopSurface = host.surface.subscribe("resize", next => undefined)
|
|
35
|
+
|
|
36
|
+
const position = await host.pointer.position()
|
|
37
|
+
const stopPointer = host.pointer.subscribe("move", next => undefined)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
A Surface contains only the width and height of the current Client Window's
|
|
41
|
+
own layer. Client code cannot select another layer, and the desktop's gutter
|
|
42
|
+
never enters an endpoint. Pointer position and movement both require the
|
|
43
|
+
`pointer` permission. Reads are asynchronous requests; subscriptions receive
|
|
44
|
+
only future publications and never replay a retained value.
|
|
23
45
|
|
|
24
46
|
A Client may traverse `Process.parent()` through any number of ancestors in
|
|
25
47
|
its own Program. The first parent outside that Program is structurally hidden
|
|
@@ -31,28 +53,53 @@ Its JavaScript entry point adapts the iframe boundary to these contracts. The
|
|
|
31
53
|
SDK owns callbacks, waits, queues, and their cleanup; the boundary owns only
|
|
32
54
|
the forwarding registrations requested by the SDK.
|
|
33
55
|
|
|
56
|
+
Importing the SDK and establishing the iframe's host lease inject no message
|
|
57
|
+
into the endpoint. Identity, Theme, Process, Window, readiness, lifecycle, and
|
|
58
|
+
application values enter only in response to an explicit request or a live
|
|
59
|
+
registration made by Program code.
|
|
60
|
+
|
|
34
61
|
`Current` combines navigation into the executing Client's Process with its
|
|
35
|
-
|
|
62
|
+
Channel. The paired Server is explicitly named as
|
|
36
63
|
`current.server`; its publishing, asking, existence, readiness, start, and stop
|
|
37
64
|
operations never masquerade as properties of `current`. `current.stop()` stops
|
|
38
65
|
the executing Client, while complete Process exit remains available only
|
|
39
|
-
through `current.process()`.
|
|
66
|
+
through `current.process()`. It is the canonical Process-owned handle, so
|
|
67
|
+
`current.server === (await current.process()).server`.
|
|
68
|
+
Endpoint `process()` navigation is asynchronous; contextual ownership is
|
|
69
|
+
requested only when navigation needs it and then retained by the SDK.
|
|
70
|
+
|
|
71
|
+
All domain handles are canonical within this iframe's JavaScript realm. Lookup,
|
|
72
|
+
navigation, event payloads, and message metadata reuse the same weakly retained
|
|
73
|
+
handle. A Client and its synchronous `window` capability remain stable for the
|
|
74
|
+
Process lifetime; Window operations always address that Client's current live
|
|
75
|
+
presentation state.
|
|
40
76
|
|
|
41
77
|
`server.ask()` does not route a question before the current Server incarnation
|
|
42
78
|
is ready. The Client SDK owns one deadline across readiness and the answer;
|
|
43
79
|
absence or incarnation loss rejects without turning the boundary into a waiter.
|
|
44
80
|
|
|
45
|
-
The package provides two contextual
|
|
81
|
+
The package provides two contextual runtime entry points:
|
|
46
82
|
|
|
47
83
|
```ts
|
|
48
84
|
import { host, current } from "@phreshos/client"
|
|
49
85
|
```
|
|
50
86
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
87
|
+
It also re-exports the shared Core runtime classes—`Program`, `Process`,
|
|
88
|
+
`Endpoint`, `Server`, and `Client`—and refines the handles returned through
|
|
89
|
+
them. These are the same domain classes used by the Server SDK, so
|
|
90
|
+
`instanceof Server` and `instanceof Client` retain one meaning. `Window`, like
|
|
91
|
+
`ClientTraffic`, is a type-only capability owned by Client and has no
|
|
92
|
+
independent `instanceof` identity.
|
|
93
|
+
|
|
94
|
+
The current Client's Channel is composed directly into `current`. Its
|
|
95
|
+
subscription tools receive events addressed to this Client, while `publish()`
|
|
96
|
+
emits outward from this Client without choosing a destination. Existence,
|
|
97
|
+
readiness, and lifecycle operations belong to `current.server`,
|
|
98
|
+
`current.stop()`, or an explicit Endpoint handle.
|
|
99
|
+
|
|
100
|
+
An Endpoint handle is also a selective source: `endpoint.subscribe()` follows
|
|
101
|
+
destinationless events emitted by that Endpoint. Its `traffic` property remains
|
|
102
|
+
reserved for directed publications, questions, and answers.
|
|
56
103
|
|
|
57
104
|
Messages sent by an Endpoint in the same Program contain that real Endpoint in
|
|
58
105
|
`from`. If the sender belongs to another Program, `from` is `null`; the foreign
|
|
@@ -61,5 +108,46 @@ The same rule applies to Client-visible traffic destinations.
|
|
|
61
108
|
|
|
62
109
|
Client-visible Program handles can operate only within their own Program.
|
|
63
110
|
They deliberately omit `install()` and `fork()`, and their storage areas never
|
|
64
|
-
expose host filesystem paths. Client Window
|
|
65
|
-
`localMove()` and `localResize()` for representation-local gestures.
|
|
111
|
+
expose host filesystem paths. Client Window capabilities add awaitable
|
|
112
|
+
`localMove()` and `localResize()` for representation-local gestures. Their
|
|
113
|
+
Promises confirm that the current Client host accepted and applied the local
|
|
114
|
+
draft; they do not enter server authority or emit Window events.
|
|
115
|
+
|
|
116
|
+
An `under` or `over` Client may own one authoritative host-rendered Surface.
|
|
117
|
+
The capability remains silent until Program code explicitly reads, changes, or
|
|
118
|
+
subscribes to it:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
const initial = await window.surface.snapshot()
|
|
122
|
+
|
|
123
|
+
const stop = window.surface.subscribe("change", surface => {
|
|
124
|
+
// Future replacements only; subscriptions do not replay `initial`.
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
await window.surface.set({
|
|
128
|
+
opacity: 0.65,
|
|
129
|
+
radius: "large",
|
|
130
|
+
transaction: { duration: 240, easing: "ease-out" }
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
await window.surface.remove()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
The server stores the target beside its Window and broadcasts complete future
|
|
137
|
+
replacements. `set()` with no settings creates a sharp, fully opaque Surface.
|
|
138
|
+
Opacity is a finite number from `0` through `1`; zero retains the Surface node.
|
|
139
|
+
Radius accepts a nonnegative pixel number, a Theme-derived `ScaleLevel`, or
|
|
140
|
+
`"full"`. Only `remove()` restores exact `null` and immediately removes the
|
|
141
|
+
node. The optional transaction uses milliseconds and a stable named or cubic
|
|
142
|
+
Bézier easing; the desktop performs the motion, honors reduced motion, and does
|
|
143
|
+
not replay a stored transaction when restoring an initial snapshot. The sharp
|
|
144
|
+
container follows the iframe geometry while the independently rounded Surface
|
|
145
|
+
neither clips nor masks Client content. `window` and `wallpaper` layers reject
|
|
146
|
+
the capability.
|
|
147
|
+
|
|
148
|
+
`program.icon()` requests the current Program's guaranteed PNG `Blob` on
|
|
149
|
+
demand. The desktop derives the Program from the calling frame; no identity,
|
|
150
|
+
private asset address, or filesystem path crosses from Client code.
|
|
151
|
+
|
|
152
|
+
Persistent startup is deliberately absent. Only a Server endpoint may change
|
|
153
|
+
whether an installed Program creates a Process when the system starts.
|
package/dist/channel.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { Channel as CoreChannel, ChannelCapture as CoreChannelCapture, ChannelEvents as CoreChannelEvents, ChannelMessage as CoreChannelMessage } from "@phreshos/core";
|
|
2
2
|
import { type Endpoint } from "./domain.js";
|
|
3
|
+
/** One value addressed to the current Client, with a client-visible sender. */
|
|
3
4
|
export type ChannelMessage<Payload = unknown> = CoreChannelMessage<Payload, Endpoint | null>;
|
|
5
|
+
/** Applies the client-visible sender envelope to known Channel events. */
|
|
4
6
|
export type ChannelEvents<Events extends object> = CoreChannelEvents<Events, Endpoint | null>;
|
|
7
|
+
/** Every event observable through the current Client's Channel. */
|
|
5
8
|
export type ChannelCapture<Events extends object = {}> = CoreChannelCapture<Events, Endpoint | null>;
|
|
9
|
+
/** Events explicitly accepted by the current Client. */
|
|
6
10
|
export interface Channel<Events extends object = {}> extends CoreChannel<Events, Endpoint | null> {
|
|
7
11
|
}
|
|
8
12
|
export declare const channel: Channel;
|
package/dist/channel.js
CHANGED
package/dist/current.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type
|
|
3
|
-
/** The
|
|
4
|
-
export
|
|
5
|
-
exists(): Promise<boolean>;
|
|
6
|
-
start(): Promise<void>;
|
|
7
|
-
stop(): Promise<void>;
|
|
8
|
-
waitReady(timeout?: number): Promise<void>;
|
|
9
|
-
}
|
|
1
|
+
import type { Channel as CoreChannel } from "@phreshos/core";
|
|
2
|
+
import { Server, type Endpoint, 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>;
|
|
10
5
|
/** Current Client context: its inbound Channel, owner hierarchy, and paired Server. */
|
|
11
6
|
export interface Current<Events extends object = {}> extends CoreChannel<Events, Endpoint | null> {
|
|
7
|
+
/** The same Server handle exposed by the current Process. */
|
|
12
8
|
readonly server: CurrentServer;
|
|
9
|
+
/** Presentation capability of this current Client. */
|
|
10
|
+
readonly window: Window;
|
|
11
|
+
/** Returns the Process represented by this Client. */
|
|
13
12
|
process(): Promise<Process>;
|
|
13
|
+
/** Returns the accessible parent Process, or `null` when none exists. */
|
|
14
14
|
parent(): Promise<Process | null>;
|
|
15
|
+
/** Returns the Program that owns this Client. */
|
|
15
16
|
program(): Promise<Program>;
|
|
16
|
-
|
|
17
|
+
/** Returns one immutable option supplied when this Process was created. */
|
|
17
18
|
option(name: string): Promise<string | undefined>;
|
|
19
|
+
/** Stops the current Client; rejects when it is the final live Endpoint. */
|
|
18
20
|
stop(): Promise<void>;
|
|
19
21
|
}
|
|
22
|
+
/** Inbound events, owner hierarchy, and paired Server for the current Client. */
|
|
20
23
|
export declare const current: Current;
|
package/dist/current.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { channel } from "./channel.js";
|
|
2
2
|
import Deadline from "./deadline.js";
|
|
3
|
-
import { process, program } from "./domain.js";
|
|
3
|
+
import { Client, Server, ServerTrafficHandle, TrafficHandle, bindEvents, endpointEvents, process, program, window as windowHandle } from "./domain.js";
|
|
4
4
|
import wire from "./wire.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
const ServerBase = Server;
|
|
6
|
+
const ClientBase = Client;
|
|
7
|
+
class CurrentServerHandle extends ServerBase {
|
|
8
|
+
owner;
|
|
9
|
+
traffic = new ServerTrafficHandle(null, "server");
|
|
10
|
+
constructor(owner) {
|
|
11
|
+
super();
|
|
12
|
+
this.owner = owner;
|
|
13
|
+
bindEvents(this, endpointEvents(null, "server"));
|
|
12
14
|
}
|
|
15
|
+
process() { return this.owner(); }
|
|
16
|
+
publish(event, payload = undefined) { wire.send("end-end", event, payload); }
|
|
13
17
|
async exists() {
|
|
14
18
|
const answer = await wire.request(["exists", "server"]);
|
|
15
19
|
return answer[0];
|
|
@@ -17,21 +21,69 @@ class PairedServer {
|
|
|
17
21
|
async start() { await wire.request(["start-endpoint", undefined, "server"]); }
|
|
18
22
|
async stop() { await wire.request(["stop-endpoint", undefined, "server"]); }
|
|
19
23
|
async waitReady(timeout) { await wire.request(["wait-ready"], timeout); }
|
|
24
|
+
async ask(event, payload = undefined) {
|
|
25
|
+
return this.askWithin(undefined, event, payload);
|
|
26
|
+
}
|
|
27
|
+
timeout(milliseconds) {
|
|
28
|
+
return { ask: (event, payload = undefined) => this.askWithin(milliseconds, event, payload) };
|
|
29
|
+
}
|
|
20
30
|
async askWithin(timeout, event, payload) {
|
|
21
31
|
const deadline = new Deadline(timeout);
|
|
22
32
|
await wire.requestWithin(["wait-ready", null, true], deadline);
|
|
23
33
|
return await wire.askServerWithin(event, payload, deadline);
|
|
24
34
|
}
|
|
25
35
|
}
|
|
36
|
+
let ownerPromise = null;
|
|
37
|
+
let currentServer;
|
|
38
|
+
let currentClient;
|
|
39
|
+
function owner() {
|
|
40
|
+
if (!ownerPromise) {
|
|
41
|
+
const resolving = wire.request(["process"]).then(answer => {
|
|
42
|
+
return process(answer[0], { server: currentServer, client: currentClient });
|
|
43
|
+
});
|
|
44
|
+
const retained = resolving.catch(error => {
|
|
45
|
+
if (ownerPromise === retained)
|
|
46
|
+
ownerPromise = null;
|
|
47
|
+
throw error;
|
|
48
|
+
});
|
|
49
|
+
ownerPromise = retained;
|
|
50
|
+
}
|
|
51
|
+
return ownerPromise;
|
|
52
|
+
}
|
|
53
|
+
currentServer = new CurrentServerHandle(owner);
|
|
54
|
+
class CurrentClientHandle extends ClientBase {
|
|
55
|
+
owner;
|
|
56
|
+
traffic = new TrafficHandle(null, "client");
|
|
57
|
+
window = windowHandle(async () => {
|
|
58
|
+
const identity = await wire.identity();
|
|
59
|
+
return { identity: identity.process, reference: identity.reference };
|
|
60
|
+
});
|
|
61
|
+
constructor(owner) {
|
|
62
|
+
super();
|
|
63
|
+
this.owner = owner;
|
|
64
|
+
bindEvents(this, endpointEvents(null, "client"));
|
|
65
|
+
}
|
|
66
|
+
process() { return this.owner(); }
|
|
67
|
+
publish(event, payload = undefined) {
|
|
68
|
+
void wire.identity().then(identity => {
|
|
69
|
+
wire.send("end-host", "send", { identity: identity.process, reference: identity.reference }, "client", event, payload);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async exists() {
|
|
73
|
+
const answer = await wire.request(["exists", "client"]);
|
|
74
|
+
return answer[0];
|
|
75
|
+
}
|
|
76
|
+
async start(overrides = {}) { await wire.request(["start-endpoint", undefined, "client", overrides]); }
|
|
77
|
+
async stop() { await wire.request(["stop-endpoint", undefined, "client"]); }
|
|
78
|
+
}
|
|
79
|
+
currentClient = new CurrentClientHandle(owner);
|
|
26
80
|
class ClientCurrent {
|
|
27
|
-
server =
|
|
81
|
+
server = currentServer;
|
|
82
|
+
window = currentClient.window;
|
|
28
83
|
constructor() {
|
|
29
84
|
bindChannel(this, channel);
|
|
30
85
|
}
|
|
31
|
-
|
|
32
|
-
const answer = await wire.request(["process"]);
|
|
33
|
-
return process(answer[0]);
|
|
34
|
-
}
|
|
86
|
+
process() { return owner(); }
|
|
35
87
|
async parent() {
|
|
36
88
|
const answer = await wire.request(["parent"]);
|
|
37
89
|
return answer[0] ? process(answer[0]) : null;
|
|
@@ -40,7 +92,6 @@ class ClientCurrent {
|
|
|
40
92
|
const answer = await wire.request(["program"]);
|
|
41
93
|
return program(answer[0]);
|
|
42
94
|
}
|
|
43
|
-
async window() { return (await this.process()).client.window(); }
|
|
44
95
|
async option(name) {
|
|
45
96
|
const answer = await wire.request(["option", undefined, name]);
|
|
46
97
|
return answer[0];
|
|
@@ -49,10 +100,12 @@ class ClientCurrent {
|
|
|
49
100
|
}
|
|
50
101
|
function bindChannel(target, source) {
|
|
51
102
|
Object.assign(target, {
|
|
103
|
+
publish: source.publish.bind(source),
|
|
52
104
|
subscribe: source.subscribe.bind(source),
|
|
53
105
|
waitFor: source.waitFor.bind(source),
|
|
54
106
|
events: source.events.bind(source),
|
|
55
107
|
observe: source.observe.bind(source)
|
|
56
108
|
});
|
|
57
109
|
}
|
|
110
|
+
/** Inbound events, owner hierarchy, and paired Server for the current Client. */
|
|
58
111
|
export const current = new ClientCurrent();
|
package/dist/domain.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { Client as CoreClient, Endpoint as CoreEndpoint, Process as CoreProcess, Program as CoreProgram, Server as CoreServer,
|
|
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 AnswerObserver as CoreAnswerObserver, type AskCapture as CoreAskCapture, type AskMessage as CoreAskMessage, type AskObserver as CoreAskObserver, type Cleanup, type ClientTraffic as CoreClientTraffic, type ClientDeclaration, type EndpointTraffic as CoreEndpointTraffic, type EndpointDeclaration, type Exit, type Launch, type Position, 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
|
+
export interface HandleAddress {
|
|
4
|
+
identity: string;
|
|
5
|
+
reference: string;
|
|
6
|
+
}
|
|
3
7
|
export interface ProgramRecord {
|
|
8
|
+
reference: string;
|
|
4
9
|
identity: string;
|
|
5
10
|
installed?: boolean;
|
|
6
11
|
name: string;
|
|
7
12
|
version: string | null;
|
|
8
13
|
description: string | null;
|
|
9
|
-
icons?: boolean;
|
|
10
14
|
server: EndpointDeclaration | null;
|
|
11
15
|
client: ClientDeclaration | null;
|
|
12
16
|
}
|
|
13
17
|
export interface ProcessRecord {
|
|
18
|
+
reference: string;
|
|
14
19
|
identity: string;
|
|
15
20
|
name: string | null;
|
|
16
21
|
program: ProgramRecord;
|
|
@@ -23,71 +28,119 @@ export interface EndpointReference {
|
|
|
23
28
|
kind: "server" | "client";
|
|
24
29
|
process: ProcessRecord;
|
|
25
30
|
}
|
|
26
|
-
export type
|
|
31
|
+
export type WindowRecord = WindowState;
|
|
32
|
+
/** Program handle visible inside a structurally isolated Client. */
|
|
33
|
+
export type Program<Events extends object = {}> = Omit<CoreProgram<Events>, "processes" | "firstProcess" | "lastProcess" | "getProcess" | "createProcess"> & {
|
|
34
|
+
/** Returns every live Process of this Program visible to the current Client. */
|
|
27
35
|
processes(): Promise<Process[]>;
|
|
36
|
+
/** Returns the earliest-started visible live Process, or `null` when none exist. */
|
|
37
|
+
firstProcess(): Promise<Process | null>;
|
|
38
|
+
/** Returns the latest-started visible live Process, or `null` when none exist. */
|
|
39
|
+
lastProcess(): Promise<Process | null>;
|
|
40
|
+
/** Finds a visible live Process by runtime identity or Program-local name. */
|
|
28
41
|
getProcess(identityOrName: string): Promise<Process | null>;
|
|
42
|
+
/** Creates one Process of this same Program. */
|
|
29
43
|
createProcess(launch?: Launch): Promise<Process>;
|
|
30
44
|
};
|
|
45
|
+
/** Process handle visible inside a structurally isolated Client. */
|
|
31
46
|
export type Process<Events extends object = {}> = Omit<CoreProcess<Events>, "server" | "client" | "program" | "parent"> & {
|
|
47
|
+
/** Permanent handle to this Process's Server. */
|
|
32
48
|
readonly server: Server;
|
|
49
|
+
/** Permanent handle to this Process's Client. */
|
|
33
50
|
readonly client: Client;
|
|
51
|
+
/** Returns the Program that owns this Process. */
|
|
34
52
|
program(): Program;
|
|
53
|
+
/** Returns the visible parent Process, or `null` when no parent is accessible. */
|
|
35
54
|
parent(): Promise<Process | null>;
|
|
36
55
|
};
|
|
56
|
+
/** Traffic value with identities hidden when they cross the Client boundary. */
|
|
37
57
|
export type TrafficMessage<Payload = unknown> = CoreTrafficMessage<Payload, Endpoint | null>;
|
|
58
|
+
/** Applies client-visible destination metadata to known traffic events. */
|
|
38
59
|
export type TrafficEvents<Events extends object> = CoreTrafficEvents<Events, Endpoint | null>;
|
|
60
|
+
/** Every ordinary event observable in client-visible Endpoint traffic. */
|
|
39
61
|
export type TrafficCapture<Events extends object = {}> = CoreTrafficCapture<Events, Endpoint | null>;
|
|
62
|
+
/** Question with a Server destination hidden when it crosses the Client boundary. */
|
|
40
63
|
export type AskMessage<Payload = unknown> = CoreAskMessage<Payload, Server | null>;
|
|
64
|
+
/** One question observable in client-visible Endpoint traffic. */
|
|
41
65
|
export type AskCapture<Payload = unknown> = CoreAskCapture<Payload, Server | null>;
|
|
66
|
+
/** Callback that observes questions sent by a client-visible Endpoint. */
|
|
42
67
|
export type AskObserver<Payload = unknown> = CoreAskObserver<Payload, Server | null>;
|
|
68
|
+
/** Answer with an Endpoint destination hidden when it crosses the Client boundary. */
|
|
43
69
|
export type AnswerMessage<Result = unknown> = CoreAnswerMessage<Result, Endpoint | null>;
|
|
70
|
+
/** One answer observable in client-visible Server traffic. */
|
|
44
71
|
export type AnswerCapture<Result = unknown> = CoreAnswerCapture<Result, Endpoint | null>;
|
|
72
|
+
/** Callback that observes answers sent by a client-visible Server. */
|
|
45
73
|
export type AnswerObserver<Result = unknown> = CoreAnswerObserver<Result, Endpoint | null>;
|
|
74
|
+
/** Directed communication originating from one client-visible Endpoint. */
|
|
46
75
|
export type EndpointTraffic<Events extends object = {}> = CoreEndpointTraffic<Events, Endpoint | null, Server | null>;
|
|
76
|
+
/** Directed communication originating from one client-visible Server. */
|
|
47
77
|
export type ServerTraffic<Events extends object = {}> = CoreServerTraffic<Events, Endpoint | null, Server | null>;
|
|
78
|
+
/** Directed communication originating from one client-visible Client. */
|
|
48
79
|
export type ClientTraffic<Events extends object = {}> = CoreClientTraffic<Events, Endpoint | null, Server | null>;
|
|
80
|
+
/** Common Endpoint handle visible inside a structurally isolated Client. */
|
|
49
81
|
export type Endpoint<Events extends object = {}> = Omit<CoreEndpoint<Events>, "process" | "traffic"> & {
|
|
82
|
+
/** Directed communication originating from this Endpoint. */
|
|
50
83
|
readonly traffic: EndpointTraffic<Events>;
|
|
51
|
-
|
|
84
|
+
/** Returns the Process that owns this Endpoint. */
|
|
85
|
+
process(): Promise<Process>;
|
|
52
86
|
};
|
|
87
|
+
/** Server handle visible inside a structurally isolated Client. */
|
|
53
88
|
export type Server<Events extends object = {}> = Omit<CoreServer<Events>, "process" | "traffic"> & Endpoint<Events> & {
|
|
89
|
+
/** Directed communication originating from this Server. */
|
|
54
90
|
readonly traffic: ServerTraffic<Events>;
|
|
55
|
-
|
|
91
|
+
/** Returns the Process that owns this Server. */
|
|
92
|
+
process(): Promise<Process>;
|
|
56
93
|
};
|
|
94
|
+
/** Client handle visible inside a structurally isolated Client. */
|
|
57
95
|
export type Client<Events extends object = {}> = Omit<CoreClient<Events>, "process" | "traffic" | "window"> & Endpoint<Events> & {
|
|
96
|
+
/** Directed communication originating from this Client. */
|
|
58
97
|
readonly traffic: ClientTraffic<Events>;
|
|
59
|
-
|
|
60
|
-
window
|
|
98
|
+
/** Presentation capability permanently owned by this Client handle. */
|
|
99
|
+
readonly window: Window;
|
|
100
|
+
/** Returns the Process that owns this Client. */
|
|
101
|
+
process(): Promise<Process>;
|
|
61
102
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
103
|
+
/** Client-owned Window capability visible inside a Client boundary. */
|
|
104
|
+
export type Window = CoreWindow & {
|
|
105
|
+
/** Moves this Window representation without changing authoritative state. */
|
|
106
|
+
localMove(position: Position): Promise<void>;
|
|
107
|
+
/** Resizes this Window representation without changing authoritative state. */
|
|
108
|
+
localResize(size: Size): Promise<void>;
|
|
66
109
|
};
|
|
110
|
+
export declare class TrafficHandle extends Events {
|
|
111
|
+
protected readonly target: HandleAddress | null;
|
|
112
|
+
protected readonly kind: "server" | "client";
|
|
113
|
+
constructor(target: HandleAddress | null, kind: "server" | "client");
|
|
114
|
+
observeAsks(observer: (capture: AskCapture) => unknown): Cleanup;
|
|
115
|
+
}
|
|
116
|
+
export declare class ServerTrafficHandle extends TrafficHandle {
|
|
117
|
+
observeAnswers(observer: (capture: AnswerCapture) => unknown): Cleanup;
|
|
118
|
+
}
|
|
119
|
+
type WindowTarget = () => Promise<HandleAddress>;
|
|
67
120
|
export declare function scoped(route: string, subject: string | null, convert: (event: string, values: unknown[]) => unknown): Events;
|
|
121
|
+
/** Destinationless events originating from one Endpoint handle. */
|
|
122
|
+
export declare function endpointEvents(target: HandleAddress | null, half: "server" | "client"): Events;
|
|
68
123
|
export declare function exit(code: unknown, signal: unknown): Exit;
|
|
69
124
|
export declare function trafficMessage(value: unknown): TrafficMessage;
|
|
70
125
|
export declare function bindEvents(target: object, events: Events): void;
|
|
71
126
|
export declare function program(record: ProgramRecord): Program;
|
|
72
|
-
export declare function process(record: ProcessRecord
|
|
127
|
+
export declare function process(record: ProcessRecord, endpoints?: {
|
|
128
|
+
server?: Server;
|
|
129
|
+
client?: Client;
|
|
130
|
+
}): Process;
|
|
73
131
|
export declare function endpoint(reference: EndpointReference | undefined): Endpoint;
|
|
132
|
+
export declare function claimEndpoint(reference: string, kind: "server" | "client", endpoint: Endpoint): Endpoint<{}>;
|
|
133
|
+
export declare function window(target: WindowTarget): Window;
|
|
74
134
|
/** Resolves only endpoint identities intentionally visible to this Client. */
|
|
75
135
|
export declare function visibleEndpoint(reference: EndpointReference | null | undefined): Endpoint | null;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
export declare const Process:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
export declare const
|
|
86
|
-
|
|
87
|
-
};
|
|
88
|
-
export declare const Client: {
|
|
89
|
-
new <Events extends object = {}>(): Client<Events>;
|
|
90
|
-
};
|
|
91
|
-
export declare const Window: {
|
|
92
|
-
new <Events extends object = {}>(): Window<Events>;
|
|
93
|
-
};
|
|
136
|
+
/** Runtime constructor shared by all client-visible Program handles. */
|
|
137
|
+
export declare const Program: typeof CoreProgram;
|
|
138
|
+
/** Runtime constructor shared by all client-visible Process handles. */
|
|
139
|
+
export declare const Process: typeof CoreProcess;
|
|
140
|
+
/** Runtime constructor shared by all client-visible Endpoint handles. */
|
|
141
|
+
export declare const Endpoint: typeof CoreEndpoint;
|
|
142
|
+
/** Runtime constructor shared by all client-visible Server handles. */
|
|
143
|
+
export declare const Server: typeof CoreServer;
|
|
144
|
+
/** Runtime constructor shared by all client-visible Client handles. */
|
|
145
|
+
export declare const Client: typeof CoreClient;
|
|
146
|
+
export {};
|