@phreshos/react 0.1.28 → 0.1.30

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/dist/main.d.ts CHANGED
@@ -9,5 +9,6 @@ export { default as useSessionState, type SessionState } from "./use-session-sta
9
9
  export { default as useEndpointState, type EndpointState } from "./use-endpoint-state.js";
10
10
  export { default as useServiceState, type ServiceState } from "./use-service-state.js";
11
11
  export { default as useWindowState } from "./use-window-state.js";
12
+ export { default as useWindowPresentationState } from "./use-window-presentation-state.js";
12
13
  export { default as useSubscribeAsks, type AskSubscribable } from "./use-subscribe-asks.js";
13
14
  export { default as useSubscribeAnswers, type AnswerSubscribable } from "./use-subscribe-answers.js";
package/dist/main.js CHANGED
@@ -9,5 +9,6 @@ export { default as useSessionState } from "./use-session-state.js";
9
9
  export { default as useEndpointState } from "./use-endpoint-state.js";
10
10
  export { default as useServiceState } from "./use-service-state.js";
11
11
  export { default as useWindowState } from "./use-window-state.js";
12
+ export { default as useWindowPresentationState } from "./use-window-presentation-state.js";
12
13
  export { default as useSubscribeAsks } from "./use-subscribe-asks.js";
13
14
  export { default as useSubscribeAnswers } from "./use-subscribe-answers.js";
@@ -1,6 +1,6 @@
1
1
  import type { Endpoint } from "@phreshos/core";
2
2
  export type EndpointState = Readonly<{
3
- exists: boolean;
3
+ running: boolean;
4
4
  }>;
5
5
  /** Explicitly reads and follows one Endpoint address while mounted. */
6
6
  export default function useEndpointState(endpoint: Endpoint): EndpointState | undefined;
@@ -2,9 +2,9 @@ import { useMemo, useSyncExternalStore } from "react";
2
2
  import LiveState, { combineCleanups } from "./live-state.js";
3
3
  /** Explicitly reads and follows one Endpoint address while mounted. */
4
4
  export default function useEndpointState(endpoint) {
5
- const state = useMemo(() => new LiveState(async () => ({ exists: await endpoint.exists() }), reduce => combineCleanups(endpoint.lifecycle.subscribe("start", () => reduce(current => setExists(current, true))), endpoint.lifecycle.subscribe("stop", () => reduce(current => setExists(current, false))))), [endpoint]);
5
+ const state = useMemo(() => new LiveState(async () => ({ running: await endpoint.running() }), reduce => combineCleanups(endpoint.lifecycle.subscribe("start", () => reduce(current => setRunning(current, true))), endpoint.lifecycle.subscribe("stop", () => reduce(current => setRunning(current, false))))), [endpoint]);
6
6
  return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
7
7
  }
8
- function setExists(state, exists) {
9
- return state.exists === exists ? state : { exists };
8
+ function setRunning(state, running) {
9
+ return state.running === running ? state : { running };
10
10
  }
@@ -2,6 +2,7 @@ import type { Process, Program } from "@phreshos/core";
2
2
  /** Mutable runtime state derived from one Program's reads and live events. */
3
3
  export type ProgramState = Readonly<{
4
4
  installed: boolean;
5
+ pinned: boolean;
5
6
  processes: readonly Process[];
6
7
  }>;
7
8
  /** Explicitly reads and follows one Program while this hook is mounted. */
@@ -3,12 +3,13 @@ import LiveState, { combineCleanups } from "./live-state.js";
3
3
  /** Explicitly reads and follows one Program while this hook is mounted. */
4
4
  export default function useProgramState(program) {
5
5
  const state = useMemo(() => new LiveState(async () => {
6
- const [installed, processes] = await Promise.all([
6
+ const [installed, pinned, processes] = await Promise.all([
7
7
  program.installed(),
8
+ program.pinned(),
8
9
  program.processes()
9
10
  ]);
10
- return { installed, processes };
11
- }, reduce => combineCleanups(program.subscribe("processCreate", process => reduce(current => addProcess(current, process))), program.subscribe("processExit", ({ process }) => reduce(current => removeProcess(current, process))), program.subscribe("uninstall", () => reduce(current => current.installed ? { ...current, installed: false } : current)))), [program]);
11
+ return { installed, pinned, processes };
12
+ }, reduce => combineCleanups(program.subscribe("processCreate", process => reduce(current => addProcess(current, process))), program.subscribe("processExit", ({ process }) => reduce(current => removeProcess(current, process))), program.subscribe("uninstall", () => reduce(current => current.installed ? { ...current, installed: false } : current)), program.subscribe("pinned", pinned => reduce(current => current.pinned === pinned ? current : { ...current, pinned })))), [program]);
12
13
  return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
13
14
  }
