@phreshos/client 0.1.4 → 0.1.6
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 +48 -24
- package/dist/current.d.ts +5 -0
- package/dist/current.js +27 -0
- package/dist/desktop.d.ts +20 -0
- package/dist/desktop.js +34 -0
- package/dist/domain.d.ts +5 -8
- package/dist/domain.js +4 -13
- package/dist/host.d.ts +4 -6
- package/dist/host.js +2 -4
- package/dist/main.d.ts +2 -2
- package/dist/main.js +1 -1
- package/dist/permissions.d.ts +3 -1
- package/dist/permissions.js +3 -1
- package/package.json +3 -3
- package/dist/surface.d.ts +0 -29
- package/dist/surface.js +0 -34
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ a peer dependency. It does not redefine those objects, own server-side
|
|
|
18
18
|
capabilities, or contain host and transport implementations.
|
|
19
19
|
|
|
20
20
|
Its `Host` contract exposes only desktop-session capabilities: the public
|
|
21
|
-
system Theme,
|
|
21
|
+
system Theme, desktop and pointer state, publicly served values, and
|
|
22
22
|
unrestricted server-side Fetch. `host.theme.snapshot()` explicitly and
|
|
23
23
|
asynchronously reads the current snapshot retained by the desktop host.
|
|
24
24
|
`host.theme.subscribe("change", listener)` is an ordinary live subscription:
|
|
@@ -26,22 +26,42 @@ it receives only complete replacements published after registration, with no
|
|
|
26
26
|
initial value or replay. The Client cannot write the authoritative value. The
|
|
27
27
|
Host does not expose system-wide Program or Process discovery.
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Desktop and pointer access are independent objects rather than events merged
|
|
30
30
|
into Host:
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
|
-
const
|
|
34
|
-
const
|
|
33
|
+
const desktop = await host.desktop.size()
|
|
34
|
+
const stopDesktop = host.desktop.subscribe("resize", next => undefined)
|
|
35
35
|
|
|
36
36
|
const position = await host.pointer.position()
|
|
37
37
|
const stopPointer = host.pointer.subscribe("move", next => undefined)
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
never enters an endpoint. Pointer position and
|
|
43
|
-
`pointer` permission. Reads are asynchronous
|
|
44
|
-
only future publications and never replay a
|
|
40
|
+
The desktop size is the complete desktop area containing this Client,
|
|
41
|
+
independent of the Client Window's layer. Client code cannot select a layer,
|
|
42
|
+
and the desktop's gutter never enters an endpoint. Pointer position and
|
|
43
|
+
movement both require the `pointer` permission. Reads are asynchronous
|
|
44
|
+
requests; subscriptions receive only future publications and never replay a
|
|
45
|
+
retained value.
|
|
46
|
+
|
|
47
|
+
Permission decisions belong to the current Program, not to the desktop Host.
|
|
48
|
+
They are available from a Program handle and flattened through `current` as the
|
|
49
|
+
same canonical capability:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const program = await current.program()
|
|
53
|
+
|
|
54
|
+
await program.permissions.granted("pointer")
|
|
55
|
+
await current.permissions.request("pointer")
|
|
56
|
+
await current.permissions.timeout(5_000).request("pointer")
|
|
57
|
+
|
|
58
|
+
current.permissions === program.permissions
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`granted()` reads the effective decision without prompting. `request()` asks
|
|
62
|
+
only when no known decision can answer immediately and returns `null` if its
|
|
63
|
+
deadline expires. The desktop remains the internal enforcement boundary, but
|
|
64
|
+
permission ownership does not alter the public shape of `host`.
|
|
45
65
|
|
|
46
66
|
A Client may traverse `Process.parent()` through any number of ancestors in
|
|
47
67
|
its own Program. The first parent outside that Program is structurally hidden
|
|
@@ -108,33 +128,37 @@ The same rule applies to Client-visible traffic destinations.
|
|
|
108
128
|
|
|
109
129
|
Client-visible Program handles can operate only within their own Program.
|
|
110
130
|
They deliberately omit `install()` and `fork()`, and their storage areas never
|
|
111
|
-
expose host filesystem paths.
|
|
112
|
-
`
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
expose host filesystem paths. `current.window` is authoritative and
|
|
132
|
+
subscribable. `current.localWindow` is the physical representation belonging to
|
|
133
|
+
this iframe on this desktop. Its reads and updates are local, have no events,
|
|
134
|
+
and cannot target another Client handle.
|
|
135
|
+
When both dimensions must change, `setGeometry({ position, size })` commits
|
|
136
|
+
them through one authoritative request and produces one `geometry` event.
|
|
137
|
+
Calling `move()` and `resize()` sequentially or through `Promise.all()` remains
|
|
138
|
+
two independent operations and can expose an intermediate state remotely.
|
|
115
139
|
|
|
116
|
-
An `under` or `over`
|
|
117
|
-
The capability is command-only: Program code may change or remove it, but
|
|
118
|
-
cannot read or subscribe to its server-owned state:
|
|
140
|
+
An `under` or `over` representation may request one local host-rendered Surface:
|
|
119
141
|
|
|
120
142
|
```ts
|
|
121
|
-
await
|
|
143
|
+
await current.localWindow.surface.set({
|
|
122
144
|
opacity: 0.65,
|
|
123
|
-
radius: "large"
|
|
124
|
-
|
|
125
|
-
})
|
|
145
|
+
radius: "large"
|
|
146
|
+
}, { duration: 240, easing: "ease-out", wait: true })
|
|
126
147
|
|
|
127
|
-
await
|
|
148
|
+
await current.localWindow.surface.remove()
|
|
128
149
|
```
|
|
129
150
|
|
|
130
|
-
The
|
|
131
|
-
|
|
151
|
+
The desktop holds local state only for the lifetime of that iframe
|
|
152
|
+
representation. Reloading or destroying it resets the representation from
|
|
153
|
+
authoritative truth, while other desktops remain unaffected. Program code may
|
|
154
|
+
synchronize desired settings through its Server and explicitly apply them
|
|
155
|
+
again. `set()` with no settings creates a sharp, fully opaque Surface.
|
|
132
156
|
Opacity is a finite number from `0` through `1`; zero retains the Surface node.
|
|
133
157
|
Radius accepts a nonnegative pixel number, a Theme-derived `ScaleLevel`, or
|
|
134
158
|
`"full"`. Only `remove()` restores exact `null` and immediately removes the
|
|
135
159
|
node. The optional transaction uses milliseconds and a stable named or cubic
|
|
136
160
|
Bézier easing; the desktop performs the motion, honors reduced motion, and does
|
|
137
|
-
does not
|
|
161
|
+
does not restore anything when a new iframe representation begins. The sharp
|
|
138
162
|
container follows the iframe geometry while the independently rounded Surface
|
|
139
163
|
neither clips nor masks Client content. `window` and `wallpaper` layers reject
|
|
140
164
|
the capability.
|
package/dist/current.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LocalWindow } from "@phreshos/core";
|
|
1
2
|
import { type Channel } from "./channel.js";
|
|
2
3
|
import { Client, Server, type Process, type Program, type Window } from "./domain.js";
|
|
3
4
|
/** The current Process's canonical Server handle. */
|
|
@@ -8,6 +9,10 @@ export interface Current<Events extends object = {}> extends Channel<Events>, Pi
|
|
|
8
9
|
readonly server: CurrentServer;
|
|
9
10
|
/** Presentation capability of this current Client. */
|
|
10
11
|
readonly window: Window;
|
|
12
|
+
/** Physical Window representation belonging only to this Client iframe. */
|
|
13
|
+
readonly localWindow: LocalWindow;
|
|
14
|
+
/** The same permission capability exposed by the current Program. */
|
|
15
|
+
readonly permissions: Program["permissions"];
|
|
11
16
|
/** Returns the Process represented by this Client. */
|
|
12
17
|
process(): Promise<Process>;
|
|
13
18
|
/** Returns the accessible parent Process, or `null` when none exists. */
|
package/dist/current.js
CHANGED
|
@@ -3,6 +3,7 @@ import Deadline from "./deadline.js";
|
|
|
3
3
|
import { Client, Server, ServerTrafficHandle, TrafficHandle, bindEvents, endpointEvents, process, program, window as windowHandle } from "./domain.js";
|
|
4
4
|
import wire from "./wire.js";
|
|
5
5
|
import { endpointService } from "./service.js";
|
|
6
|
+
import { currentProgramPermissions } from "./permissions.js";
|
|
6
7
|
const ServerBase = Server;
|
|
7
8
|
const ClientBase = Client;
|
|
8
9
|
class CurrentServerHandle extends ServerBase {
|
|
@@ -83,6 +84,8 @@ currentClient = new CurrentClientHandle(owner);
|
|
|
83
84
|
class ClientCurrent {
|
|
84
85
|
server = currentServer;
|
|
85
86
|
window = currentClient.window;
|
|
87
|
+
localWindow = new LocalWindowHandle();
|
|
88
|
+
permissions = currentProgramPermissions;
|
|
86
89
|
constructor() {
|
|
87
90
|
bindChannel(this, channel);
|
|
88
91
|
}
|
|
@@ -102,6 +105,30 @@ class ClientCurrent {
|
|
|
102
105
|
async stop() { await wire.request(["stop-current"]); }
|
|
103
106
|
service() { return endpointService(null, "client"); }
|
|
104
107
|
}
|
|
108
|
+
class LocalWindowHandle {
|
|
109
|
+
surface = new LocalWindowSurfaceHandle();
|
|
110
|
+
async state() {
|
|
111
|
+
const answer = await wire.request(["localWindow"]);
|
|
112
|
+
return answer[0];
|
|
113
|
+
}
|
|
114
|
+
async title() { return (await this.state()).title; }
|
|
115
|
+
async position() { return (await this.state()).position; }
|
|
116
|
+
async size() { return (await this.state()).size; }
|
|
117
|
+
async minimized() { return (await this.state()).minimized; }
|
|
118
|
+
async front() { return (await this.state()).front; }
|
|
119
|
+
async layer() { return (await this.state()).layer; }
|
|
120
|
+
async location() { return (await this.state()).location; }
|
|
121
|
+
async move(position, transaction) { await wire.request(["localWindowMove", position, transaction]); }
|
|
122
|
+
async resize(size, transaction) { await wire.request(["localWindowResize", size, transaction]); }
|
|
123
|
+
async setGeometry(geometry, transaction) { await wire.request(["localWindowGeometry", geometry, transaction]); }
|
|
124
|
+
async minimize(minimized = true) { await wire.request(["localWindowMinimize", minimized]); }
|
|
125
|
+
async changeTitle(title) { await wire.request(["localWindowTitle", title]); }
|
|
126
|
+
async raise() { await wire.request(["localWindowRaise"]); }
|
|
127
|
+
}
|
|
128
|
+
class LocalWindowSurfaceHandle {
|
|
129
|
+
async set(settings = {}, transaction) { await wire.request(["localWindowSurfaceSet", settings, transaction]); }
|
|
130
|
+
async remove() { await wire.request(["localWindowSurfaceRemove"]); }
|
|
131
|
+
}
|
|
105
132
|
function bindChannel(target, source) {
|
|
106
133
|
Object.assign(target, {
|
|
107
134
|
publish: source.publish.bind(source),
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Size, Subscribable } from "@phreshos/core";
|
|
2
|
+
import Events from "./events.js";
|
|
3
|
+
/** Live changes to the desktop area containing this Client. */
|
|
4
|
+
export type DesktopEvents = {
|
|
5
|
+
/** The desktop area resized. */
|
|
6
|
+
resize: Size;
|
|
7
|
+
};
|
|
8
|
+
/** Explicit desktop size reads and future resizes. */
|
|
9
|
+
export interface HostDesktop extends Subscribable<DesktopEvents, never> {
|
|
10
|
+
/** Reads the complete current desktop area in CSS pixels. */
|
|
11
|
+
size(): Promise<Size>;
|
|
12
|
+
}
|
|
13
|
+
/** Desktop access bound to the current Client Process boundary. */
|
|
14
|
+
export default class ClientDesktop extends Events {
|
|
15
|
+
constructor();
|
|
16
|
+
size(): Promise<Readonly<{
|
|
17
|
+
width: import("@phreshos/core").Value;
|
|
18
|
+
height: import("@phreshos/core").Value;
|
|
19
|
+
}>>;
|
|
20
|
+
}
|
package/dist/desktop.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Events from "./events.js";
|
|
2
|
+
import wire from "./wire.js";
|
|
3
|
+
/** Desktop access bound to the current Client Process boundary. */
|
|
4
|
+
export default class ClientDesktop extends Events {
|
|
5
|
+
constructor() {
|
|
6
|
+
super((event, listener, impossible) => wire.on("host-desktop", event, value => {
|
|
7
|
+
const size = createSize(value);
|
|
8
|
+
if (size)
|
|
9
|
+
listener(size);
|
|
10
|
+
}, null, impossible), observer => wire.onAll("host-desktop", (event, value) => {
|
|
11
|
+
const size = createSize(value);
|
|
12
|
+
if (typeof event === "string" && size)
|
|
13
|
+
observer(event, size);
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
async size() {
|
|
17
|
+
const answer = await wire.request(["desktop"]);
|
|
18
|
+
const size = createSize(answer[0]);
|
|
19
|
+
if (!size)
|
|
20
|
+
throw new Error("The host returned an invalid desktop size");
|
|
21
|
+
return size;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function createSize(value) {
|
|
25
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
26
|
+
return null;
|
|
27
|
+
const size = value;
|
|
28
|
+
if (!finite(size.width) || !finite(size.height))
|
|
29
|
+
return null;
|
|
30
|
+
return Object.freeze({ width: size.width, height: size.height });
|
|
31
|
+
}
|
|
32
|
+
function finite(value) {
|
|
33
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
34
|
+
}
|
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 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
|
|
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 Permissions, type ServerTraffic as CoreServerTraffic, 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;
|
|
@@ -31,6 +31,8 @@ export interface EndpointReference {
|
|
|
31
31
|
export type WindowRecord = WindowState;
|
|
32
32
|
/** Program handle visible inside a structurally isolated Client. */
|
|
33
33
|
export type Program<Events extends object = {}> = Omit<CoreProgram<Events>, "processes" | "firstProcess" | "lastProcess" | "getProcess" | "createProcess"> & {
|
|
34
|
+
/** Effective permission decisions owned by this Program. */
|
|
35
|
+
readonly permissions: Permissions;
|
|
34
36
|
/** Returns every live Process of this Program visible to the current Client. */
|
|
35
37
|
processes(): Promise<Process[]>;
|
|
36
38
|
/** Returns the earliest-started visible live Process, or `null` when none exist. */
|
|
@@ -100,13 +102,8 @@ export type Client<Events extends object = {}> = Omit<CoreClient<Events>, "proce
|
|
|
100
102
|
/** Returns the Process that owns this Client. */
|
|
101
103
|
process(): Promise<Process>;
|
|
102
104
|
};
|
|
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>;
|
|
109
|
-
};
|
|
105
|
+
/** Authoritative Client-owned Window capability visible inside a Client boundary. */
|
|
106
|
+
export type Window = CoreWindow;
|
|
110
107
|
export declare class TrafficHandle extends Events {
|
|
111
108
|
protected readonly target: HandleAddress | null;
|
|
112
109
|
protected readonly kind: "server" | "client";
|
package/dist/domain.js
CHANGED
|
@@ -5,6 +5,7 @@ import HandleRegistry from "./handle-registry.js";
|
|
|
5
5
|
import { area, sql, store } from "./storage.js";
|
|
6
6
|
import wire from "./wire.js";
|
|
7
7
|
import { endpointService } from "./service.js";
|
|
8
|
+
import { currentProgramPermissions } from "./permissions.js";
|
|
8
9
|
const handles = new HandleRegistry();
|
|
9
10
|
const ProgramBase = CoreProgram;
|
|
10
11
|
const ProcessBase = CoreProcess;
|
|
@@ -18,6 +19,7 @@ class ProgramHandle extends ProgramBase {
|
|
|
18
19
|
store = store();
|
|
19
20
|
logs = sql("logs");
|
|
20
21
|
database = sql("database");
|
|
22
|
+
permissions = currentProgramPermissions;
|
|
21
23
|
record;
|
|
22
24
|
constructor(record) {
|
|
23
25
|
super();
|
|
@@ -204,11 +206,9 @@ class ClientHandle extends ClientBase {
|
|
|
204
206
|
}
|
|
205
207
|
class WindowHandle extends Events {
|
|
206
208
|
target;
|
|
207
|
-
surface;
|
|
208
209
|
constructor(target) {
|
|
209
210
|
super(...deferredScoped("host-end", target, (_event, values) => values[0]));
|
|
210
211
|
this.target = target;
|
|
211
|
-
this.surface = new WindowSurfaceHandle(target);
|
|
212
212
|
}
|
|
213
213
|
async state() {
|
|
214
214
|
const answer = await wire.request(["window", await this.target()]);
|
|
@@ -222,21 +222,12 @@ class WindowHandle extends Events {
|
|
|
222
222
|
async layer() { return (await this.state()).layer; }
|
|
223
223
|
async location() { return (await this.state()).location; }
|
|
224
224
|
async move(position) { await wire.request(["move", await this.target(), position]); }
|
|
225
|
-
async localMove(position) { await wire.request(["localMove", await this.target(), position]); }
|
|
226
225
|
async resize(size) { await wire.request(["resize", await this.target(), size]); }
|
|
227
|
-
async
|
|
226
|
+
async setGeometry(geometry) { await wire.request(["setGeometry", await this.target(), geometry]); }
|
|
228
227
|
async minimize(minimized = true) { await wire.request(["minimize", await this.target(), minimized]); }
|
|
229
228
|
async changeTitle(title) { await wire.request(["changeTitle", await this.target(), title]); }
|
|
230
229
|
async raise() { await wire.request(["raise", await this.target()]); }
|
|
231
230
|
}
|
|
232
|
-
class WindowSurfaceHandle {
|
|
233
|
-
target;
|
|
234
|
-
constructor(target) {
|
|
235
|
-
this.target = target;
|
|
236
|
-
}
|
|
237
|
-
async set(settings = {}) { await wire.request(["surfaceSet", await this.target(), settings]); }
|
|
238
|
-
async remove() { await wire.request(["surfaceRemove", await this.target()]); }
|
|
239
|
-
}
|
|
240
231
|
function deferredScoped(route, target, convert) {
|
|
241
232
|
return [
|
|
242
233
|
(event, listener, impossible) => {
|
|
@@ -260,7 +251,7 @@ function deferredScoped(route, target, convert) {
|
|
|
260
251
|
];
|
|
261
252
|
}
|
|
262
253
|
function windowEvent(event) {
|
|
263
|
-
return event === "move" || event === "resize" || event === "minimize" || event === "changeTitle" || event === "front";
|
|
254
|
+
return event === "move" || event === "resize" || event === "geometry" || event === "minimize" || event === "changeTitle" || event === "front";
|
|
264
255
|
}
|
|
265
256
|
function deferred(target, register, impossible) {
|
|
266
257
|
let active = true;
|
package/dist/host.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import type { ClientServiceHandler,
|
|
1
|
+
import type { ClientServiceHandler, ServedFile, ServerServiceHandler, Theme, ThemeProperties } from "@phreshos/core";
|
|
2
2
|
import { type HostPointer } from "./pointer.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type HostDesktop } from "./desktop.js";
|
|
4
4
|
/** Desktop capabilities structurally available to a Client endpoint. */
|
|
5
5
|
export interface Host {
|
|
6
6
|
/** Read-only system Theme explicitly read from and observed through the desktop host. */
|
|
7
7
|
readonly theme: Theme<ThemeProperties>;
|
|
8
|
-
/**
|
|
9
|
-
readonly
|
|
8
|
+
/** Layer-independent desktop size reads and live updates. */
|
|
9
|
+
readonly desktop: HostDesktop;
|
|
10
10
|
/** Permission-guarded desktop pointer reads and live movement. */
|
|
11
11
|
readonly pointer: HostPointer;
|
|
12
|
-
/** Permission decisions for capabilities guarded by the desktop. */
|
|
13
|
-
readonly permissions: Permissions;
|
|
14
12
|
/** Stores one value as a publicly reachable file. */
|
|
15
13
|
serve(value: unknown): Promise<ServedFile>;
|
|
16
14
|
/** Performs an unrestricted server-side fetch on behalf of this Client. */
|
package/dist/host.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { content } from "./content.js";
|
|
2
2
|
import ClientTheme from "./theme.js";
|
|
3
3
|
import wire from "./wire.js";
|
|
4
|
-
import ClientPermissions from "./permissions.js";
|
|
5
4
|
import ClientPointer, {} from "./pointer.js";
|
|
6
|
-
import
|
|
5
|
+
import ClientDesktop, {} from "./desktop.js";
|
|
7
6
|
import { service as serviceHandle } from "./service.js";
|
|
8
7
|
class ClientHost {
|
|
9
8
|
theme = new ClientTheme();
|
|
10
|
-
|
|
9
|
+
desktop = new ClientDesktop();
|
|
11
10
|
pointer = new ClientPointer();
|
|
12
|
-
permissions = new ClientPermissions();
|
|
13
11
|
async serve(value) {
|
|
14
12
|
const source = content(value);
|
|
15
13
|
const channel = new MessageChannel();
|
package/dist/main.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { host, type Host } from "./host.js";
|
|
2
2
|
export { type HostPointer, type PointerEvents, type PointerPosition } from "./pointer.js";
|
|
3
|
-
export { type
|
|
3
|
+
export { type DesktopEvents, type HostDesktop } from "./desktop.js";
|
|
4
4
|
export { current, type Current, type CurrentServer } from "./current.js";
|
|
5
5
|
export { type Channel, type ChannelCapture, type ChannelEvents, type ChannelMessage } from "./channel.js";
|
|
6
6
|
export { ClientServiceHandler, ServerServiceHandler, ServiceHandler, type ClientServiceChannel, type ServerServiceChannel, type ServiceChannel, type ServiceKey, type ServiceLifecycleEvents } from "@phreshos/core";
|
|
7
7
|
export { Client, Endpoint, Process, Program, Server, type Window, type AnswerCapture, type AnswerMessage, type AnswerObserver, type AskCapture, type AskMessage, type AskObserver, type ClientTraffic, type EndpointTraffic, type ServerTraffic, type TrafficCapture, type TrafficEvents, type TrafficMessage } from "./domain.js";
|
|
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, Permissions, Position, ProgramArea, ProgramEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, ServedFile, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TimedPermissions, Timeoutable, Theme, ThemeEvents, ThemeProperties, Value, WritableTheme, WindowEvents, WindowLayer, WindowState,
|
|
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, Permissions, Position, ProgramArea, ProgramEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, ServedFile, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TimedPermissions, Timeoutable, Theme, ThemeEvents, ThemeProperties, Value, WritableTheme, WindowEvents, WindowGeometry, WindowLayer, WindowState, Easing, LocalWindow, LocalWindowSurface, SurfaceSettings, Transaction } from "@phreshos/core";
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { host } from "./host.js";
|
|
2
2
|
export {} from "./pointer.js";
|
|
3
|
-
export {} from "./
|
|
3
|
+
export {} from "./desktop.js";
|
|
4
4
|
export { current } from "./current.js";
|
|
5
5
|
export {} from "./channel.js";
|
|
6
6
|
export { ClientServiceHandler, ServerServiceHandler, ServiceHandler } from "@phreshos/core";
|
package/dist/permissions.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { PermissionDecision, PermissionName, Permissions, TimedPermissions } from "@phreshos/core";
|
|
2
|
-
/** Client
|
|
2
|
+
/** Client access to the current Program's effective permission decisions. */
|
|
3
3
|
export default class ClientPermissions implements Permissions {
|
|
4
4
|
granted(name: PermissionName): Promise<PermissionDecision>;
|
|
5
5
|
request(name: PermissionName): Promise<PermissionDecision>;
|
|
6
6
|
timeout(milliseconds: number): TimedPermissions;
|
|
7
7
|
private requestWithin;
|
|
8
8
|
}
|
|
9
|
+
/** The one Program-owned permission capability visible in this isolated Client. */
|
|
10
|
+
export declare const currentProgramPermissions: ClientPermissions;
|
package/dist/permissions.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import wire from "./wire.js";
|
|
2
2
|
const defaultPermissionTimeout = 30_000;
|
|
3
|
-
/** Client
|
|
3
|
+
/** Client access to the current Program's effective permission decisions. */
|
|
4
4
|
export default class ClientPermissions {
|
|
5
5
|
async granted(name) {
|
|
6
6
|
const answer = await wire.request(["permission-granted", name]);
|
|
@@ -19,3 +19,5 @@ export default class ClientPermissions {
|
|
|
19
19
|
return answer?.[0] ?? null;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
/** The one Program-owned permission capability visible in this isolated Client. */
|
|
23
|
+
export const currentProgramPermissions = new ClientPermissions();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "The SDK used by a Program's client endpoint.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"prepack": "node --run build"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@phreshos/core": "^0.1.
|
|
49
|
+
"@phreshos/core": "^0.1.6"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@phreshos/core": "^0.1.
|
|
52
|
+
"@phreshos/core": "^0.1.6",
|
|
53
53
|
"typescript": "^6.0.3"
|
|
54
54
|
}
|
|
55
55
|
}
|
package/dist/surface.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { Subscribable } from "@phreshos/core";
|
|
2
|
-
import Events from "./events.js";
|
|
3
|
-
/** The available workspace of this Client Window's layer. */
|
|
4
|
-
export type Surface = Readonly<{
|
|
5
|
-
/** Available width in CSS pixels. */
|
|
6
|
-
width: number;
|
|
7
|
-
/** Available height in CSS pixels. */
|
|
8
|
-
height: number;
|
|
9
|
-
}>;
|
|
10
|
-
/** Live changes to this Client Window's surface. */
|
|
11
|
-
export type SurfaceEvents = {
|
|
12
|
-
/** The available workspace resized. */
|
|
13
|
-
resize: Surface;
|
|
14
|
-
};
|
|
15
|
-
/** Explicit surface size reads and future resizes. */
|
|
16
|
-
export interface HostSurface extends Subscribable<SurfaceEvents, never> {
|
|
17
|
-
/** Reads this Client Window's current surface. */
|
|
18
|
-
size(): Promise<Surface>;
|
|
19
|
-
}
|
|
20
|
-
/** Client surface access bound to the current Process boundary. */
|
|
21
|
-
export default class ClientSurface extends Events {
|
|
22
|
-
constructor();
|
|
23
|
-
size(): Promise<Readonly<{
|
|
24
|
-
/** Available width in CSS pixels. */
|
|
25
|
-
width: number;
|
|
26
|
-
/** Available height in CSS pixels. */
|
|
27
|
-
height: number;
|
|
28
|
-
}>>;
|
|
29
|
-
}
|
package/dist/surface.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import Events from "./events.js";
|
|
2
|
-
import wire from "./wire.js";
|
|
3
|
-
/** Client surface access bound to the current Process boundary. */
|
|
4
|
-
export default class ClientSurface extends Events {
|
|
5
|
-
constructor() {
|
|
6
|
-
super((event, listener, impossible) => wire.on("host-surface", event, value => {
|
|
7
|
-
const surface = createSurface(value);
|
|
8
|
-
if (surface)
|
|
9
|
-
listener(surface);
|
|
10
|
-
}, null, impossible), observer => wire.onAll("host-surface", (event, value) => {
|
|
11
|
-
const surface = createSurface(value);
|
|
12
|
-
if (typeof event === "string" && surface)
|
|
13
|
-
observer(event, surface);
|
|
14
|
-
}));
|
|
15
|
-
}
|
|
16
|
-
async size() {
|
|
17
|
-
const answer = await wire.request(["surface"]);
|
|
18
|
-
const surface = createSurface(answer[0]);
|
|
19
|
-
if (!surface)
|
|
20
|
-
throw new Error("The desktop returned an invalid Surface size");
|
|
21
|
-
return surface;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function createSurface(value) {
|
|
25
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
26
|
-
return null;
|
|
27
|
-
const surface = value;
|
|
28
|
-
if (!finite(surface.width) || !finite(surface.height))
|
|
29
|
-
return null;
|
|
30
|
-
return Object.freeze({ width: surface.width, height: surface.height });
|
|
31
|
-
}
|
|
32
|
-
function finite(value) {
|
|
33
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
34
|
-
}
|