@phreshos/react 0.1.32 → 0.1.33

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.
@@ -12,6 +12,8 @@ export default function ContextProvider({ children, context, fallback }: Context
12
12
  export declare function useContext(): ClientContext;
13
13
  /** Read the current Context when present; explicit-handle hooks also work without it. */
14
14
  export declare function useProvidedContext(): ClientContext | null;
15
+ /** Resolve the current Program without requiring a provider for explicit-handle hooks. */
16
+ export declare function useProvidedProgram(): Program | undefined;
15
17
  /** Returns the current Program once it resolves. */
16
18
  export declare function useProgram<Handle extends Program = Program>(): Handle;
17
19
  /** Returns the current Process once it resolves. */
@@ -22,6 +22,13 @@ export function useContext() {
22
22
  export function useProvidedContext() {
23
23
  return useReactContext(CurrentContext)?.context ?? null;
24
24
  }
25
+ /** Resolve the current Program without requiring a provider for explicit-handle hooks. */
26
+ export function useProvidedProgram() {
27
+ const value = useReactContext(CurrentContext);
28
+ return useSyncExternalStore(value?.program.subscribe ?? noSubscribe, value?.program.snapshot ?? noProgram, value?.program.snapshot ?? noProgram);
29
+ }
30
+ function noSubscribe() { return () => undefined; }
31
+ function noProgram() { return undefined; }
25
32
  /** Returns the current Program once it resolves. */
26
33
  export function useProgram() {
27
34
  return useResolved(useValue().program);
package/dist/main.d.ts CHANGED
@@ -10,5 +10,6 @@ export { default as useEndpointState, type EndpointState } from "./use-endpoint-
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
12
  export { default as useClientMemory } from "./use-client-memory.js";
13
+ export { default as useProgramStore } from "./use-program-store.js";
13
14
  export { default as useSubscribeAsks, type AskSubscribable } from "./use-subscribe-asks.js";
14
15
  export { default as useSubscribeAnswers, type AnswerSubscribable } from "./use-subscribe-answers.js";
package/dist/main.js CHANGED
@@ -10,5 +10,6 @@ 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
12
  export { default as useClientMemory } from "./use-client-memory.js";
13
+ export { default as useProgramStore } from "./use-program-store.js";
13
14
  export { default as useSubscribeAsks } from "./use-subscribe-asks.js";
14
15
  export { default as useSubscribeAnswers } from "./use-subscribe-answers.js";
@@ -0,0 +1,7 @@
1
+ import type { ProgramStore } from "@phreshos/core";
2
+ type Widen<Value> = Value extends string ? string : Value extends number ? number : Value extends boolean ? boolean : Value;
3
+ type StoreResult<Value> = readonly [Value | undefined, (next: Value | ((current: Value | undefined) => Value)) => Promise<void>];
4
+ /** Follows one Program-owned persistent value and seeds it only when absent. */
5
+ export default function useProgramStore<Value>(key: string, initial: Value): StoreResult<Widen<Value>>;
6
+ export default function useProgramStore<Value>(store: ProgramStore, key: string, initial: Value): StoreResult<Widen<Value>>;
7
+ export {};
@@ -0,0 +1,21 @@
1
+ import { useCallback, useMemo, useSyncExternalStore } from "react";
2
+ import { useProvidedProgram } from "./context-provider.js";
3
+ import LiveState from "./live-state.js";
4
+ export default function useProgramStore(storeOrKey, keyOrInitial, explicitInitial) {
5
+ const program = useProvidedProgram();
6
+ const store = typeof storeOrKey === "string" ? program?.store : storeOrKey;
7
+ if (!store)
8
+ throw new Error("useProgramStore(key, initial) requires ContextProvider");
9
+ const key = typeof storeOrKey === "string" ? storeOrKey : keyOrInitial;
10
+ const initial = typeof storeOrKey === "string" ? keyOrInitial : explicitInitial;
11
+ // A stored undefined value still occupies a key; only the System can test absence atomically.
12
+ const state = useMemo(() => new LiveState(async () => ({ value: await store.getOrSet(key, initial) }), reduce => store.subscribe(key, value => reduce(() => ({ value })))), [store, key]);
13
+ const snapshot = useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
14
+ const set = useCallback(async (next) => {
15
+ if (typeof next === "function")
16
+ await store.update(key, next);
17
+ else
18
+ await store.set(key, next);
19
+ }, [store, key]);
20
+ return [snapshot?.value, set];
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phreshos/react",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
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.62",
49
+ "@phreshos/core": "^0.1.63",
50
50
  "react": "^19.2.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@phreshos/core": "^0.1.62",
53
+ "@phreshos/core": "^0.1.63",
54
54
  "@testing-library/dom": "^10.4.1",
55
55
  "@testing-library/react": "^16.3.0",
56
56
  "@types/react": "^19.2.18",