@phreshos/client 0.1.12 → 0.1.13

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 CHANGED
@@ -51,11 +51,11 @@ same canonical capability:
51
51
  ```ts
52
52
  const program = await current.program()
53
53
 
54
- await program.permissions.granted("pointer")
55
- await current.permissions.request("pointer")
56
- await current.permissions.timeout(5_000).request("pointer")
54
+ await program.permission.granted("pointer")
55
+ await current.permission.request("pointer")
56
+ await current.permission.timeout(5_000).request("pointer")
57
57
 
58
- current.permissions === program.permissions
58
+ current.permission === program.permission
59
59
  ```
60
60
 
61
61
  `granted()` reads the effective decision without prompting. `request()` asks
@@ -63,6 +63,20 @@ only when no known decision can answer immediately and returns `null` if its
63
63
  deadline expires. The desktop remains the internal enforcement boundary, but
64
64
  permission ownership does not alter the public shape of `host`.
65
65
 
66
+ The Client Host exposes service preparation as its only service-registry
67
+ capability. Preparing a handle does not read or start the service:
68
+
69
+ ```ts
70
+ const service = host.service.prepare({
71
+ program: "counter",
72
+ endpoint: "server",
73
+ name: "state"
74
+ })
75
+
76
+ await service.waitReady()
77
+ if (await service.enabled()) await service.channel.ask("value")
78
+ ```
79
+
66
80
  A Client may traverse `Process.parent()` through any number of ancestors in
67
81
  its own Program. The first parent outside that Program is structurally hidden
68
82
  and returned as `null`; no cross-Program Process handle enters the client. If
package/dist/current.d.ts CHANGED
@@ -9,7 +9,7 @@ export interface Current<Events extends object = {}> extends Channel<Events>, Pi
9
9
  /** Presentation capability of this current Client. */
10
10
  readonly window: Window;
11
11
  /** The same permission capability exposed by the current Program. */
12
- readonly permissions: Program["permissions"];
12
+ readonly permission: Program["permission"];
13
13
  /** Returns the Process represented by this Client. */
14
14
  process(): Promise<Process>;
15
15
  /** Returns the accessible parent Process, or `null` when none exists. */
package/dist/current.js CHANGED
@@ -3,7 +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
+ import { currentProgramPermission } from "./permissions.js";
7
7
  const ServerBase = Server;
8
8
  const ClientBase = Client;
