@phreshos/react 0.1.12 → 0.1.14
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 +22 -17
- package/dist/{current-provider.d.ts → context-provider.d.ts} +13 -13
- package/dist/{current-provider.js → context-provider.js} +23 -23
- package/dist/main.d.ts +3 -4
- package/dist/main.js +3 -4
- package/dist/use-service-state.js +1 -1
- package/dist/use-subscribe-answers.d.ts +8 -0
- package/dist/use-subscribe-answers.js +7 -0
- package/dist/use-subscribe-asks.d.ts +8 -0
- package/dist/use-subscribe-asks.js +7 -0
- package/dist/use-subscribe.d.ts +8 -9
- package/dist/use-subscribe.js +8 -2
- package/package.json +5 -5
- package/dist/use-observe-answers.d.ts +0 -11
- package/dist/use-observe-answers.js +0 -10
- package/dist/use-observe-asks.d.ts +0 -11
- package/dist/use-observe-asks.js +0 -10
- package/dist/use-observe.d.ts +0 -3
- package/dist/use-observe.js +0 -7
package/README.md
CHANGED
|
@@ -16,25 +16,25 @@ dependencies.
|
|
|
16
16
|
|
|
17
17
|
It provides two kinds of adapter:
|
|
18
18
|
|
|
19
|
-
- `
|
|
19
|
+
- `ContextProvider` resolves exactly the runtime values named by its required
|
|
20
20
|
`provide` prop, then exposes them synchronously through `useProgram()`,
|
|
21
21
|
`useProcess()`, and `useParent()`.
|
|
22
22
|
- `SystemProvider` subscribes before reading exactly the system values named by its
|
|
23
23
|
required `provide` prop. `useSystemAppearance()`, `useDesktopPreferences()`,
|
|
24
24
|
`useDesktopSize()`, and `usePointerPosition()` expose those values synchronously
|
|
25
25
|
after resolution.
|
|
26
|
-
- `useSubscribe()`
|
|
27
|
-
|
|
26
|
+
- `useSubscribe()` owns named or all-event registrations for one mounted React
|
|
27
|
+
consumer.
|
|
28
28
|
- `useProgramState(program)`, `useProcessState(process)`,
|
|
29
29
|
`useServiceState(service)`, and `useWindowState(window)` explicitly compose
|
|
30
30
|
existing reads with future live events for one mounted consumer. They add no
|
|
31
31
|
state operation to another SDK.
|
|
32
|
-
- `
|
|
33
|
-
while `
|
|
34
|
-
|
|
32
|
+
- `useSubscribeAsks()` adapts an Endpoint traffic surface's question
|
|
33
|
+
subscription, while `useSubscribeAnswers()` adapts a Server traffic
|
|
34
|
+
surface's answer subscription.
|
|
35
35
|
|
|
36
|
-
Window needs no React resolution: `
|
|
37
|
-
silent capability object. `
|
|
36
|
+
Window needs no React resolution: `context.window` is already a synchronous,
|
|
37
|
+
silent capability object. `ContextProvider` therefore has no `window` selection
|
|
38
38
|
and the React SDK exposes no pass-through `useWindow()` hook.
|
|
39
39
|
|
|
40
40
|
The domain state hooks return only mutable state; identity and immutable
|
|
@@ -73,15 +73,20 @@ mount its `useWindowState()` child only while `clientExists` is true. Calling
|
|
|
73
73
|
the Window hook while the Client is absent lets the existing Window reads
|
|
74
74
|
reject normally.
|
|
75
75
|
|
|
76
|
-
The ordinary-event and traffic hooks retain the latest value returned by their
|
|
77
|
-
`useSubscribe()` may omit that callback; its default
|
|
78
|
-
`message => message`, so the hook retains the latest message
|
|
76
|
+
The ordinary-event and traffic hooks retain the latest value returned by their
|
|
77
|
+
projector. A named `useSubscribe()` may omit that callback; its default
|
|
78
|
+
projector is `message => message`, so the hook retains the latest message
|
|
79
|
+
unchanged. The all-event form receives a correlated capture:
|
|
79
80
|
|
|
80
81
|
```tsx
|
|
81
82
|
import { system } from "@phreshos/client"
|
|
82
83
|
import { useSubscribe } from "@phreshos/react"
|
|
83
84
|
|
|
84
85
|
const desktop = useSubscribe(system.desktop, "resize")
|
|
86
|
+
|
|
87
|
+
const latest = useSubscribe(system.desktop, capture => {
|
|
88
|
+
if (capture.event === "resize") return capture.message
|
|
89
|
+
})
|
|
85
90
|
```
|
|
86
91
|
|
|
87
92
|
System reads are asynchronous while subscriptions are live-only. `SystemProvider`
|
|
@@ -116,9 +121,9 @@ communicates its effective scheme through the Client iframe, while each Client
|
|
|
116
121
|
HTML document declares which schemes it supports.
|
|
117
122
|
|
|
118
123
|
```tsx
|
|
119
|
-
import {
|
|
124
|
+
import { context } from "@phreshos/client"
|
|
120
125
|
import {
|
|
121
|
-
|
|
126
|
+
ContextProvider,
|
|
122
127
|
useProgram,
|
|
123
128
|
useSubscribe
|
|
124
129
|
} from "@phreshos/react"
|
|
@@ -126,7 +131,7 @@ import {
|
|
|
126
131
|
function Counter() {
|
|
127
132
|
const program = useProgram()
|
|
128
133
|
|
|
129
|
-
const count = useSubscribe(
|
|
134
|
+
const count = useSubscribe(context, "count", message => {
|
|
130
135
|
return Number(message.payload)
|
|
131
136
|
})
|
|
132
137
|
|
|
@@ -135,14 +140,14 @@ function Counter() {
|
|
|
135
140
|
|
|
136
141
|
export default function App() {
|
|
137
142
|
return (
|
|
138
|
-
<
|
|
143
|
+
<ContextProvider provide={["program"]} fallback={<p>Loading…</p>} waitServer>
|
|
139
144
|
<Counter />
|
|
140
|
-
</
|
|
145
|
+
</ContextProvider>
|
|
141
146
|
)
|
|
142
147
|
}
|
|
143
148
|
```
|
|
144
149
|
|
|
145
|
-
Using a
|
|
150
|
+
Using a context or system hook outside its provider, or without selecting its
|
|
146
151
|
value, throws a configuration error. Neither provider supplies an implicit
|
|
147
152
|
"everything" selection, so adding a future capability cannot make it enter an
|
|
148
153
|
existing application.
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type Process, type Program } from "@phreshos/client";
|
|
3
3
|
declare const provisionNames: readonly ["program", "process", "parent"];
|
|
4
|
-
/** Resolves only the
|
|
5
|
-
export default function
|
|
4
|
+
/** Resolves only the runtime handles explicitly selected by the program. */
|
|
5
|
+
export default function ContextProvider({ children, fallback, provide, waitServer }: ContextProviderProperties): import("react").FunctionComponentElement<SelectedContextProviderProperties>;
|
|
6
6
|
/** Returns the current Program selected by the nearest provider. */
|
|
7
7
|
export declare function useProgram(): Program;
|
|
8
8
|
/** Returns the current Process selected by the nearest provider. */
|
|
9
9
|
export declare function useProcess(): Process;
|
|
10
10
|
/** Returns the current Process's selected visible parent. */
|
|
11
11
|
export declare function useParent(): Process | null;
|
|
12
|
-
/** Values that
|
|
13
|
-
export type
|
|
14
|
-
/** Required non-empty selection of
|
|
15
|
-
export type
|
|
16
|
-
/** Properties accepted by
|
|
17
|
-
export interface
|
|
18
|
-
/** Content rendered after every selected
|
|
12
|
+
/** Values that ContextProvider can resolve. */
|
|
13
|
+
export type ContextProvisionName = typeof provisionNames[number];
|
|
14
|
+
/** Required non-empty selection of runtime values. */
|
|
15
|
+
export type ContextProvision = readonly [ContextProvisionName, ...ContextProvisionName[]];
|
|
16
|
+
/** Properties accepted by ContextProvider. */
|
|
17
|
+
export interface ContextProviderProperties {
|
|
18
|
+
/** Content rendered after every selected runtime handle has resolved. */
|
|
19
19
|
readonly children: ReactNode;
|
|
20
20
|
/** Content rendered while selected handles or optional Server readiness resolve. */
|
|
21
21
|
readonly fallback?: ReactNode;
|
|
22
|
-
/** Exact
|
|
23
|
-
readonly provide:
|
|
22
|
+
/** Exact runtime values made available to descendant hooks. */
|
|
23
|
+
readonly provide: ContextProvision;
|
|
24
24
|
/**
|
|
25
25
|
* Waits for the Process's Server before rendering children.
|
|
26
26
|
* `true` uses the default ten-second deadline; a number sets milliseconds.
|
|
27
27
|
*/
|
|
28
28
|
readonly waitServer?: boolean | number;
|
|
29
29
|
}
|
|
30
|
-
type
|
|
31
|
-
selection: readonly
|
|
30
|
+
type SelectedContextProviderProperties = Omit<ContextProviderProperties, "provide" | "waitServer"> & Readonly<{
|
|
31
|
+
selection: readonly ContextProvisionName[];
|
|
32
32
|
waitServer: boolean | number;
|
|
33
33
|
}>;
|
|
34
34
|
export {};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createContext, createElement, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { context } from "@phreshos/client";
|
|
3
3
|
const provisionNames = ["program", "process", "parent"];
|
|
4
|
-
const
|
|
5
|
-
/** Resolves only the
|
|
6
|
-
export default function
|
|
4
|
+
const RuntimeContext = createContext(null);
|
|
5
|
+
/** Resolves only the runtime handles explicitly selected by the program. */
|
|
6
|
+
export default function ContextProvider({ children, fallback = null, provide, waitServer = false }) {
|
|
7
7
|
const normalized = normalizeProvision(provide);
|
|
8
8
|
const selectionKey = normalized.join("\0");
|
|
9
9
|
const selection = useMemo(() => normalized, [selectionKey]);
|
|
10
|
-
return createElement(
|
|
10
|
+
return createElement(SelectedContextProvider, {
|
|
11
11
|
children,
|
|
12
12
|
fallback,
|
|
13
13
|
key: `${selectionKey}\0${String(waitServer)}`,
|
|
@@ -15,12 +15,12 @@ export default function CurrentProvider({ children, fallback = null, provide, wa
|
|
|
15
15
|
waitServer
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function SelectedContextProvider({ children, fallback, selection, waitServer }) {
|
|
19
19
|
const [resolution, setResolution] = useState({ status: "pending" });
|
|
20
20
|
useEffect(() => {
|
|
21
21
|
let active = true;
|
|
22
22
|
setResolution({ status: "pending" });
|
|
23
|
-
void
|
|
23
|
+
void resolveContext(selection, waitServer).then(value => {
|
|
24
24
|
if (active)
|
|
25
25
|
setResolution({ status: "ready", value });
|
|
26
26
|
}, error => {
|
|
@@ -33,12 +33,12 @@ function SelectedCurrentProvider({ children, fallback, selection, waitServer })
|
|
|
33
33
|
return fallback;
|
|
34
34
|
if (resolution.status === "error")
|
|
35
35
|
throw resolution.error;
|
|
36
|
-
return createElement(
|
|
36
|
+
return createElement(RuntimeContext.Provider, { value: resolution.value }, children);
|
|
37
37
|
}
|
|
38
|
-
async function
|
|
38
|
+
async function resolveContext(selection, waitServer) {
|
|
39
39
|
const serverReady = typeof waitServer === "number"
|
|
40
|
-
?
|
|
41
|
-
: waitServer ?
|
|
40
|
+
? context.server.waitReady(waitServer)
|
|
41
|
+
: waitServer ? context.server.waitReady() : undefined;
|
|
42
42
|
const [entries] = await Promise.all([
|
|
43
43
|
Promise.all(selection.map(resolveProvision)),
|
|
44
44
|
serverReady
|
|
@@ -50,9 +50,9 @@ async function resolveCurrent(selection, waitServer) {
|
|
|
50
50
|
}
|
|
51
51
|
async function resolveProvision(name) {
|
|
52
52
|
switch (name) {
|
|
53
|
-
case "program": return [name, await
|
|
54
|
-
case "process": return [name, await
|
|
55
|
-
case "parent": return [name, await
|
|
53
|
+
case "program": return [name, await context.program()];
|
|
54
|
+
case "process": return [name, await context.process()];
|
|
55
|
+
case "parent": return [name, await context.parent()];
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
/** Returns the current Program selected by the nearest provider. */
|
|
@@ -68,22 +68,22 @@ export function useParent() {
|
|
|
68
68
|
return useProvided("parent");
|
|
69
69
|
}
|
|
70
70
|
function useProvided(name) {
|
|
71
|
-
const
|
|
72
|
-
if (!
|
|
73
|
-
throw new Error(`use${hookName(name)} must be used inside
|
|
74
|
-
if (!
|
|
75
|
-
throw new Error(`use${hookName(name)} requires "${name}" in
|
|
76
|
-
return
|
|
71
|
+
const providedContext = useContext(RuntimeContext);
|
|
72
|
+
if (!providedContext)
|
|
73
|
+
throw new Error(`use${hookName(name)} must be used inside ContextProvider`);
|
|
74
|
+
if (!providedContext.provided.has(name))
|
|
75
|
+
throw new Error(`use${hookName(name)} requires "${name}" in ContextProvider's provide prop`);
|
|
76
|
+
return providedContext.values[name];
|
|
77
77
|
}
|
|
78
78
|
function normalizeProvision(provide) {
|
|
79
79
|
if (!Array.isArray(provide) || provide.length === 0)
|
|
80
|
-
throw new Error("
|
|
80
|
+
throw new Error("ContextProvider's provide prop must select at least one runtime value");
|
|
81
81
|
const selected = new Set();
|
|
82
82
|
for (const name of provide) {
|
|
83
83
|
if (!provisionNames.includes(name))
|
|
84
|
-
throw new Error(`
|
|
84
|
+
throw new Error(`ContextProvider cannot provide "${String(name)}"`);
|
|
85
85
|
if (selected.has(name))
|
|
86
|
-
throw new Error(`
|
|
86
|
+
throw new Error(`ContextProvider's provide prop selects "${name}" more than once`);
|
|
87
87
|
selected.add(name);
|
|
88
88
|
}
|
|
89
89
|
return [...selected];
|
package/dist/main.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as ContextProvider, useParent, useProcess, useProgram, type ContextProvision, type ContextProvisionName, type ContextProviderProperties } from "./context-provider.js";
|
|
2
2
|
export { default as SystemProvider, usePointerPosition, useDesktopSize, useDesktopPreferences, useSystemAppearance, type SystemProvision, type SystemProvisionName, type SystemProviderProperties } from "./system-provider.js";
|
|
3
3
|
export { default as useSubscribe } from "./use-subscribe.js";
|
|
4
|
-
export { default as useObserve } from "./use-observe.js";
|
|
5
4
|
export { default as useProgramState, type ProgramState } from "./use-program-state.js";
|
|
6
5
|
export { default as useProcessState, type ProcessState } from "./use-process-state.js";
|
|
7
6
|
export { default as useServiceState, type ServiceState } from "./use-service-state.js";
|
|
8
7
|
export { default as useWindowState } from "./use-window-state.js";
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
8
|
+
export { default as useSubscribeAsks, type AskSubscribable } from "./use-subscribe-asks.js";
|
|
9
|
+
export { default as useSubscribeAnswers, type AnswerSubscribable } from "./use-subscribe-answers.js";
|
package/dist/main.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as ContextProvider, useParent, useProcess, useProgram } from "./context-provider.js";
|
|
2
2
|
export { default as SystemProvider, usePointerPosition, useDesktopSize, useDesktopPreferences, useSystemAppearance } from "./system-provider.js";
|
|
3
3
|
export { default as useSubscribe } from "./use-subscribe.js";
|
|
4
|
-
export { default as useObserve } from "./use-observe.js";
|
|
5
4
|
export { default as useProgramState } from "./use-program-state.js";
|
|
6
5
|
export { default as useProcessState } from "./use-process-state.js";
|
|
7
6
|
export { default as useServiceState } from "./use-service-state.js";
|
|
8
7
|
export { default as useWindowState } from "./use-window-state.js";
|
|
9
|
-
export { default as
|
|
10
|
-
export { default as
|
|
8
|
+
export { default as useSubscribeAsks } from "./use-subscribe-asks.js";
|
|
9
|
+
export { default as useSubscribeAnswers } from "./use-subscribe-answers.js";
|
|
@@ -2,7 +2,7 @@ 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 () => ({ enabled: await service.enabled() }), reduce => combineCleanups(service.subscribe("enable", () => reduce(current => setEnabled(current, true))), service.subscribe("disable", () => reduce(current => setEnabled(current, false))))), [service]);
|
|
5
|
+
const state = useMemo(() => new LiveState(async () => ({ enabled: await service.enabled() }), reduce => combineCleanups(service.lifecycle.subscribe("enable", () => reduce(current => setEnabled(current, true))), service.lifecycle.subscribe("disable", () => reduce(current => setEnabled(current, false))))), [service]);
|
|
6
6
|
return useSyncExternalStore(state.subscribe, state.snapshot, state.snapshot);
|
|
7
7
|
}
|
|
8
8
|
function setEnabled(state, enabled) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AnswerCapture, AnswerSubscriber, Cleanup } from "@phreshos/client";
|
|
2
|
+
/** Any Server traffic surface capable of subscribing to its outgoing answers. */
|
|
3
|
+
export type AnswerSubscribable = Readonly<{
|
|
4
|
+
/** Subscribes to answers sent by the target Server and returns its cleanup. */
|
|
5
|
+
subscribeAnswers<Result = unknown>(subscriber: AnswerSubscriber<Result>): Cleanup;
|
|
6
|
+
}>;
|
|
7
|
+
/** Subscribes to outgoing answers while mounted and retains the latest projection. */
|
|
8
|
+
export default function useSubscribeAnswers<Answer, Result>(target: AnswerSubscribable, project: (capture: AnswerCapture<Answer>) => Result): Awaited<Result> | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import useEventResult from "./event-result.js";
|
|
3
|
+
/** Subscribes to outgoing answers while mounted and retains the latest projection. */
|
|
4
|
+
export default function useSubscribeAnswers(target, project) {
|
|
5
|
+
const connect = useCallback((receive) => target.subscribeAnswers(receive), [target]);
|
|
6
|
+
return useEventResult(connect, project);
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AskCapture, AskSubscriber, Cleanup } from "@phreshos/client";
|
|
2
|
+
/** Any Endpoint traffic surface capable of subscribing to its outgoing questions. */
|
|
3
|
+
export type AskSubscribable = Readonly<{
|
|
4
|
+
/** Subscribes to questions sent by the target Endpoint and returns its cleanup. */
|
|
5
|
+
subscribeAsks<Payload = unknown>(subscriber: AskSubscriber<Payload>): Cleanup;
|
|
6
|
+
}>;
|
|
7
|
+
/** Subscribes to outgoing questions while mounted and retains the latest projection. */
|
|
8
|
+
export default function useSubscribeAsks<Payload, Result>(target: AskSubscribable, project: (capture: AskCapture<Payload>) => Result): Awaited<Result> | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import useEventResult from "./event-result.js";
|
|
3
|
+
/** Subscribes to outgoing questions while mounted and retains the latest projection. */
|
|
4
|
+
export default function useSubscribeAsks(target, project) {
|
|
5
|
+
const connect = useCallback((receive) => target.subscribeAsks(receive), [target]);
|
|
6
|
+
return useEventResult(connect, project);
|
|
7
|
+
}
|
package/dist/use-subscribe.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Captures, Context, ContextMessage, Endpoint, EventMessage, EventName, Subscribable, SubscribableEvents, SubscribableFallback } from "@phreshos/client";
|
|
2
2
|
type OpenEvent = string & {};
|
|
3
3
|
type AvailableEvent<Events extends object, Fallback> = EventName<Events> | ([Fallback] extends [never] ? never : OpenEvent);
|
|
4
4
|
type CompatibleEvent<Events extends object, Fallback, Narrowed> = {
|
|
@@ -11,17 +11,16 @@ type SubscribableTarget = Readonly<{
|
|
|
11
11
|
}>;
|
|
12
12
|
type TargetEvent<Target> = AvailableEvent<SubscribableEvents<Target>, SubscribableFallback<Target>>;
|
|
13
13
|
type TargetMessage<Target, Event extends string> = EventMessage<SubscribableEvents<Target>, SubscribableFallback<Target>, Event>;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
* The target supplies known message types. An explicit generic or callback
|
|
18
|
-
* annotation may narrow that type, but cannot replace it incompatibly.
|
|
19
|
-
*/
|
|
14
|
+
type TargetCapture<Target> = Captures<SubscribableEvents<Target>, SubscribableFallback<Target>>;
|
|
15
|
+
/** Subscribes while mounted and retains the latest named message. */
|
|
20
16
|
export default function useSubscribe<Target extends SubscribableTarget, Event extends TargetEvent<Target>>(target: Target, event: Event): TargetMessage<Target, Event> | undefined;
|
|
21
17
|
export default function useSubscribe<Narrowed = unknown>(target: Endpoint, event: string): Narrowed | undefined;
|
|
22
|
-
export default function useSubscribe<Narrowed extends
|
|
18
|
+
export default function useSubscribe<Narrowed extends ContextMessage<unknown> = ContextMessage<unknown>>(target: Context, event: string): Narrowed | undefined;
|
|
19
|
+
/** Subscribes while mounted and retains the latest projected named message. */
|
|
23
20
|
export default function useSubscribe<Target extends SubscribableTarget, Event extends TargetEvent<Target>, Result>(target: Target, event: Event, project: (message: TargetMessage<Target, Event>) => Result): Awaited<Result> | undefined;
|
|
24
21
|
export default function useSubscribe<Narrowed, Result = unknown>(target: Endpoint, event: string, project: (message: Narrowed) => Result): Awaited<Result> | undefined;
|
|
25
|
-
export default function useSubscribe<Narrowed extends
|
|
22
|
+
export default function useSubscribe<Narrowed extends ContextMessage<unknown>, Result = unknown>(target: Context, event: string, project: (message: Narrowed) => Result): Awaited<Result> | undefined;
|
|
26
23
|
export default function useSubscribe<Narrowed, Events extends object, Fallback, Result>(target: Subscribable<Events, Fallback>, event: CompatibleEvent<Events, Fallback, Narrowed>, project: (message: Narrowed) => Result): Awaited<Result> | undefined;
|
|
24
|
+
/** Subscribes across every event and retains the latest projected capture. */
|
|
25
|
+
export default function useSubscribe<Target extends SubscribableTarget, Result>(target: Target, project: (capture: TargetCapture<Target>) => Result): Awaited<Result> | undefined;
|
|
27
26
|
export {};
|
package/dist/use-subscribe.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
import useEventResult from "./event-result.js";
|
|
3
|
-
export default function useSubscribe(target,
|
|
3
|
+
export default function useSubscribe(target, eventOrProject, namedProject) {
|
|
4
|
+
const event = typeof eventOrProject === "string" ? eventOrProject : null;
|
|
4
5
|
const connect = useCallback((receive) => {
|
|
6
|
+
if (event === null) {
|
|
7
|
+
const subscribe = target.subscribe;
|
|
8
|
+
return subscribe(receive);
|
|
9
|
+
}
|
|
5
10
|
const subscribe = target.subscribe;
|
|
6
11
|
return subscribe(event, receive);
|
|
7
12
|
}, [target, event]);
|
|
8
|
-
|
|
13
|
+
const project = event === null ? eventOrProject : namedProject ?? identity;
|
|
14
|
+
return useEventResult(connect, project);
|
|
9
15
|
}
|
|
10
16
|
function identity(message) {
|
|
11
17
|
return message;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phreshos/react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
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.
|
|
51
|
-
"@phreshos/core": "^0.1.
|
|
50
|
+
"@phreshos/client": "^0.1.26",
|
|
51
|
+
"@phreshos/core": "^0.1.26",
|
|
52
52
|
"react": "^19.2.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@phreshos/client": "^0.1.
|
|
56
|
-
"@phreshos/core": "^0.1.
|
|
55
|
+
"@phreshos/client": "^0.1.26",
|
|
56
|
+
"@phreshos/core": "^0.1.26",
|
|
57
57
|
"@testing-library/react": "^16.3.0",
|
|
58
58
|
"@types/react": "^19.2.18",
|
|
59
59
|
"@types/react-dom": "^19.2.4",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { AnswerCapture, AnswerObserver, Cleanup } from "@phreshos/client";
|
|
2
|
-
/** Any Server traffic surface capable of observing its outgoing answers. */
|
|
3
|
-
export type AnswerObservable = Readonly<{
|
|
4
|
-
/** Observes answers sent by the target Server and returns its cleanup. */
|
|
5
|
-
observeAnswers<Result = unknown>(observer: AnswerObserver<Result>): Cleanup;
|
|
6
|
-
}>;
|
|
7
|
-
/**
|
|
8
|
-
* Observes answers in one Server's traffic while mounted and retains the
|
|
9
|
-
* latest projected result.
|
|
10
|
-
*/
|
|
11
|
-
export default function useObserveAnswers<Answer, Result>(target: AnswerObservable, project: (capture: AnswerCapture<Answer>) => Result): Awaited<Result> | undefined;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import useEventResult from "./event-result.js";
|
|
3
|
-
/**
|
|
4
|
-
* Observes answers in one Server's traffic while mounted and retains the
|
|
5
|
-
* latest projected result.
|
|
6
|
-
*/
|
|
7
|
-
export default function useObserveAnswers(target, project) {
|
|
8
|
-
const connect = useCallback((receive) => target.observeAnswers(receive), [target]);
|
|
9
|
-
return useEventResult(connect, project);
|
|
10
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { AskCapture, AskObserver, Cleanup } from "@phreshos/client";
|
|
2
|
-
/** Any Endpoint traffic surface capable of observing its outgoing questions. */
|
|
3
|
-
export type AskObservable = Readonly<{
|
|
4
|
-
/** Observes questions sent by the target Endpoint and returns its cleanup. */
|
|
5
|
-
observeAsks<Payload = unknown>(observer: AskObserver<Payload>): Cleanup;
|
|
6
|
-
}>;
|
|
7
|
-
/**
|
|
8
|
-
* Observes questions in one Endpoint's traffic while mounted and retains the
|
|
9
|
-
* latest projected result.
|
|
10
|
-
*/
|
|
11
|
-
export default function useObserveAsks<Payload, Result>(target: AskObservable, project: (capture: AskCapture<Payload>) => Result): Awaited<Result> | undefined;
|
package/dist/use-observe-asks.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import useEventResult from "./event-result.js";
|
|
3
|
-
/**
|
|
4
|
-
* Observes questions in one Endpoint's traffic while mounted and retains the
|
|
5
|
-
* latest projected result.
|
|
6
|
-
*/
|
|
7
|
-
export default function useObserveAsks(target, project) {
|
|
8
|
-
const connect = useCallback((receive) => target.observeAsks(receive), [target]);
|
|
9
|
-
return useEventResult(connect, project);
|
|
10
|
-
}
|
package/dist/use-observe.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { Captures, Subscribable } from "@phreshos/client";
|
|
2
|
-
/** Observes all events while mounted and retains the latest projected result. */
|
|
3
|
-
export default function useObserve<Events extends object, Fallback, Result>(target: Subscribable<Events, Fallback>, project: (capture: Captures<Events, Fallback>) => Result): Awaited<Result> | undefined;
|
package/dist/use-observe.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react";
|
|
2
|
-
import useEventResult from "./event-result.js";
|
|
3
|
-
/** Observes all events while mounted and retains the latest projected result. */
|
|
4
|
-
export default function useObserve(target, project) {
|
|
5
|
-
const connect = useCallback((receive) => target.observe(receive), [target]);
|
|
6
|
-
return useEventResult(connect, project);
|
|
7
|
-
}
|