14
15
  function addProcess(state, process) {
@@ -1,7 +1,7 @@
1
1
  import type { Service } from "@phreshos/core";
2
- /** Live existence of one configured Endpoint service. */
2
+ /** Live availability of one stable Service address. */
3
3
  export type ServiceState = Readonly<{
4
- exists: boolean;
4
+ available: boolean;
5
5
  }>;
6
6
  /** Explicitly reads and follows one service while this hook is mounted. */
7
7
  export default function useServiceState(service: Service): ServiceState | undefined;
@@ -2,9 +2,9 @@ import { useMemo, useSyncExternalStore } from "react";
2
2
  import LiveState, { combineCleanups } from "./live-state.js";
3
3
  /** Explicitly reads and follows one service while this hook is mounted. */
4
4
  export default function useServiceState(service) {
5
- const state = useMemo(() => new LiveState(async () => ({ exists: await service.exists() }), reduce => combineCleanups(service.lifecycle.subscribe("start", () => reduce(current => setExists(current, true))), service.lifecycle.subscribe("stop", () => reduce(current => setExists(current, false))))), [service]);
5
+ const state = useMemo(() => new LiveState(async () => ({ available: await service.available() }), reduce => combineCleanups(service.lifecycle.subscribe("available", () => reduce(current => setAvailable(current, true))), service.lifecycle.subscribe("unavailable", () => reduce(current => setAvailable(current, false))))), [service]);
6
6
  return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
7
7
  }
8
- function setExists(state, exists) {
9
- return state.exists === exists ? state : { exists };
8
+ function setAvailable(state, available) {
9
+ return state.available === available ? state : { available };
10
10
  }
@@ -0,0 +1,3 @@
1
+ import type { WindowPresentation, WindowPresentationState } from "@phreshos/core";
2
+ /** Reads and follows the values one Desktop relies on to represent a Window. */
3
+ export default function useWindowPresentationState(presentation: WindowPresentation): WindowPresentationState | undefined;
@@ -0,0 +1,30 @@
1
+ import { useMemo, useSyncExternalStore } from "react";
2
+ import LiveState, { combineCleanups } from "./live-state.js";
3
+ /** Reads and follows the values one Desktop relies on to represent a Window. */
4
+ export default function useWindowPresentationState(presentation) {
5
+ const state = useMemo(() => new LiveState(() => readPresentation(presentation), reduce => combineCleanups(presentation.subscribe("move", position => reduce(current => change(current, "position", position))), presentation.subscribe("resize", size => reduce(current => change(current, "size", size))), presentation.subscribe("minimize", minimized => reduce(current => change(current, "minimized", minimized))), presentation.subscribe("maximize", maximized => reduce(current => change(current, "maximized", maximized))), presentation.subscribe("changeTitle", title => reduce(current => change(current, "title", title))), presentation.subscribe("changeHeader", header => reduce(current => change(current, "header", header))), presentation.subscribe("changeSurface", surface => reduce(current => change(current, "surface", surface))), presentation.subscribe("front", front => reduce(current => change(current, "front", front))))), [presentation]);
6
+ return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
7
+ }
8
+ async function readPresentation(presentation) {
9
+ const layer = await presentation.layer();
10
+ if (layer === "wallpaper")
11
+ return { layer };
12
+ const [surface, position, size, minimized, maximized, front] = await Promise.all([
13
+ presentation.surface(),
14
+ presentation.position(),
15
+ presentation.size(),
16
+ presentation.minimized(),
17
+ presentation.maximized(),
18
+ presentation.front()
19
+ ]);
20
+ if (layer === "under" || layer === "over" || layer === "shell") {
21
+ return { layer, surface, position, size, minimized, maximized, front };
22
+ }
23
+ const [title, header] = await Promise.all([presentation.title(), presentation.header()]);
24
+ return { layer, title, header, surface, position, size, minimized, maximized, front };
25
+ }
26
+ function change(state, property, value) {
27
+ if (!(property in state))
28
+ return state;
29
+ return { ...state, [property]: value };
30
+ }
@@ -3,9 +3,11 @@ import LiveState, { combineCleanups } from "./live-state.js";
3
3
  /** Explicitly reads and follows one live Client Window while mounted. */
4
4
  export default function useWindowState(window) {
5
5
  const state = useMemo(() => new LiveState(async () => {
6
- const [title, header, position, size, minimized, maximized, front, layer] = await Promise.all([
6
+ const [title, header, surface, transaction, position, size, minimized, maximized, front, layer] = await Promise.all([
7
7
  window.title(),
8
8
  window.header(),
9
+ window.surface(),
10
+ window.transaction(),
9
11
  window.position(),
10
12
  window.size(),
11
13
  window.minimized(),
@@ -13,7 +15,7 @@ export default function useWindowState(window) {
13
15
  window.front(),
14
16
  window.layer()
15
17
  ]);
16
- return { title, header, position, size, minimized, maximized, front, layer };
17
- }, reduce => combineCleanups(window.subscribe("move", position => reduce(current => ({ ...current, position }))), window.subscribe("resize", size => reduce(current => ({ ...current, size }))), window.subscribe("minimize", minimized => reduce(current => ({ ...current, minimized }))), window.subscribe("maximize", maximized => reduce(current => ({ ...current, maximized }))), window.subscribe("changeTitle", title => reduce(current => ({ ...current, title }))), window.subscribe("changeHeader", header => reduce(current => ({ ...current, header }))), window.subscribe("front", front => reduce(current => ({ ...current, front }))))), [window]);
18
+ return { title, header, surface, transaction, position, size, minimized, maximized, front, layer };
19
+ }, reduce => combineCleanups(window.subscribe("move", position => reduce(current => ({ ...current, position }))), window.subscribe("resize", size => reduce(current => ({ ...current, size }))), window.subscribe("minimize", minimized => reduce(current => ({ ...current, minimized }))), window.subscribe("maximize", maximized => reduce(current => ({ ...current, maximized }))), window.subscribe("changeTitle", title => reduce(current => ({ ...current, title }))), window.subscribe("changeHeader", header => reduce(current => ({ ...current, header }))), window.subscribe("changeSurface", surface => reduce(current => ({ ...current, surface }))), window.subscribe("changeTransaction", transaction => reduce(current => ({ ...current, transaction }))), window.subscribe("front", front => reduce(current => ({ ...current, front }))))), [window]);
18
20
  return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
19
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/react",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "Runtime-neutral React adapters for PhreshOS contracts.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -46,11 +46,11 @@
46
46
  "prepack": "node --run build"
47
47
  },
48
48
  "peerDependencies": {
49
- "@phreshos/core": "^0.1.53",
49
+ "@phreshos/core": "^0.1.58",
50
50
  "react": "^19.2.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@phreshos/core": "^0.1.53",
53
+ "@phreshos/core": "^0.1.58",
54
54
  "@testing-library/dom": "^10.4.1",
55
55
  "@testing-library/react": "^16.3.0",
56
56
  "@types/react": "^19.2.18",