9
9
  class CurrentServerHandle extends ServerBase {
@@ -41,7 +41,7 @@ let currentServer;
41
41
  let currentClient;
42
42
  function owner() {
43
43
  if (!ownerPromise) {
44
- const resolving = wire.request(["process"]).then(answer => {
44
+ const resolving = wire.request(["current-process"]).then(answer => {
45
45
  return process(answer[0], { server: currentServer, client: currentClient });
46
46
  });
47
47
  const retained = resolving.catch(error => {
@@ -84,7 +84,7 @@ currentClient = new CurrentClientHandle(owner);
84
84
  class ClientCurrent {
85
85
  server = currentServer;
86
86
  window = currentClient.window;
87
- permissions = currentProgramPermissions;
87
+ permission = currentProgramPermission;
88
88
  constructor() {
89
89
  bindChannel(this, channel);
90
90
  }
@@ -94,7 +94,7 @@ class ClientCurrent {
94
94
  return answer[0] ? process(answer[0]) : null;
95
95
  }
96
96
  async program() {
97
- const answer = await wire.request(["program"]);
97
+ const answer = await wire.request(["current-program"]);
98
98
  return program(answer[0]);
99
99
  }
100
100
  async option(name) {
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 LocalWindow, 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";
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 LocalWindow, type Permission, type ProgramProcess as CoreProgramProcess, 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;
@@ -30,19 +30,24 @@ export interface EndpointReference {
30
30
  }
31
31
  export type WindowRecord = WindowState;
32
32
  /** Program handle visible inside a structurally isolated Client. */
33
- export type Program<Events extends object = {}> = Omit<CoreProgram<Events>, "processes" | "firstProcess" | "lastProcess" | "getProcess" | "createProcess"> & {
33
+ export type Program<Events extends object = {}> = Omit<CoreProgram<Events>, "process"> & {
34
34
  /** Effective permission decisions owned by this Program. */
35
- readonly permissions: Permissions;
35
+ readonly permission: Permission;
36
+ /** Operations and lifecycle observation for this Program's Processes. */
37
+ readonly process: ProgramProcess;
38
+ };
39
+ /** Client-visible Process operations scoped to one Program. */
40
+ export type ProgramProcess = Omit<CoreProgramProcess, "list" | "first" | "last" | "find" | "create"> & {
36
41
  /** Returns every live Process of this Program visible to the current Client. */
37
- processes(): Promise<Process[]>;
42
+ list(): Promise<Process[]>;
38
43
  /** Returns the earliest-started visible live Process, or `null` when none exist. */
39
- firstProcess(): Promise<Process | null>;
44
+ first(): Promise<Process | null>;
40
45
  /** Returns the latest-started visible live Process, or `null` when none exist. */
41
- lastProcess(): Promise<Process | null>;
46
+ last(): Promise<Process | null>;
42
47
  /** Finds a visible live Process by runtime identity or Program-local name. */
43
- getProcess(identityOrName: string): Promise<Process | null>;
48
+ find(identityOrName: string): Promise<Process | null>;
44
49
  /** Creates one Process of this same Program. */
45
- createProcess(launch?: Launch): Promise<Process>;
50
+ create(launch?: Launch): Promise<Process>;
46
51
  };
47
52
  /** Process handle visible inside a structurally isolated Client. */
48
53
  export type Process<Events extends object = {}> = Omit<CoreProcess<Events>, "server" | "client" | "program" | "parent"> & {
package/dist/domain.js CHANGED
@@ -5,7 +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
+ import { currentProgramPermission } from "./permissions.js";
9
9
  const handles = new HandleRegistry();
10
10
  const ProgramBase = CoreProgram;
11
11
  const ProcessBase = CoreProcess;
@@ -19,14 +19,16 @@ class ProgramHandle extends ProgramBase {
19
19
  store = store();
20
20
  logs = sql("logs");
21
21
  database = sql("database");
22
- permissions = currentProgramPermissions;
22
+ permission = currentProgramPermission;
23
+ process;
23
24
  record;
24
25
  constructor(record) {
25
26
  super();
26
27
  this.identity = record.identity;
27
28
  this.reference = record.reference;
28
29
  this.record = record;
29
- bindEvents(this, scoped("host-end", record.reference, programEvent));
30
+ this.process = new ProgramProcessHandle(record.reference);
31
+ bindEvents(this, scoped("program-host", record.reference, programEvent));
30
32
  }
31
33
  get name() { return this.record.name; }
32
34
  get version() { return this.record.version; }
@@ -38,24 +40,6 @@ class ProgramHandle extends ProgramBase {
38
40
  throw new Error("A Program handle cannot become another Program");
39
41
  this.record = record;
40
42
  }
41
- async processes() {
42
- const answer = await wire.request(["processes"]);
43
- return answer[0].map(record => process(record));
44
- }
45
- async firstProcess() {
46
- return chronological(await this.processes())[0] ?? null;
47
- }
48
- async lastProcess() {
49
- return chronological(await this.processes()).at(-1) ?? null;
50
- }
51
- async getProcess(identityOrName) {
52
- const answer = await wire.request(["program-process", undefined, identityOrName]);
53
- return answer[0] ? process(answer[0]) : null;
54
- }
55
- async createProcess(launch = {}) {
56
- const answer = await wire.request(["create-process", undefined, launch]);
57
- return process(answer[0]);
58
- }
59
43
  async icon(size = "medium") {
60
44
  const answer = await wire.request(["icon", size]);
61
45
  return new Blob([Uint8Array.from(answer[0])], { type: "image/png" });
@@ -66,8 +50,31 @@ class ProgramHandle extends ProgramBase {
66
50
  }
67
51
  async uninstall(everything = false) { await wire.request(["uninstall", undefined, everything]); }
68
52
  async forget() { await wire.request(["forget"]); }
53
+ }
54
+ class ProgramProcessHandle {
55
+ constructor(program) {
56
+ bindEvents(this, scoped("program-process", program, programProcessEvent));
57
+ }
58
+ async list() {
59
+ const answer = await wire.request(["program-process-list"]);
60
+ return answer[0].map(record => process(record));
61
+ }
62
+ async first() {
63
+ return chronological(await this.list())[0] ?? null;
64
+ }
65
+ async last() {
66
+ return chronological(await this.list()).at(-1) ?? null;
67
+ }
68
+ async find(identityOrName) {
69
+ const answer = await wire.request(["program-process-find", identityOrName]);
70
+ return answer[0] ? process(answer[0]) : null;
71
+ }
72
+ async create(launch = {}) {
73
+ const answer = await wire.request(["program-process-create", launch]);
74
+ return process(answer[0]);
75
+ }
69
76
  async exitAll() {
70
- const answer = await wire.request(["exit-all"]);
77
+ const answer = await wire.request(["program-process-exit-all"]);
71
78
  return answer[0];
72
79
  }
73
80
  }
@@ -333,13 +340,16 @@ function unscoped(subject, values) {
333
340
  return values;
334
341
  return values[0] === subject ? values.slice(1) : null;
335
342
  }
336
- function programEvent(event, values) {
343
+ function programProcessEvent(event, values) {
337
344
  if (event === "endpointStart" || event === "endpointStop")
338
345
  return lifecycleEndpoint(values[0], values[1]);
339
- if (event === "processCreate")
346
+ if (event === "create")
340
347
  return process(values[0]);
341
- if (event === "processExit")
348
+ if (event === "exit")
342
349
  return { process: process(values[0]), ...exit(values[1], values[2]) };
350
+ return undefined;
351
+ }
352
+ function programEvent(event, values) {
343
353
  if (event === "uninstall")
344
354
  return { everythingRemoved: values[0] === true };
345
355
  return undefined;
package/dist/host.d.ts CHANGED
@@ -1,6 +1,11 @@
1
- import type { ClientServiceHandler, ServedFile, ServerServiceHandler, Theme, ThemeProperties } from "@phreshos/core";
1
+ import type { ClientServiceHandler, ServedFile, ServerServiceHandler, ServiceKey, Theme, ThemeProperties } from "@phreshos/core";
2
2
  import { type HostPointer } from "./pointer.js";
3
3
  import { type HostDesktop } from "./desktop.js";
4
+ type ServiceEndpoint = ServiceKey["endpoint"];
5
+ type ServiceAddress<Endpoint extends ServiceEndpoint> = Omit<ServiceKey, "endpoint"> & Readonly<{
6
+ endpoint: Endpoint;
7
+ }>;
8
+ type ServiceHandle<Endpoint extends ServiceEndpoint, Events extends object> = Endpoint extends "server" ? ServerServiceHandler<Events> : ClientServiceHandler<Events>;
4
9
  /** Desktop capabilities structurally available to a Client endpoint. */
5
10
  export interface Host {
6
11
  /** Read-only system Theme explicitly read from and observed through the desktop host. */
@@ -13,14 +18,21 @@ export interface Host {
13
18
  serve(value: unknown): Promise<ServedFile>;
14
19
  /** Performs an unrestricted server-side fetch on behalf of this Client. */
15
20
  fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
21
+ /** Prepares exact public service handles without exposing the service registry. */
22
+ readonly service: HostService;
23
+ }
24
+ /** Exact public service preparation available to a Client endpoint. */
25
+ export interface HostService {
26
+ /** Returns a precisely typed stable handle for either service endpoint. */
27
+ prepare<Endpoint extends ServiceEndpoint, ServiceEvents extends object = {}>(key: ServiceAddress<Endpoint>): ServiceHandle<Endpoint, ServiceEvents>;
16
28
  /** Returns a stable handle for one exact Server service identity. */
17
- service<ServiceEvents extends object = {}>(key: {
29
+ prepare<ServiceEvents extends object = {}>(key: {
18
30
  program: string;
19
31
  endpoint: "server";
20
32
  name: string;
21
33
  }): ServerServiceHandler<ServiceEvents>;
22
34
  /** Returns a stable handle for one exact Client service identity. */
23
- service<ServiceEvents extends object = {}>(key: {
35
+ prepare<ServiceEvents extends object = {}>(key: {
24
36
  program: string;
25
37
  endpoint: "client";
26
38
  name: string;
@@ -28,3 +40,4 @@ export interface Host {
28
40
  }
29
41
  /** Desktop capabilities available to this Client. */
30
42
  export declare const host: Host;
43
+ export {};
package/dist/host.js CHANGED
@@ -3,11 +3,12 @@ import ClientTheme from "./theme.js";
3
3
  import wire from "./wire.js";
4
4
  import ClientPointer, {} from "./pointer.js";
5
5
  import ClientDesktop, {} from "./desktop.js";
6
- import { service as serviceHandle } from "./service.js";
6
+ import { prepareService } from "./service.js";
7
7
  class ClientHost {
8
8
  theme = new ClientTheme();
9
9
  desktop = new ClientDesktop();
10
10
  pointer = new ClientPointer();
11
+ service = new ClientHostService();
11
12
  async serve(value) {
12
13
  const source = content(value);
13
14
  const channel = new MessageChannel();
@@ -78,8 +79,10 @@ class ClientHost {
78
79
  });
79
80
  return response;
80
81
  }
81
- service(key) {
82
- return serviceHandle(key);
82
+ }
83
+ class ClientHostService {
84
+ prepare(key) {
85
+ return prepareService(key);
83
86
  }
84
87
  }
85
88
  function requestHeaders(normalized, supplied) {
package/dist/main.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { host, type Host } from "./host.js";
1
+ export { host, type Host, type HostService } from "./host.js";
2
2
  export { type HostPointer, type PointerEvents, type PointerPosition } from "./pointer.js";
3
3
  export { type DesktopEvents, type DesktopSize, 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
- 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, WindowGeometry, WindowLayer, WindowState, Easing, LocalWindow, LocalWindowSurface, SurfaceSettings, Transaction } from "@phreshos/core";
7
+ export { Client, Endpoint, Process, Program, Server, type Window, type ProgramProcess, 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, Permission, Position, ProgramArea, ProgramEvents, ProgramProcessEvents, ProgramProcessExit, ProgramSql, ProgramStore, ProcessEvents, Publishable, ServedFile, Size, Subscribable, SubscribableEvents, SubscribableFallback, TimedAskable, TimedPermission, Timeoutable, Theme, ThemeEvents, ThemeProperties, Value, WritableTheme, WindowEvents, WindowGeometry, WindowLayer, WindowState, Easing, LocalWindow, LocalWindowSurface, SurfaceSettings, Transaction } from "@phreshos/core";
@@ -1,10 +1,10 @@
1
- import type { PermissionDecision, PermissionName, Permissions, TimedPermissions } from "@phreshos/core";
1
+ import type { Permission, PermissionDecision, PermissionName, TimedPermission } from "@phreshos/core";
2
2
  /** Client access to the current Program's effective permission decisions. */
3
- export default class ClientPermissions implements Permissions {
3
+ export default class ClientPermission implements Permission {
4
4
  granted(name: PermissionName): Promise<PermissionDecision>;
5
5
  request(name: PermissionName): Promise<PermissionDecision>;
6
- timeout(milliseconds: number): TimedPermissions;
6
+ timeout(milliseconds: number): TimedPermission;
7
7
  private requestWithin;
8
8
  }
9
9
  /** The one Program-owned permission capability visible in this isolated Client. */
10
- export declare const currentProgramPermissions: ClientPermissions;
10
+ export declare const currentProgramPermission: ClientPermission;
@@ -1,7 +1,7 @@
1
1
  import wire from "./wire.js";
2
2
  const defaultPermissionTimeout = 30_000;
3
3
  /** Client access to the current Program's effective permission decisions. */
4
- export default class ClientPermissions {
4
+ export default class ClientPermission {
5
5
  async granted(name) {
6
6
  const answer = await wire.request(["permission-granted", name]);
7
7
  return answer[0];
@@ -20,4 +20,4 @@ export default class ClientPermissions {
20
20
  }
21
21
  }
22
22
  /** The one Program-owned permission capability visible in this isolated Client. */
23
- export const currentProgramPermissions = new ClientPermissions();
23
+ export const currentProgramPermission = new ClientPermission();
package/dist/service.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { type ClientServiceHandler, type ServerServiceHandler, type ServiceDefinition, type ServiceHandler, type ServiceKey } from "@phreshos/core";
2
2
  import type { HandleAddress } from "./domain.js";
3
- export declare function service<EventsMap extends object = {}>(key: ServiceKey & {
3
+ export declare function prepareService<EventsMap extends object = {}>(key: ServiceKey & {
4
4
  endpoint: "server";
5
5
  }): ServerServiceHandler<EventsMap>;
6
- export declare function service<EventsMap extends object = {}>(key: ServiceKey & {
6
+ export declare function prepareService<EventsMap extends object = {}>(key: ServiceKey & {
7
7
  endpoint: "client";
8
8
  }): ClientServiceHandler<EventsMap>;
9
- export declare function service(key: ServiceKey): ServiceHandler;
9
+ export declare function prepareService(key: ServiceKey): ServiceHandler;
10
10
  export declare function enableCurrentService(definition: ServiceDefinition): Promise<void>;
11
11
  export declare function disableCurrentService(): Promise<void>;
12
12
  export declare function endpointService<EventsMap extends object = {}>(target: HandleAddress | null, endpoint: "server"): Promise<ServerServiceHandler<EventsMap> | null>;
package/dist/service.js CHANGED
@@ -46,22 +46,22 @@ class ClientChannelHandle extends Events {
46
46
  }
47
47
  class ServerHandler extends ServerServiceBase {
48
48
  key;
49
- program;
50
- endpoint = "server";
51
49
  name;
52
50
  channel;
53
51
  constructor(key) {
54
52
  super();
55
53
  this.key = key;
56
- this.program = key.program;
57
54
  this.name = key.name;
58
55
  this.channel = new ServerChannelHandle(key);
59
56
  bindEvents(this, new Events(...serviceEvents(key, "lifecycle")));
60
57
  }
61
- async disabled() {
62
- const answer = await wire.request(["service-disabled", this.key]);
58
+ async enabled() {
59
+ const answer = await wire.request(["service-enabled", this.key]);
63
60
  return answer[0];
64
61
  }
62
+ async waitReady(timeout) {
63
+ await wire.request(["service-wait-ready", this.key, timeout], timeout);
64
+ }
65
65
  async docs() {
66
66
  const answer = await wire.request(["service-docs", this.key]);
67
67
  return answer[0];
@@ -69,24 +69,24 @@ class ServerHandler extends ServerServiceBase {
69
69
  }
70
70
  class ClientHandler extends ClientServiceBase {
71
71
  key;
72
- program;
73
- endpoint = "client";
74
72
  name;
75
73
  channel;
76
74
  constructor(key) {
77
75
  super();
78
76
  this.key = key;
79
- this.program = key.program;
80
77
  this.name = key.name;
81
78
  this.channel = new ClientChannelHandle(key);
82
79
  bindEvents(this, new Events(...serviceEvents(key, "lifecycle")));
83
80
  }
84
- async disabled() {
85
- const answer = await wire.request(["service-disabled", this.key]);
81
+ async enabled() {
82
+ const answer = await wire.request(["service-enabled", this.key]);
86
83
  return answer[0];
87
84
  }
85
+ async waitReady(timeout) {
86
+ await wire.request(["service-wait-ready", this.key, timeout], timeout);
87
+ }
88
88
  }
89
- export function service(key) {
89
+ export function prepareService(key) {
90
90
  if (!isServiceKey(key))
91
91
  throw new Error("A complete service key is required");
92
92
  const normalized = Object.freeze({ program: key.program, endpoint: key.endpoint, name: key.name });
@@ -105,7 +105,7 @@ export async function disableCurrentService() {
105
105
  }
106
106
  export async function endpointService(target, endpoint) {
107
107
  const answer = await wire.request(["endpoint-service", target, endpoint]);
108
- return answer[0] ? service(answer[0]) : null;
108
+ return answer[0] ? prepareService(answer[0]) : null;
109
109
  }
110
110
  function serviceEvents(key, scope) {
111
111
  return [
package/dist/theme.js CHANGED
@@ -5,28 +5,14 @@ import wire from "./wire.js";
5
5
  export default class ClientTheme extends Events {
6
6
  constructor() {
7
7
  super((event, listener, impossible) => wire.on("host-theme", event, value => {
8
- if (isObject(value))
9
- listener(createThemeSnapshot(value));
8
+ listener(createThemeSnapshot(value));
10
9
  }, null, impossible), observer => wire.onAll("host-theme", (event, value) => {
11
- if (typeof event === "string" && isObject(value))
10
+ if (typeof event === "string")
12
11
  observer(event, createThemeSnapshot(value));
13
12
  }));
14
13
  }
15
14
  async snapshot() {
16
- const answer = await wire.request(["theme"]);
17
- if (!isObject(answer[0]))
18
- throw new Error("The desktop returned an invalid Theme snapshot");
19
- return createThemeSnapshot(answer[0]);
15
+ const [theme] = await wire.request(["theme"]);
16
+ return createThemeSnapshot(theme);
20
17
  }
21
18
  }
22
- function isObject(value) {
23
- if (typeof value !== "object" || value === null || Array.isArray(value))
24
- return false;
25
- const theme = value;
26
- const surface = theme.surface;
27
- return typeof theme.background === "string" && typeof theme.foreground === "string" && typeof theme.accent === "string"
28
- && typeof theme.spacing === "number" && typeof theme.radius === "number"
29
- && typeof surface === "object" && surface !== null
30
- && typeof surface.grain === "number" && typeof surface.animation === "number"
31
- && typeof surface.backdrop === "number" && typeof surface.opacity === "number";
32
- }
package/dist/wire.js CHANGED
@@ -62,7 +62,7 @@ class Wire {
62
62
  /** Resolves this endpoint's Process address only for operations that need it. */
63
63
  identity() {
64
64
  if (!this.identityPromise) {
65
- const resolving = this.request(["process"]).then(value => {
65
+ const resolving = this.request(["current-process"]).then(value => {
66
66
  const [record] = value;
67
67
  if (typeof record?.identity !== "string" || typeof record.reference !== "string") {
68
68
  throw new Error("The desktop returned an invalid Process identity");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/client",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "The SDK used by a Program's client endpoint.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -41,18 +41,19 @@
41
41
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
42
42
  "check": "tsc --noEmit",
43
43
  "build": "node --run clean && tsc --noEmit false --outDir dist --rootDir source",
44
+ "verify:completions": "node scripts/verify-completions.mjs",
44
45
  "verify:package": "node scripts/verify-package.mjs",
45
- "verify": "node --run check && node --run build && node --run verify:package",
46
+ "verify": "node --run check && node --run verify:completions && node --run build && node --run verify:package",
46
47
  "prepack": "node --run build"
47
48
  },
48
49
  "peerDependencies": {
49
- "@phreshos/core": "^0.1.8"
50
+ "@phreshos/core": "^0.1.9"
50
51
  },
51
52
  "dependencies": {
52
53
  "@msgpack/msgpack": "^3.1.3"
53
54
  },
54
55
  "devDependencies": {
55
- "@phreshos/core": "^0.1.8",
56
+ "@phreshos/core": "^0.1.9",
56
57
  "typescript": "^6.0.3"
57
58
  }
58
59
  }