@phreshos/react 0.1.1 → 0.1.3

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
@@ -24,9 +24,10 @@ It provides two kinds of adapter:
24
24
  `usePointerPosition()` expose those values synchronously after resolution.
25
25
  - `useSubscribe()` and `useObserve()` own persistent ordinary-event
26
26
  registrations for one mounted React consumer.
27
- - `useProgramState(program)`, `useProcessState(process)`, and
28
- `useWindowState(window)` explicitly compose existing reads with future live
29
- events for one mounted consumer. They add no state operation to another SDK.
27
+ - `useProgramState(program)`, `useProcessState(process)`,
28
+ `useServiceState(service)`, and `useWindowState(window)` explicitly compose
29
+ existing reads with future live events for one mounted consumer. They add no
30
+ state operation to another SDK.
30
31
  - `useObserveAsks()` adapts an Endpoint traffic surface's question observation,
31
32
  while `useObserveAnswers()` adapts a Server traffic surface's answer
32
33
  observation.
@@ -48,10 +49,17 @@ useProgramState(program)
48
49
  useProcessState(process)
49
50
  // { exited, serverExists, clientExists } | undefined
50
51
 
52
+ useServiceState(service)
53
+ // { disabled } | undefined
54
+
51
55
  useWindowState(window)
52
56
  // WindowState | undefined
53
57
  ```
54
58
 
59
+ `WindowState` contains the observable Window properties only. The command-only
60
+ `window.surface` capability is intentionally absent: Program code may replace
61
+ or remove its target but cannot read or subscribe to it.
62
+
55
63
  `undefined` means only that the initial explicit reads are pending. Each hook
56
64
  opens its live subscriptions before those reads, then applies any intervening
57
65
  events so an older result cannot overwrite newer state. If an initial read
package/dist/main.d.ts CHANGED
@@ -6,6 +6,7 @@ export { default as useScale } from "./use-scale.js";
6
6
  export { default as useColor } from "./use-color.js";
7
7
  export { default as useProgramState, type ProgramState } from "./use-program-state.js";
8
8
  export { default as useProcessState, type ProcessState } from "./use-process-state.js";
9
+ export { default as useServiceState, type ServiceState } from "./use-service-state.js";
9
10
  export { default as useWindowState } from "./use-window-state.js";
10
11
  export { default as useObserveAsks, type AskObservable } from "./use-observe-asks.js";
11
12
  export { default as useObserveAnswers, type AnswerObservable } from "./use-observe-answers.js";
package/dist/main.js CHANGED
@@ -6,6 +6,7 @@ export { default as useScale } from "./use-scale.js";
6
6
  export { default as useColor } from "./use-color.js";
7
7
  export { default as useProgramState } from "./use-program-state.js";
8
8
  export { default as useProcessState } from "./use-process-state.js";
9
+ export { default as useServiceState } from "./use-service-state.js";
9
10
  export { default as useWindowState } from "./use-window-state.js";
10
11
  export { default as useObserveAsks } from "./use-observe-asks.js";
11
12
  export { default as useObserveAnswers } from "./use-observe-answers.js";
@@ -0,0 +1,7 @@
1
+ import type { ServiceHandler } from "@phreshos/client";
2
+ /** Live availability of one exact service identity. */
3
+ export type ServiceState = Readonly<{
4
+ disabled: boolean;
5
+ }>;
6
+ /** Explicitly reads and follows one service while this hook is mounted. */
7
+ export default function useServiceState(service: ServiceHandler): ServiceState | undefined;
@@ -0,0 +1,10 @@
1
+ import { useMemo, useSyncExternalStore } from "react";
2
+ import LiveState, { combineCleanups } from "./live-state.js";
3
+ /** Explicitly reads and follows one service while this hook is mounted. */
4
+ export default function useServiceState(service) {
5
+ const state = useMemo(() => new LiveState(async () => ({ disabled: await service.disabled() }), reduce => combineCleanups(service.subscribe("enable", () => reduce(current => setDisabled(current, false))), service.subscribe("disable", () => reduce(current => setDisabled(current, true))))), [service]);
6
+ return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
7
+ }
8
+ function setDisabled(state, disabled) {
9
+ return state.disabled === disabled ? state : { disabled };
10
+ }
@@ -3,17 +3,16 @@ 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, position, size, minimized, front, layer, location, surface] = await Promise.all([
6
+ const [title, position, size, minimized, front, layer, location] = await Promise.all([
7
7
  window.title(),
8
8
  window.position(),
9
9
  window.size(),
10
10
  window.minimized(),
11
11
  window.front(),
12
12
  window.layer(),
13
- window.location(),
14
- window.surface.snapshot()
13
+ window.location()
15
14
  ]);
16
- return { title, position, size, minimized, front, layer, location, surface };
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("changeTitle", title => reduce(current => ({ ...current, title }))), window.subscribe("front", front => reduce(current => ({ ...current, front }))), window.surface.subscribe("change", surface => reduce(current => ({ ...current, surface }))))), [window]);
15
+ return { title, position, size, minimized, front, layer, location };
16
+ }, 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("changeTitle", title => reduce(current => ({ ...current, title }))), window.subscribe("front", front => reduce(current => ({ ...current, front }))))), [window]);
18
17
  return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
19
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/react",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "React adapters for the Client SDK.",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",
@@ -47,13 +47,13 @@
47
47
  "prepack": "node --run test && node --run build"
48
48
  },
49
49
  "peerDependencies": {
50
- "@phreshos/client": "^0.1.1",
51
- "@phreshos/core": "^0.1.1",
50
+ "@phreshos/client": "^0.1.3",
51
+ "@phreshos/core": "^0.1.3",
52
52
  "react": "^19.2.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@phreshos/client": "^0.1.1",
56
- "@phreshos/core": "^0.1.1",
55
+ "@phreshos/client": "^0.1.3",
56
+ "@phreshos/core": "^0.1.3",
57
57
  "@testing-library/react": "^16.3.0",
58
58
  "@types/react": "^19.2.18",
59
59
  "@types/react-dom": "^19.2.4",