@phreshos/client 0.1.4 → 0.1.5
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 +34 -6
- package/dist/current.d.ts +2 -0
- package/dist/current.js +2 -0
- package/dist/domain.d.ts +12 -1
- package/dist/domain.js +6 -3
- package/dist/host.d.ts +1 -3
- package/dist/host.js +0 -2
- package/dist/main.d.ts +2 -2
- package/dist/permissions.d.ts +3 -1
- package/dist/permissions.js +3 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -43,6 +43,25 @@ never enters an endpoint. Pointer position and movement both require the
|
|
|
43
43
|
`pointer` permission. Reads are asynchronous requests; subscriptions receive
|
|
44
44
|
only future publications and never replay a retained value.
|
|
45
45
|
|
|
46
|
+
Permission decisions belong to the current Program, not to the desktop Host.
|
|
47
|
+
They are available from a Program handle and flattened through `current` as the
|
|
48
|
+
same canonical capability:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
const program = await current.program()
|
|
52
|
+
|
|
53
|
+
await program.permissions.granted("pointer")
|
|
54
|
+
await current.permissions.request("pointer")
|
|
55
|
+
await current.permissions.timeout(5_000).request("pointer")
|
|
56
|
+
|
|
57
|
+
current.permissions === program.permissions
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`granted()` reads the effective decision without prompting. `request()` asks
|
|
61
|
+
only when no known decision can answer immediately and returns `null` if its
|
|
62
|
+
deadline expires. The desktop remains the internal enforcement boundary, but
|
|
63
|
+
permission ownership does not alter the public shape of `host`.
|
|
64
|
+
|
|
46
65
|
A Client may traverse `Process.parent()` through any number of ancestors in
|
|
47
66
|
its own Program. The first parent outside that Program is structurally hidden
|
|
48
67
|
and returned as `null`; no cross-Program Process handle enters the client. If
|
|
@@ -112,10 +131,15 @@ expose host filesystem paths. Client Window capabilities add awaitable
|
|
|
112
131
|
`localMove()` and `localResize()` for representation-local gestures. Their
|
|
113
132
|
Promises confirm that the current Client host accepted and applied the local
|
|
114
133
|
draft; they do not enter server authority or emit Window events.
|
|
134
|
+
When both dimensions must change, `setGeometry({ position, size })` commits
|
|
135
|
+
them through one authoritative request and produces one `geometry` event.
|
|
136
|
+
Calling `move()` and `resize()` sequentially or through `Promise.all()` remains
|
|
137
|
+
two independent operations and can expose an intermediate state remotely.
|
|
115
138
|
|
|
116
|
-
An `under` or `over`
|
|
117
|
-
The capability
|
|
118
|
-
|
|
139
|
+
An `under` or `over` Window representation may request one local host-rendered
|
|
140
|
+
Surface. The capability follows the same desktop-local targeting model as
|
|
141
|
+
`localMove()` and `localResize()`; it is command-only and has no server-owned
|
|
142
|
+
state:
|
|
119
143
|
|
|
120
144
|
```ts
|
|
121
145
|
await window.surface.set({
|
|
@@ -127,14 +151,18 @@ await window.surface.set({
|
|
|
127
151
|
await window.surface.remove()
|
|
128
152
|
```
|
|
129
153
|
|
|
130
|
-
The
|
|
131
|
-
|
|
154
|
+
The desktop holds the target only for the lifetime of the addressed iframe.
|
|
155
|
+
Reloading or destroying that representation removes it; another accessible
|
|
156
|
+
Window handle may tailor the same local representation, while other desktops
|
|
157
|
+
remain unaffected. Program code may synchronize desired settings through its
|
|
158
|
+
Server and explicitly apply them again. `set()` with no settings creates a
|
|
159
|
+
sharp, fully opaque Surface.
|
|
132
160
|
Opacity is a finite number from `0` through `1`; zero retains the Surface node.
|
|
133
161
|
Radius accepts a nonnegative pixel number, a Theme-derived `ScaleLevel`, or
|
|
134
162
|
`"full"`. Only `remove()` restores exact `null` and immediately removes the
|
|
135
163
|
node. The optional transaction uses milliseconds and a stable named or cubic
|
|
136
164
|
Bézier easing; the desktop performs the motion, honors reduced motion, and does
|
|
137
|
-
does not
|
|
165
|
+
does not restore anything when a new iframe representation begins. The sharp
|
|
138
166
|
container follows the iframe geometry while the independently rounded Surface
|
|
139
167
|
neither clips nor masks Client content. `window` and `wallpaper` layers reject
|
|
140
168
|
the capability.
|
package/dist/current.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface Current<Events extends object = {}> extends Channel<Events>, Pi
|
|
|
8
8
|
readonly server: CurrentServer;
|
|
9
9
|
/** Presentation capability of this current Client. */
|
|
10
10
|
readonly window: Window;
|
|
11
|
+
/** The same permission capability exposed by the current Program. */
|
|
12
|
+
readonly permissions: Program["permissions"];
|
|
11
13
|
/** Returns the Process represented by this Client. */
|
|
12
14
|
process(): Promise<Process>;
|
|
13
15
|
/** 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,7 @@ currentClient = new CurrentClientHandle(owner);
|
|
|
83
84
|
class ClientCurrent {
|
|
84
85
|
server = currentServer;
|
|
85
86
|
window = currentClient.window;
|
|
87
|
+
permissions = currentProgramPermissions;
|
|
86
88
|
constructor() {
|
|
87
89
|
bindChannel(this, channel);
|
|
88
90
|
}
|
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 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";
|
|
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 ClientSurfaceSettings, type ClientTraffic as CoreClientTraffic, type ClientDeclaration, type EndpointTraffic as CoreEndpointTraffic, type EndpointDeclaration, type Exit, type Launch, type Permissions, 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
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. */
|
|
@@ -102,11 +104,20 @@ export type Client<Events extends object = {}> = Omit<CoreClient<Events>, "proce
|
|
|
102
104
|
};
|
|
103
105
|
/** Client-owned Window capability visible inside a Client boundary. */
|
|
104
106
|
export type Window = CoreWindow & {
|
|
107
|
+
/** Host-rendered material belonging only to this desktop representation. */
|
|
108
|
+
readonly surface: ClientWindowSurface;
|
|
105
109
|
/** Moves this Window representation without changing authoritative state. */
|
|
106
110
|
localMove(position: Position): Promise<void>;
|
|
107
111
|
/** Resizes this Window representation without changing authoritative state. */
|
|
108
112
|
localResize(size: Size): Promise<void>;
|
|
109
113
|
};
|
|
114
|
+
/** Command-only Surface of one Window representation on this desktop. */
|
|
115
|
+
export interface ClientWindowSurface {
|
|
116
|
+
/** Creates or replaces the representation-local Surface. */
|
|
117
|
+
set(settings?: ClientSurfaceSettings): Promise<void>;
|
|
118
|
+
/** Immediately removes the representation-local Surface. */
|
|
119
|
+
remove(): Promise<void>;
|
|
120
|
+
}
|
|
110
121
|
export declare class TrafficHandle extends Events {
|
|
111
122
|
protected readonly target: HandleAddress | null;
|
|
112
123
|
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();
|
|
@@ -208,7 +210,7 @@ class WindowHandle extends Events {
|
|
|
208
210
|
constructor(target) {
|
|
209
211
|
super(...deferredScoped("host-end", target, (_event, values) => values[0]));
|
|
210
212
|
this.target = target;
|
|
211
|
-
this.surface = new
|
|
213
|
+
this.surface = new ClientWindowSurfaceHandle(target);
|
|
212
214
|
}
|
|
213
215
|
async state() {
|
|
214
216
|
const answer = await wire.request(["window", await this.target()]);
|
|
@@ -224,12 +226,13 @@ class WindowHandle extends Events {
|
|
|
224
226
|
async move(position) { await wire.request(["move", await this.target(), position]); }
|
|
225
227
|
async localMove(position) { await wire.request(["localMove", await this.target(), position]); }
|
|
226
228
|
async resize(size) { await wire.request(["resize", await this.target(), size]); }
|
|
229
|
+
async setGeometry(geometry) { await wire.request(["setGeometry", await this.target(), geometry]); }
|
|
227
230
|
async localResize(size) { await wire.request(["localResize", await this.target(), size]); }
|
|
228
231
|
async minimize(minimized = true) { await wire.request(["minimize", await this.target(), minimized]); }
|
|
229
232
|
async changeTitle(title) { await wire.request(["changeTitle", await this.target(), title]); }
|
|
230
233
|
async raise() { await wire.request(["raise", await this.target()]); }
|
|
231
234
|
}
|
|
232
|
-
class
|
|
235
|
+
class ClientWindowSurfaceHandle {
|
|
233
236
|
target;
|
|
234
237
|
constructor(target) {
|
|
235
238
|
this.target = target;
|
|
@@ -260,7 +263,7 @@ function deferredScoped(route, target, convert) {
|
|
|
260
263
|
];
|
|
261
264
|
}
|
|
262
265
|
function windowEvent(event) {
|
|
263
|
-
return event === "move" || event === "resize" || event === "minimize" || event === "changeTitle" || event === "front";
|
|
266
|
+
return event === "move" || event === "resize" || event === "geometry" || event === "minimize" || event === "changeTitle" || event === "front";
|
|
264
267
|
}
|
|
265
268
|
function deferred(target, register, impossible) {
|
|
266
269
|
let active = true;
|
package/dist/host.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClientServiceHandler,
|
|
1
|
+
import type { ClientServiceHandler, ServedFile, ServerServiceHandler, Theme, ThemeProperties } from "@phreshos/core";
|
|
2
2
|
import { type HostPointer } from "./pointer.js";
|
|
3
3
|
import { type HostSurface } from "./surface.js";
|
|
4
4
|
/** Desktop capabilities structurally available to a Client endpoint. */
|
|
@@ -9,8 +9,6 @@ export interface Host {
|
|
|
9
9
|
readonly surface: HostSurface;
|
|
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,7 +1,6 @@
|
|
|
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
5
|
import ClientSurface, {} from "./surface.js";
|
|
7
6
|
import { service as serviceHandle } from "./service.js";
|
|
@@ -9,7 +8,6 @@ class ClientHost {
|
|
|
9
8
|
theme = new ClientTheme();
|
|
10
9
|
surface = new ClientSurface();
|
|
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
|
@@ -4,5 +4,5 @@ export { type HostSurface, type Surface, type SurfaceEvents } from "./surface.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
|
-
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,
|
|
7
|
+
export { Client, Endpoint, Process, Program, Server, type ClientWindowSurface, 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, WindowGeometry, WindowLayer, WindowState, ClientSurfaceEasing, ClientSurfaceSettings, ClientSurfaceTransaction } 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.5",
|
|
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.5"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@phreshos/core": "^0.1.
|
|
52
|
+
"@phreshos/core": "^0.1.5",
|
|
53
53
|
"typescript": "^6.0.3"
|
|
54
54
|
}
|
|
55
55
|
}
|