@w6w/react 0.6.0 → 0.9.9
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 +183 -44
- package/dist/mod.d.ts +3 -3
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +4 -3
- package/dist/mod.js.map +1 -1
- package/dist/src/W6WProvider.d.ts +89 -39
- package/dist/src/W6WProvider.d.ts.map +1 -1
- package/dist/src/W6WProvider.js +104 -57
- package/dist/src/W6WProvider.js.map +1 -1
- package/dist/src/adapter.d.ts +157 -2
- package/dist/src/adapter.d.ts.map +1 -1
- package/dist/src/adapter.js +116 -1
- package/dist/src/adapter.js.map +1 -1
- package/dist/src/hooks.d.ts +90 -11
- package/dist/src/hooks.d.ts.map +1 -1
- package/dist/src/hooks.js +181 -42
- package/dist/src/hooks.js.map +1 -1
- package/dist/src/single-flight.d.ts +33 -0
- package/dist/src/single-flight.d.ts.map +1 -0
- package/dist/src/single-flight.js +71 -0
- package/dist/src/single-flight.js.map +1 -0
- package/dist/src/version.js +1 -1
- package/package.json +13 -4
package/dist/src/W6WProvider.js
CHANGED
|
@@ -1,80 +1,113 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* `<W6WProvider>` — one `W6WClient` per `baseUrl
|
|
4
|
-
*
|
|
3
|
+
* `<W6WProvider>` — one `W6WClient` per `{baseUrl, project, identityKey,
|
|
4
|
+
* refreshOnUnauthorized, headers}` combination, with the token resolved per
|
|
5
|
+
* request (concurrent requests share one supplier call).
|
|
5
6
|
*
|
|
6
|
-
* `@w6w/sdk`'s `W6WClientOptions.token` (`node/src/config.ts:41-63`)
|
|
7
|
-
*
|
|
8
|
-
* (
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* `@w6w/sdk`'s `W6WClientOptions.token` (`node/src/config.ts:41-63`) accepts
|
|
8
|
+
* either a plain string or a {@linkcode TokenProvider} function — the
|
|
9
|
+
* function form is called (and its result awaited) per request — requests in
|
|
10
|
+
* flight at the same time share ONE call, nothing is cached once it settles,
|
|
11
|
+
* and it is never resolved once at construction. This provider hands the
|
|
12
|
+
* SDK a single STABLE function that reads the CURRENT `token` prop through a
|
|
13
|
+
* ref: a string prop is returned as-is, a function prop is called with
|
|
14
|
+
* whatever `ctx` the SDK forwards (including `{forceRefresh: true}` on its
|
|
15
|
+
* own one-shot 401 recovery retry, `node/src/http.ts`). `fetch` and
|
|
16
|
+
* `onUnauthorized` are the same shape — stable wrappers over "latest" refs —
|
|
17
|
+
* so neither a token rotation, a new `fetch` identity, nor a new
|
|
18
|
+
* `onUnauthorized` closure identity ever rebuilds the client. A nullish or
|
|
19
|
+
* blank token (sync or async) never reaches the wire: the SDK's own
|
|
20
|
+
* `requireToken` raises a local {@linkcode ConfigError} before any `fetch`
|
|
21
|
+
* call, which is the floor `hooks.ts`'s `useAsync` reports as `loading`, not
|
|
22
|
+
* `error`.
|
|
11
23
|
*
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
* the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* always overwrites it first) and an injected `fetch` that resolves the
|
|
23
|
-
* current `token` prop (calling it, if it is a supplier) on every call.
|
|
24
|
+
* **What DOES rebuild the client** (the `useMemo` below): `baseUrl`,
|
|
25
|
+
* `project`, `identityKey`, `refreshOnUnauthorized`, and a canonical STRING of
|
|
26
|
+
* `headers`' sorted entries — never the `headers` object's own identity (an
|
|
27
|
+
* inline literal would rebuild the client on every render) and never
|
|
28
|
+
* `token`. `identityKey` (e.g. `${subject}:${account}`) is the one supported
|
|
29
|
+
* way to force a rebuild on purpose, for a host juggling more than one
|
|
30
|
+
* signed-in identity: every hook built on `useAsync` (`hooks.ts`) resets its
|
|
31
|
+
* state to `{data: undefined, error: undefined, loading: true}` when the
|
|
32
|
+
* client it reads through changes, aborting whatever it had in flight first —
|
|
33
|
+
* a stale account's data is never shown under a new one.
|
|
24
34
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* function has a stable identity across renders, so keying on the supplier
|
|
29
|
-
* would never rebuild AND never read a fresh value, while keying on the
|
|
30
|
-
* token's resolved value would tear the client down and rebuild it on every
|
|
31
|
-
* rotation — exactly what C-4 says not to do ("without tearing down"). The
|
|
32
|
-
* memo below depends on `[baseUrl, project]` only; `token` and `fetch` are
|
|
33
|
-
* read through "latest" refs, updated every render but never a dependency, so
|
|
34
|
-
* a rotating token is read fresh per request without ever rebuilding the
|
|
35
|
-
* client.
|
|
35
|
+
* `ready` (default `true`) gates every READ hook, never a mutation: while
|
|
36
|
+
* `false`, a read hook reports `loading: true` and never calls the SDK at
|
|
37
|
+
* all. Flipping it to `true` (or changing `identityKey`) fetches.
|
|
36
38
|
*
|
|
37
39
|
* @module
|
|
38
40
|
*/
|
|
39
41
|
import { W6WClient } from "@w6w/sdk";
|
|
40
42
|
import { createContext, useContext, useMemo, useRef } from "react";
|
|
43
|
+
const Ctx = createContext(null);
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
45
|
+
* Canonical encoding of a headers object for the `useMemo` dependency array —
|
|
46
|
+
* sorted entries, so `{a: "1", b: "2"}` and `{b: "2", a: "1"}` produce the
|
|
47
|
+
* SAME key and two structurally-equal-but-distinct objects never rebuild the
|
|
48
|
+
* client.
|
|
46
49
|
*/
|
|
47
|
-
|
|
48
|
-
const
|
|
50
|
+
function headersKey(headers) {
|
|
51
|
+
const entries = Object.entries(headers ?? {}).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
52
|
+
return entries.map(([name, value]) => `${name}\u0000${value}`).join("\u0001");
|
|
53
|
+
}
|
|
49
54
|
/**
|
|
50
|
-
* Provides one memoized `W6WClient` to every component under
|
|
51
|
-
* module's header for the
|
|
55
|
+
* Provides one memoized `W6WClient` (plus `ready`) to every component under
|
|
56
|
+
* it. See this module's header for the token-freshness mechanism and the
|
|
57
|
+
* memoization policy.
|
|
52
58
|
*/
|
|
53
59
|
export function W6WProvider(props) {
|
|
54
|
-
const { baseUrl, token, fetch: fetchOverride, project, children } = props;
|
|
60
|
+
const { baseUrl, token, fetch: fetchOverride, project, headers, ready = true, identityKey, refreshOnUnauthorized, onUnauthorized, children, } = props;
|
|
55
61
|
// "Latest ref" pattern: kept in sync on every render, but never a `useMemo`
|
|
56
|
-
// dependency below — the
|
|
57
|
-
// value through these, so a token rotation
|
|
58
|
-
//
|
|
59
|
-
// "reactive" values, so
|
|
60
|
-
// require them in the memo's
|
|
62
|
+
// dependency below — the stable wrappers constructed inside always read the
|
|
63
|
+
// CURRENT prop value through these, so a token rotation, a new `fetch`
|
|
64
|
+
// identity or a new `onUnauthorized` closure identity never forces a client
|
|
65
|
+
// rebuild. Refs are stable across renders and are not "reactive" values, so
|
|
66
|
+
// `useExhaustiveDependencies` correctly does not require them in the memo's
|
|
67
|
+
// dependency array. `headers` gets the same treatment for the same reason —
|
|
68
|
+
// the memo depends on its canonical STRING (`headersKey`, below), not on
|
|
69
|
+
// this ref — but the value actually handed to `W6WClient` is read fresh at
|
|
70
|
+
// the moment the memo recomputes.
|
|
61
71
|
const tokenRef = useRef(token);
|
|
62
72
|
tokenRef.current = token;
|
|
63
73
|
const fetchRef = useRef(fetchOverride);
|
|
64
74
|
fetchRef.current = fetchOverride;
|
|
75
|
+
const onUnauthorizedRef = useRef(onUnauthorized);
|
|
76
|
+
onUnauthorizedRef.current = onUnauthorized;
|
|
77
|
+
const headersRef = useRef(headers);
|
|
78
|
+
headersRef.current = headers;
|
|
79
|
+
const headersSnapshot = headersKey(headers);
|
|
65
80
|
const client = useMemo(() => {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
// `identityKey` and `headersSnapshot` are not otherwise read in this body
|
|
82
|
+
// — they exist purely so this memo depends on them (identity switch;
|
|
83
|
+
// headers content change, per this module's header). Referencing them
|
|
84
|
+
// here (as opposed to only in the dependency array below) is what keeps
|
|
85
|
+
// `useExhaustiveDependencies` from treating them as superfluous.
|
|
86
|
+
void identityKey;
|
|
87
|
+
void headersSnapshot;
|
|
88
|
+
const stableToken = (ctx) => {
|
|
89
|
+
const current = tokenRef.current;
|
|
90
|
+
return typeof current === "function" ? current(ctx) : current;
|
|
91
|
+
};
|
|
92
|
+
const stableFetch = (input, init) => {
|
|
72
93
|
const transport = fetchRef.current ?? ((i, ii) => globalThis.fetch(i, ii));
|
|
73
|
-
return transport(input,
|
|
94
|
+
return transport(input, init);
|
|
74
95
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
96
|
+
const stableOnUnauthorized = (error) => {
|
|
97
|
+
onUnauthorizedRef.current?.(error);
|
|
98
|
+
};
|
|
99
|
+
return new W6WClient({
|
|
100
|
+
baseUrl,
|
|
101
|
+
project,
|
|
102
|
+
token: stableToken,
|
|
103
|
+
fetch: stableFetch,
|
|
104
|
+
headers: headersRef.current,
|
|
105
|
+
refreshOnUnauthorized,
|
|
106
|
+
onUnauthorized: stableOnUnauthorized,
|
|
107
|
+
});
|
|
108
|
+
}, [baseUrl, project, identityKey, refreshOnUnauthorized, headersSnapshot]);
|
|
109
|
+
const value = useMemo(() => ({ client, ready }), [client, ready]);
|
|
110
|
+
return _jsx(Ctx.Provider, { value: value, children: children });
|
|
78
111
|
}
|
|
79
112
|
/**
|
|
80
113
|
* Access the memoized `W6WClient`. Throws a helpful error if used outside a
|
|
@@ -82,11 +115,25 @@ export function W6WProvider(props) {
|
|
|
82
115
|
* `useW6WApi` shape — read-only reference, transcribed here, never imported).
|
|
83
116
|
*/
|
|
84
117
|
export function useW6WClient() {
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
118
|
+
const ctx = useContext(Ctx);
|
|
119
|
+
if (!ctx) {
|
|
87
120
|
throw new Error("useW6WClient must be used inside <W6WProvider>. " +
|
|
88
121
|
'Wrap your app root with <W6WProvider baseUrl="..." token="...">...</W6WProvider>.');
|
|
89
122
|
}
|
|
90
|
-
return client;
|
|
123
|
+
return ctx.client;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Internal: the context value including `ready`, consumed only by the read
|
|
127
|
+
* hooks in `hooks.ts` (via a relative import — never re-exported from
|
|
128
|
+
* `mod.ts`). `useW6WClient`'s `W6WClient` return type is the public surface;
|
|
129
|
+
* this is the one extra bit every read hook needs to gate on.
|
|
130
|
+
*/
|
|
131
|
+
export function useW6WProviderContext() {
|
|
132
|
+
const ctx = useContext(Ctx);
|
|
133
|
+
if (!ctx) {
|
|
134
|
+
throw new Error("This hook must be used inside <W6WProvider>. " +
|
|
135
|
+
'Wrap your app root with <W6WProvider baseUrl="..." token="...">...</W6WProvider>.');
|
|
136
|
+
}
|
|
137
|
+
return ctx;
|
|
91
138
|
}
|
|
92
139
|
//# sourceMappingURL=W6WProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"W6WProvider.js","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"W6WProvider.js","sourceRoot":"","sources":["../../src/W6WProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/src/adapter.d.ts
CHANGED
|
@@ -35,18 +35,134 @@
|
|
|
35
35
|
* so writing a second pagination loop here would be exactly the "third client
|
|
36
36
|
* for these routes" C-2 exists to prevent.
|
|
37
37
|
*
|
|
38
|
+
* `listTriggerApps`/`getAppTriggers`/`listSubscriptionsForWorkflow`/
|
|
39
|
+
* `createSubscription` are REQUIRED here even though `@w6w/ui`'s own
|
|
40
|
+
* declaration marks them optional (`?`) — plan.md D-2: optional-in-`ui` lets
|
|
41
|
+
* a partner on an older `@w6w/react` degrade instead of crashing, while every
|
|
42
|
+
* consumer of THIS adapter gets a real implementation.
|
|
43
|
+
*
|
|
44
|
+
* `listFunctions`/`getFunction`/`invokeFunction`/`listWorkflows`/`getWorkflow`/
|
|
45
|
+
* `runWorkflow` are thin calls over the BASE `client.functions.*`/
|
|
46
|
+
* `client.workflows.*` surface — never `client.console.*` — mirroring
|
|
47
|
+
* `listConnections`'s own base-over-console preference above. `getFunction`
|
|
48
|
+
* and `getWorkflow` reshape the base namespace's intentionally OPAQUE
|
|
49
|
+
* definition (`node/src/functions.ts`'s `FunctionDefinition`,
|
|
50
|
+
* `node/src/workflows.ts`'s `WorkflowDefinition` are both
|
|
51
|
+
* `Record<string, unknown>`, by design — a newer server may add fields a
|
|
52
|
+
* modelled type would reject) into `@w6w/ui`'s narrower `FunctionDetail`/
|
|
53
|
+
* `WorkflowDetail` by reading the handful of fields every stored definition
|
|
54
|
+
* carries (`id`, `key`/`name`, `displayName`, `description`, `inputs`/
|
|
55
|
+
* `steps`) — the same real wire fields `@w6w/sdk/console`'s typed
|
|
56
|
+
* `FunctionDef`/the console workflow shape name, not a guess. `getFunction`'s
|
|
57
|
+
* `inputs` picks up the SAME `ActionParam` narrowing as `getAppActions`
|
|
58
|
+
* above (6 fields vs `@w6w/ui`'s 14 richer, presentation-only ones). `runWorkflow`
|
|
59
|
+
* always sends `wait: true` and forwards `client.workflows.run`'s own
|
|
60
|
+
* `terminal` unchanged — that field is already derived from the run's
|
|
61
|
+
* `status` (`200` ⇒ terminal, the server's `202` wait-timeout ⇒ not), so
|
|
62
|
+
* re-deriving it from `httpStatus` a second time here would be a second,
|
|
63
|
+
* possibly-diverging copy of the same rule.
|
|
64
|
+
*
|
|
38
65
|
* @module
|
|
39
66
|
*/
|
|
40
|
-
import { type ConnectionSummary, type W6WClient } from "@w6w/sdk";
|
|
41
|
-
import type { ActionDef, ApiCallRecord, AppSummary, AuthDef, InvokeOptions, SavedTest, StepTest, TestRunSummary } from "@w6w/sdk/console";
|
|
67
|
+
import { type ConnectionSummary, type FunctionSummary, type W6WClient, type WorkflowSummary } from "@w6w/sdk";
|
|
68
|
+
import type { ActionDef, ActionParam, ApiCallRecord, AppSummary, AuthDef, InvokeOptions, SavedTest, StepTest, Subscription, TestRunSummary, TriggerDef } from "@w6w/sdk/console";
|
|
42
69
|
/**
|
|
43
70
|
* The `@w6w/ui` `W6WApi` contract, hand-duplicated — see this module's
|
|
44
71
|
* header. Every member's signature mirrors `provider.tsx:87-231`'s member of
|
|
45
72
|
* the same name.
|
|
46
73
|
*/
|
|
74
|
+
/**
|
|
75
|
+
* Options for {@link W6WApi.listAppsPage} — one bounded, server-paged
|
|
76
|
+
* request. Every member is optional; an omitted member is a host-defined
|
|
77
|
+
* default (usually "no filter"/"first page"), never a client-side guess.
|
|
78
|
+
* Hand-duplicated verbatim from `packages/ui/src/provider.tsx` — see this
|
|
79
|
+
* module's header.
|
|
80
|
+
*/
|
|
81
|
+
export interface ListAppsPageOptions {
|
|
82
|
+
/** Full-text search term, forwarded to the server verbatim. */
|
|
83
|
+
q?: string;
|
|
84
|
+
/** Server-side category filter (e.g. `"ai"`). */
|
|
85
|
+
category?: string;
|
|
86
|
+
/** Opaque pagination cursor from a prior {@link AppsPageResult.nextCursor}. */
|
|
87
|
+
cursor?: string;
|
|
88
|
+
/** Page size; a host may clamp this to its own bounds. */
|
|
89
|
+
limit?: number;
|
|
90
|
+
/** Ask the host for a bounded picker-summary projection (heavy fields like inline icons may be trimmed). */
|
|
91
|
+
compact?: boolean;
|
|
92
|
+
/** Abort this request. Local request control only; never a wire field. */
|
|
93
|
+
signal?: AbortSignal;
|
|
94
|
+
}
|
|
95
|
+
/** One page of apps, as returned by {@link W6WApi.listAppsPage}. */
|
|
96
|
+
export interface AppsPageResult {
|
|
97
|
+
apps: AppSummary[];
|
|
98
|
+
/** Present unless this is the last page. */
|
|
99
|
+
nextCursor?: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* One step of a Workflow, as {@link W6WApi.getWorkflow} returns it — the
|
|
103
|
+
* minimal shape the Configure stage needs to find the entry/trigger step's
|
|
104
|
+
* own declared `with` fields. Hand-duplicated verbatim from
|
|
105
|
+
* `packages/ui/src/types.ts`'s `WorkflowStepSummary` — see this module's
|
|
106
|
+
* header.
|
|
107
|
+
*/
|
|
108
|
+
export interface WorkflowStepSummary {
|
|
109
|
+
id: string;
|
|
110
|
+
uses: {
|
|
111
|
+
app: string;
|
|
112
|
+
action: string;
|
|
113
|
+
};
|
|
114
|
+
with?: Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A Workflow's full definition, as {@link W6WApi.getWorkflow} returns it.
|
|
118
|
+
* Hand-duplicated verbatim from `packages/ui/src/types.ts`'s
|
|
119
|
+
* `WorkflowDetail` — see this module's header.
|
|
120
|
+
*/
|
|
121
|
+
export interface WorkflowDetail {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
displayName?: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
steps: WorkflowStepSummary[];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A Function's canonical interface, as {@link W6WApi.getFunction} returns
|
|
130
|
+
* it. Hand-duplicated verbatim from `packages/ui/src/types.ts`'s
|
|
131
|
+
* `FunctionDetail` — see this module's header.
|
|
132
|
+
*/
|
|
133
|
+
export interface FunctionDetail {
|
|
134
|
+
id: string;
|
|
135
|
+
key: string;
|
|
136
|
+
displayName?: string;
|
|
137
|
+
description?: string;
|
|
138
|
+
inputs: ActionParam[];
|
|
139
|
+
valid: boolean;
|
|
140
|
+
}
|
|
47
141
|
export interface W6WApi {
|
|
48
142
|
/** List registered apps to pick from in the connection modal. */
|
|
49
143
|
listApps(): Promise<AppSummary[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Fetch ONE bounded, server-paged slice of the app catalog — the seam every
|
|
146
|
+
* bounded picker UI (`AppPicker`'s paged mode, `StepBuilderModal`'s
|
|
147
|
+
* Apps/AI/Triggers tabs) prefers over {@link listApps} when a host
|
|
148
|
+
* implements it. OPTIONAL and ADDITIVE: an older/imported provider that
|
|
149
|
+
* only implements `listApps` still typechecks and simply keeps the
|
|
150
|
+
* eager-list behavior everywhere this member is absent.
|
|
151
|
+
*/
|
|
152
|
+
listAppsPage?(options?: ListAppsPageOptions): Promise<AppsPageResult>;
|
|
153
|
+
/**
|
|
154
|
+
* Resolve a bounded, explicit set of app ids to their summaries — the seam
|
|
155
|
+
* behind the "Ready to use" tab's connected-app batching and
|
|
156
|
+
* `AddConnectionModal`'s `initialAppId` resolution: a caller that already
|
|
157
|
+
* knows exactly which ids it needs never has to fetch (or filter) the whole
|
|
158
|
+
* catalog to find them. OPTIONAL, like {@link listAppsPage}: absent, a
|
|
159
|
+
* caller falls back to its pre-existing `listApps`-based resolution.
|
|
160
|
+
* Missing/404 ids are simply omitted from the result, never an error for
|
|
161
|
+
* the whole batch.
|
|
162
|
+
*/
|
|
163
|
+
listAppsByIds?(ids: readonly string[], options?: {
|
|
164
|
+
signal?: AbortSignal;
|
|
165
|
+
}): Promise<AppSummary[]>;
|
|
50
166
|
/** Load auth methods declared by an app's manifest, with availability flags. */
|
|
51
167
|
getAppAuth(appId: string): Promise<AuthDef[]>;
|
|
52
168
|
/** Create a non-OAuth connection with a user-supplied credential. */
|
|
@@ -138,6 +254,45 @@ export interface W6WApi {
|
|
|
138
254
|
}): Promise<void>;
|
|
139
255
|
/** List the saved test fixtures for a workflow step. */
|
|
140
256
|
listStepTests(workflowId: string, stepId: string): Promise<StepTest[]>;
|
|
257
|
+
/** List the apps whose latest version declares at least one trigger. */
|
|
258
|
+
listTriggerApps(): Promise<AppSummary[]>;
|
|
259
|
+
/** List an app's declared triggers, to pick from in the Triggers tab. */
|
|
260
|
+
getAppTriggers(appId: string): Promise<TriggerDef[]>;
|
|
261
|
+
/** List the subscriptions (trigger bindings) already bound to one workflow. */
|
|
262
|
+
listSubscriptionsForWorkflow(workflowId: string): Promise<Subscription[]>;
|
|
263
|
+
/** Bind an app's trigger to a workflow. */
|
|
264
|
+
createSubscription(appId: string, triggerKey: string, input: {
|
|
265
|
+
workflowId: string;
|
|
266
|
+
connectionId?: string | null;
|
|
267
|
+
params?: Record<string, unknown>;
|
|
268
|
+
}): Promise<Subscription>;
|
|
269
|
+
/** List the caller's registered Functions — drives the step builder's Functions tab. */
|
|
270
|
+
listFunctions(): Promise<FunctionSummary[]>;
|
|
271
|
+
/** Load one Function's canonical interface, for the Functions tab's Configure stage. */
|
|
272
|
+
getFunction(id: string): Promise<FunctionDetail>;
|
|
273
|
+
/** Invoke a Function directly — the Functions tab's Test stage. Returns the raw output. */
|
|
274
|
+
invokeFunction(id: string, inputs: Record<string, unknown>): Promise<unknown>;
|
|
275
|
+
/** List the caller's registered Workflows — drives the step builder's Workflows tab. */
|
|
276
|
+
listWorkflows(): Promise<WorkflowSummary[]>;
|
|
277
|
+
/** Load one Workflow's full definition, for the Workflows tab's Configure stage. */
|
|
278
|
+
getWorkflow(id: string): Promise<WorkflowDetail>;
|
|
279
|
+
/**
|
|
280
|
+
* Run a Workflow synchronously — the Workflows tab's Test stage. Always the
|
|
281
|
+
* SAME `?wait=true` path a saved `@w6w/call` step takes at run time, never
|
|
282
|
+
* a client-side enqueue-and-poll. `terminal` is derived from the run's own
|
|
283
|
+
* status (`200` ⇒ `true`, the server's `202` wait-timeout ⇒ `false` — a
|
|
284
|
+
* legitimate "still running" outcome, not an error).
|
|
285
|
+
*/
|
|
286
|
+
runWorkflow(id: string, opts?: {
|
|
287
|
+
variables?: Record<string, unknown>;
|
|
288
|
+
input?: Record<string, unknown>;
|
|
289
|
+
}): Promise<{
|
|
290
|
+
runId: string;
|
|
291
|
+
status: string;
|
|
292
|
+
output?: unknown;
|
|
293
|
+
error?: unknown;
|
|
294
|
+
terminal: boolean;
|
|
295
|
+
}>;
|
|
141
296
|
}
|
|
142
297
|
/** Build a `W6WApi` implementation over an existing `W6WClient`. See this module's header. */
|
|
143
298
|
export declare function createW6WUiAdapter(client: W6WClient): W6WApi;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/src/adapter.js
CHANGED
|
@@ -35,9 +35,36 @@
|
|
|
35
35
|
* so writing a second pagination loop here would be exactly the "third client
|
|
36
36
|
* for these routes" C-2 exists to prevent.
|
|
37
37
|
*
|
|
38
|
+
* `listTriggerApps`/`getAppTriggers`/`listSubscriptionsForWorkflow`/
|
|
39
|
+
* `createSubscription` are REQUIRED here even though `@w6w/ui`'s own
|
|
40
|
+
* declaration marks them optional (`?`) — plan.md D-2: optional-in-`ui` lets
|
|
41
|
+
* a partner on an older `@w6w/react` degrade instead of crashing, while every
|
|
42
|
+
* consumer of THIS adapter gets a real implementation.
|
|
43
|
+
*
|
|
44
|
+
* `listFunctions`/`getFunction`/`invokeFunction`/`listWorkflows`/`getWorkflow`/
|
|
45
|
+
* `runWorkflow` are thin calls over the BASE `client.functions.*`/
|
|
46
|
+
* `client.workflows.*` surface — never `client.console.*` — mirroring
|
|
47
|
+
* `listConnections`'s own base-over-console preference above. `getFunction`
|
|
48
|
+
* and `getWorkflow` reshape the base namespace's intentionally OPAQUE
|
|
49
|
+
* definition (`node/src/functions.ts`'s `FunctionDefinition`,
|
|
50
|
+
* `node/src/workflows.ts`'s `WorkflowDefinition` are both
|
|
51
|
+
* `Record<string, unknown>`, by design — a newer server may add fields a
|
|
52
|
+
* modelled type would reject) into `@w6w/ui`'s narrower `FunctionDetail`/
|
|
53
|
+
* `WorkflowDetail` by reading the handful of fields every stored definition
|
|
54
|
+
* carries (`id`, `key`/`name`, `displayName`, `description`, `inputs`/
|
|
55
|
+
* `steps`) — the same real wire fields `@w6w/sdk/console`'s typed
|
|
56
|
+
* `FunctionDef`/the console workflow shape name, not a guess. `getFunction`'s
|
|
57
|
+
* `inputs` picks up the SAME `ActionParam` narrowing as `getAppActions`
|
|
58
|
+
* above (6 fields vs `@w6w/ui`'s 14 richer, presentation-only ones). `runWorkflow`
|
|
59
|
+
* always sends `wait: true` and forwards `client.workflows.run`'s own
|
|
60
|
+
* `terminal` unchanged — that field is already derived from the run's
|
|
61
|
+
* `status` (`200` ⇒ terminal, the server's `202` wait-timeout ⇒ not), so
|
|
62
|
+
* re-deriving it from `httpStatus` a second time here would be a second,
|
|
63
|
+
* possibly-diverging copy of the same rule.
|
|
64
|
+
*
|
|
38
65
|
* @module
|
|
39
66
|
*/
|
|
40
|
-
import { ApiError } from "@w6w/sdk";
|
|
67
|
+
import { ApiError, } from "@w6w/sdk";
|
|
41
68
|
/**
|
|
42
69
|
* Alias `@w6w/sdk`'s `ApiError.raw` onto `.body` (`err.body === err.raw`, not
|
|
43
70
|
* a copy) before an error reaches the caller — the field name every
|
|
@@ -67,10 +94,44 @@ async function withApiErrorBody(fn) {
|
|
|
67
94
|
throw err;
|
|
68
95
|
}
|
|
69
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* The server's own `ids` cap (`MAX_IDS_PER_QUERY`, `registry/packages/types/src/datastore.ts`) —
|
|
99
|
+
* `listAppsByIds` below chunks to this size itself since `console.apps.listPage`
|
|
100
|
+
* is a thin, non-chunking pass-through (`node/src/console/apps.ts`) and a
|
|
101
|
+
* caller passing more than this in one request gets the server's `400`.
|
|
102
|
+
*/
|
|
103
|
+
const MAX_IDS_PER_CHUNK = 100;
|
|
70
104
|
/** Build a `W6WApi` implementation over an existing `W6WClient`. See this module's header. */
|
|
71
105
|
export function createW6WUiAdapter(client) {
|
|
72
106
|
return {
|
|
73
107
|
listApps: () => withApiErrorBody(() => client.console.apps.list()),
|
|
108
|
+
listAppsPage: (options = {}) => withApiErrorBody(async () => {
|
|
109
|
+
const page = await client.console.apps.listPage({
|
|
110
|
+
q: options.q,
|
|
111
|
+
category: options.category,
|
|
112
|
+
cursor: options.cursor,
|
|
113
|
+
limit: options.limit,
|
|
114
|
+
compact: options.compact,
|
|
115
|
+
signal: options.signal,
|
|
116
|
+
});
|
|
117
|
+
return { apps: page.apps, nextCursor: page.nextCursor };
|
|
118
|
+
}),
|
|
119
|
+
// Dedupe first (a caller may hand in the same id twice across tabs/pages);
|
|
120
|
+
// `[]` resolves with NO request at all — never an unfiltered page. Chunks
|
|
121
|
+
// of <= MAX_IDS_PER_CHUNK each become their own `listPage({ ids: chunk })`
|
|
122
|
+
// call, issued CONCURRENTLY (`Promise.all`), and the pages are
|
|
123
|
+
// concatenated in chunk order.
|
|
124
|
+
listAppsByIds: (ids, options) => withApiErrorBody(async () => {
|
|
125
|
+
const unique = Array.from(new Set(ids));
|
|
126
|
+
if (unique.length === 0)
|
|
127
|
+
return [];
|
|
128
|
+
const chunks = [];
|
|
129
|
+
for (let i = 0; i < unique.length; i += MAX_IDS_PER_CHUNK) {
|
|
130
|
+
chunks.push(unique.slice(i, i + MAX_IDS_PER_CHUNK));
|
|
131
|
+
}
|
|
132
|
+
const pages = await Promise.all(chunks.map((chunk) => client.console.apps.listPage({ ids: chunk, signal: options?.signal })));
|
|
133
|
+
return pages.flatMap((page) => page.apps);
|
|
134
|
+
}),
|
|
74
135
|
getAppAuth: (appId) => withApiErrorBody(() => client.console.apps.getAuth(appId)),
|
|
75
136
|
createConnection: (appId, body) => withApiErrorBody(() => client.console.connections.create(appId, body)),
|
|
76
137
|
startAppOAuthFlow: (appId, authKey, body) => withApiErrorBody(() => client.console.apps.startOAuthFlow(appId, authKey, body)),
|
|
@@ -95,6 +156,60 @@ export function createW6WUiAdapter(client) {
|
|
|
95
156
|
// Same discard as `recordTestRun` above.
|
|
96
157
|
recordStepTestRun: (workflowId, stepId, body) => withApiErrorBody(() => client.console.stepTests.recordRun(workflowId, stepId, body).then(() => undefined)),
|
|
97
158
|
listStepTests: (workflowId, stepId) => withApiErrorBody(() => client.console.stepTests.list(workflowId, stepId)),
|
|
159
|
+
// Same predicate studio's own facade uses (T2.1.1), so the two embedding
|
|
160
|
+
// paths cannot disagree on which apps have a trigger to offer.
|
|
161
|
+
listTriggerApps: () => withApiErrorBody(async () => {
|
|
162
|
+
const apps = await client.console.apps.list();
|
|
163
|
+
return apps.filter((a) => (a.triggerCount ?? 0) > 0);
|
|
164
|
+
}),
|
|
165
|
+
getAppTriggers: (appId) => withApiErrorBody(() => client.console.apps.getTriggers(appId)),
|
|
166
|
+
listSubscriptionsForWorkflow: (workflowId) => withApiErrorBody(() => client.console.subscriptions.listForWorkflow(workflowId)),
|
|
167
|
+
// `input` is forwarded verbatim as the whole POST body.
|
|
168
|
+
createSubscription: (appId, triggerKey, input) => withApiErrorBody(() => client.console.subscriptions.create(appId, triggerKey, input)),
|
|
169
|
+
// The BASE `client.functions.*`/`client.workflows.*` surface from here
|
|
170
|
+
// down — never `console.*`. See this module's header.
|
|
171
|
+
listFunctions: () => withApiErrorBody(() => client.functions.list()),
|
|
172
|
+
getFunction: (id) => withApiErrorBody(async () => {
|
|
173
|
+
const { function: fn, valid } = await client.functions.get(id);
|
|
174
|
+
const def = fn;
|
|
175
|
+
return {
|
|
176
|
+
id: def.id,
|
|
177
|
+
key: def.key,
|
|
178
|
+
displayName: def.displayName,
|
|
179
|
+
description: def.description,
|
|
180
|
+
inputs: def.inputs ?? [],
|
|
181
|
+
valid,
|
|
182
|
+
};
|
|
183
|
+
}),
|
|
184
|
+
// `inputs` is forwarded as the whole `payload` — the Function's canonical
|
|
185
|
+
// inputs object, matching `client.functions.run`'s own `{payload}` shape
|
|
186
|
+
// (`node/src/functions.ts`), which POSTs `{inputs: payload}`.
|
|
187
|
+
invokeFunction: (id, inputs) => withApiErrorBody(() => client.functions.run(id, { payload: inputs })),
|
|
188
|
+
listWorkflows: () => withApiErrorBody(() => client.workflows.list()),
|
|
189
|
+
getWorkflow: (id) => withApiErrorBody(async () => {
|
|
190
|
+
const { workflow } = await client.workflows.get(id);
|
|
191
|
+
const def = workflow;
|
|
192
|
+
return {
|
|
193
|
+
id: def.id,
|
|
194
|
+
name: def.name,
|
|
195
|
+
displayName: def.displayName,
|
|
196
|
+
description: def.description,
|
|
197
|
+
steps: def.steps ?? [],
|
|
198
|
+
};
|
|
199
|
+
}),
|
|
200
|
+
// Always `wait: true` — see this module's header for why `terminal` is
|
|
201
|
+
// forwarded from `client.workflows.run`'s own result rather than
|
|
202
|
+
// re-derived from `httpStatus` a second time.
|
|
203
|
+
runWorkflow: (id, opts) => withApiErrorBody(async () => {
|
|
204
|
+
const result = await client.workflows.run(id, { ...opts, wait: true });
|
|
205
|
+
return {
|
|
206
|
+
runId: result.runId,
|
|
207
|
+
status: result.status,
|
|
208
|
+
output: result.output,
|
|
209
|
+
error: result.error,
|
|
210
|
+
terminal: result.terminal,
|
|
211
|
+
};
|
|
212
|
+
}),
|
|
98
213
|
};
|
|
99
214
|
}
|
|
100
215
|
//# sourceMappingURL=adapter.js.map
|
package/dist/src/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"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"}
|